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