Skip to content

WWW-Authenticate trailing white-space with empty parameters #3127

Closed

Description

@Julien00859

Hello there 👋

I tried to follow the guidelines at:

Legal: no GenAI tool were used, nowhere, and I'm making this PR on behave of my employer.

Thank you for Werkzeug!


When a WWWAuthenticate header with no realm or other parameter is converted to a response header, the header contains an invalid trailing white-space.

When loading that header in h11.Response it is rejected because of the trailing white-space.

  • Python version: 3.12.3-0ubuntu2.1
  • Werkzeug version: 3.0.1-3ubuntu0.2
  • h11 version: 0.14.0-1ubuntu0.24.04.1

Such parameter-less headers are standard: https://httpwg.org/specs/rfc9110.html#challenge.and.response

Simple reproduction steps:

wa = WWWAuthenticate('bearer')
assert wa.to_header() == "Bearer"  # must not be "Bearer "

The exact problem we are having, when loading the response in h11:

Our controller does:

raise Unauthorized('Missing "Authorization"', www_authenticate=WWWAuthenticate('bearer'))

It ultimately reaches our WSGI server:

def start_response(self, status, response_headers, exc_info):
    status_code, _, reason = status.partition(' ')
    status_code = HTTPStatus(int(status_code))
    response_headers = [
        (header.encode('ascii').lower(), value.encode('latin-1'))
        for header, value in response_headers
    ]
    ...
    h11_response = h11.Response(
        status_code=status_code,
        reason=reason,
        headers=response_headers,
    )

And h11 rejects the header:

  File "/home/julien/Odoo/community/odoo/http/server.py", line 307, in start_response
    h11_response = h11_response_cls(
                   ^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/h11/_events.py", line 151, in __init__
    self, "headers", normalize_and_validate(headers, _parsed=_parsed)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/h11/_headers.py", line 164, in normalize_and_validate
    validate(_field_value_re, value, "Illegal header value {!r}", value)
  File "/usr/lib/python3/dist-packages/h11/_util.py", line 91, in validate
    raise LocalProtocolError(msg)
h11._util.LocalProtocolError: Illegal header value b'Bearer '

We are doing the following patch in our wsgi server to mitigate the problem:

+        if get_header(b'www-authenticate'):
+            for index, (header, value) in enumerate(response_headers):
+                if header == b'www-authenticate':
+                    break
+            response_headers[index] = (header, value.rstrip())
+

I've fixed the issue inside werkzeug and I would like to make a PR, what branch can I target?

Regards,
Julien (juc)

Activity

  1. davidism commented on Mar 20, 2026

    @davidism
    Member

    Sounds good, this can be a PR to stable since it's a bug fix.

  2. added 4 commits that reference this issue on Mar 20, 2026
    190c407
    dbde504
    1dfc1ab
    0309c93
  3. added a commit that references this issue on Mar 23, 2026
    051fd66
  4. locked as resolved and limited conversation to collaborators on Apr 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions