Incorrect 401 www-authenticate challenge (realm, format)
The REST API's 401 challenge is incorrectly formatted and does not contain a unique REALM.
The code intends to do the right thing, but doesn't quite. There are three bugs in one line of code.
- The intended realm is not sent
- The realm is not quoted in the challenge
- The charset is not specified, although the server expects UTF-8
(A unique REALM allows clients to respond with the correct credentials for a protected resource. For Basic authentication, as used here, it need only be unique within a given host; for Digest, the host name & user group are recommended in RFC 7516. The latter scheme benefits the end users of Basic authentication clients, but is not essential.))
src/mailmlan/rest/wsgiapp.py
contains:
39 REALM = 'mailman3-rest'
92 credentials = b64decode(request.auth[6:]).decode('utf-8')
97 if not authorized:
98 # Not authorized.
99 raise HTTPUnauthorized(
100 '401 Unauthorized',
101 'REST API authorization failed',
102 challenges=['Basic realm=Mailman3'])
Clearly the intent, and desired behavior, of line 102 is to send 'Basic realm=' + REALM ('Basic realm=Mailman3-rest
'). This fixes bug 1.
Bug 2: Section 2.2 of RFC 7617 (https://tools.ietf.org/html/rfc7617#section-2.1) requires quotes around the value:
For historical reasons, a sender MUST only generate the quoted-string
syntax. Recipients might have to support both token and
quoted-string syntax for maximum interoperability with existing
clients that have been accepting both notations for a long time.
Bug 3: The code on line 92 suggests that the charset parameter should be included in the challenge. (Section 2.1 - there's an example at the end of page 5.)
So the correct code would be: challenges=['Basic realm="' + REALM + '", charset="UTF-8"])
This is a case where the error does correctly identify the content as application/json.
Packet trace:
GET /3.1/lists HTTP/1.1
TE: deflate,gzip;q=0.3
Keep-Alive: 300
Connection: Keep-Alive, TE
Accept: application/json
Host: random.example.net:8001
User-Agent: vth-mailman/1.000
Content-Type: application/json
HTTP/1.0 401 Unauthorized
Date: Tue, 27 Jun 2017 11:02:46 GMT
Server: WSGIServer/0.2 CPython/3.5.3
www-authenticate: Basic realm=Mailman3
content-length: 77
content-type: application/json; charset=UTF-8
vary: Accept
{"title": "401 Unauthorized", "description": "REST API authorization failed"}