adamchainz / django-cors-headers

Django app for handling the server headers required for Cross-Origin Resource Sharing (CORS)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

UnicodeDecodeError if Origin header is not ASCII-encoded

M1ha-Shvn opened this issue · comments

Hi.
I use django-cors-headers 2.4.0 with django 2.2.9 and gunicorn 19.9.0.
Configuration:

CORS_ORIGIN_REGEX_WHITELIST = '^.*$'
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_METHODS = (
    'GET',
    'POST',
    'PUT',
    'PATCH',
    'DELETE',
    'OPTIONS'
)

Yesterday I'v noticed errors from gunicorn in logs, looking like:

[2020-05-19 14:43:46 +0300] [29611] [ERROR] Error handling request /utils/rtsauth?version=1
Traceback (most recent call last):
  File "/home/ubuntu2/cqapi/venv/lib/python3.6/site-packages/gunicorn/workers/gthread.py", line 279, in handle
    keepalive = self.handle_request(req, conn)
  File "/home/ubuntu2/cqapi/venv/lib/python3.6/site-packages/gunicorn/workers/gthread.py", line 334, in handle_request
    resp.write(item)
  File "/home/ubuntu2/cqapi/venv/lib/python3.6/site-packages/gunicorn/http/wsgi.py", line 338, in write
    self.send_headers()
  File "/home/ubuntu2/cqapi/venv/lib/python3.6/site-packages/gunicorn/http/wsgi.py", line 331, in send_headers
    util.write(self.sock, util.to_bytestring(header_str, "ascii"))
  File "/home/ubuntu2/cqapi/venv/lib/python3.6/site-packages/gunicorn/util.py", line 507, in to_bytestring
    return value.encode(encoding)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 262-287: ordinal not in range(128)

I've digged into gunicorn code and logged failing response headers:

HTTP/1.1 200 OK
Server: gunicorn/19.9.0
Date: Tue, 19 May 2020 11:43:46 GMT
Connection: close
Content-Type: application/json
Allow: OPTIONS, GET
Content-Length: 37
Vary: Origin
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://п�авобе�ежн�й72.��

Decoding origin, gives us a Cirillic domain name: правобережный72.рф.
I've gone to this site, and checked that in latest Google Chorme everything works ok, sending IDNA-decoded domain. So my guess is that request comes from some old/rare browser, which doesn't support IDNA encoding for Origin headers.

This line of code tells, that this header is formed from request's Origin header. I've reproduced the issue using curl:

curl localhost:8002/api/ping -H 'Origin: правобережный72.рф'

Hi

The exception is happening inside gunicorn, and you're not on the latest version 20.0.4. Please upgrade and test, and then report an issue there if it persists.

You're also on an old django-cors-headers version - I only support the latest version.

Thanks,

Adam