Opened 4 years ago
Closed 4 years ago
#32578 closed Bug (fixed)
Handle request.get_host() raising DisallowedHost in CsrfViewMiddleware._origin_verified()
Reported by: | Chris Jerdonek | Owned by: | Chris Jerdonek |
---|---|---|---|
Component: | CSRF | Version: | dev |
Severity: | Normal | Keywords: | CsrfViewMiddleware, DisallowedHost |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | yes | UI/UX: | no |
Description
Currently, on this line, CsrfViewMiddleware._origin_verified()
doesn't handle request.get_host()
raising DisallowedHost
:
https://github.com/django/django/blob/41e6b2a3c5e723256506b9ff49437d52a1f3bf43/django/middleware/csrf.py#L229-L231
Since Django was previously fixed to handle request.get_host()
raising DisallowedHost
elsewhere in CsrfViewMiddleware.process_view()
(see ticket #28693), it seems like it should be handled here, too.
Attachments (1)
Change History (11)
comment:1 by , 4 years ago
comment:2 by , 4 years ago
Another option would be for get_host()
to accept an argument that causes it to return e.g. None
on a disallowed host instead of raising DisallowedHost
. That would make people more aware of that possibility and give callers another option aside from a try-except for handling that case.
comment:3 by , 4 years ago
Easy pickings: | set |
---|---|
Triage Stage: | Unreviewed → Accepted |
Type: | Uncategorized → Bug |
Thanks for the report. I attached a test.
follow-up: 5 comment:4 by , 4 years ago
Thanks, Mariusz. However, do you know for sure that's testing the right code path? _origin_verified()
only gets called when if request.method not in ('GET', 'HEAD', 'OPTIONS', 'TRACE')
, but the test appears to be GET
. I could be wrong though since my observation is based on inspection rather than running the test.
comment:5 by , 4 years ago
Replying to Chris Jerdonek:
Thanks, Mariusz. However, do you know for sure that's testing the right code path?
_origin_verified()
only gets called whenif request.method not in ('GET', 'HEAD', 'OPTIONS', 'TRACE')
, but the test appears to beGET
. I could be wrong though since my observation is based on inspection rather than running the test.
Test crashes because method
is not set in this case. I updated attached test to use the POST
method.
Replying to Tim Graham:
It might be better to perform host validation elsewhere in Django as suggested in #27575 so that DisallowedHost doesn't need to be caught everywhere.
This can be tricky, so I'd fix this case independently and discuss the options in #27575.
follow-up: 7 comment:6 by , 4 years ago
Test crashes because method is not set in this case. I updated attached test to use the POST method.
It might be good to fix _get_GET_no_csrf_cookie_request()
so that the method is indeed set to GET
.
comment:7 by , 4 years ago
Replying to Chris Jerdonek:
It might be good to fix
_get_GET_no_csrf_cookie_request()
so that the method is indeed set toGET
.
Agreed, PR.
comment:8 by , 4 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
It might be better to perform host validation elsewhere in Django as suggested in #27575 so that
DisallowedHost
doesn't need to be caught everywhere.