#27379: Django violates RFC7230 when handling requests.
-------------------------------------+-------------------------------------
Reporter: Stavros | Owner: nobody
Korokithakis |
Type: Bug | Status: new
Component: Uncategorized | Version: 1.10
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Florian Apolloner):
* cc: Florian Apolloner (added)
Comment:
I think this depends on how you configured Nginx. If Nginx works as a
proxy for your application, this applies (
https://tools.ietf.org/html/rfc7230#section-5.4 ):
{{{
When a proxy receives a request with an absolute-form of
request-target, the proxy MUST ignore the received Host header field
(if any) and instead replace it with the host information of the
request-target. A proxy that forwards such a request MUST generate a
new Host field-value based on the received request-target rather than
forward the received Host field-value.
}}}
If Nginx does not work as a proxy, it should reject requests which are not
compliant to the RFC ( https://tools.ietf.org/html/rfc7230#section-5.3 ):
{{{
When making a request directly to an origin server, other than a
CONNECT or server-wide OPTIONS request (as detailed below), a client
MUST send only the absolute path and query components of the target
URI as the request-target. If the target URI's path component is
empty, the client MUST send "/" as the path within the origin-form of
request-target. A Host header field is also sent, as defined in
Section 5.4.
}}}
In this case it is imo questionable if Nginx should pass an invalid
request on at all, or answer with 400 already as per (
https://tools.ietf.org/html/rfc7230#section-5.4 ):
{{{
A server MUST respond with a 400 (Bad Request) status code to any
HTTP/1.1 request message that lacks a Host header field and to any
request message that contains more than one Host header field or a
Host header field with an invalid field-value.
}}}
It is questionable on whether an invalid request makes the Host header in
this case invalid, but well.
Either way, I cannot see any reason for Django to consider such a request
not as an attack, and therefore the last paragraph of (
https://tools.ietf.org/html/rfc7230#section-5.5 ) applies:
{{{
Once the effective request URI has been constructed, an origin server
needs to decide whether or not to provide service for that URI via
the connection in which the request was received. For example, the
request might have been misdirected, deliberately or accidentally,
such that the information within a received request-target or Host
header field differs from the host or port upon which the connection
has been made. If the connection is from a trusted gateway, that
inconsistency might be expected; otherwise, it might indicate an
attempt to bypass security filters, trick the server into delivering
non-public content, or poison a cache. See Section 9 for security
considerations regarding message routing.
}}}
Django chooses not to honour this request cause the host-header is not
configured as it expects it too. This is a valid reason to reject the
request, cause after all a valid client MUST send a valid host-header and
technically is not allowed to send a full request URI. So unless there is
any evidence that this has legitimate use cases, I suggest we leave it as
is to keep the code simple. Another interesting sidenote: How is the
server supposed to know if `http://example.com` is a full URI or actually
a path named `http://example.com`?
--
Ticket URL: <https://code.djangoproject.com/ticket/27379#comment:2>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/071.dd5f2d521970c94503e35b4567b3fc59%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.