<div dir="ltr"><div>This thread is mostly about X-Forwarded-Host & X-Forwarded-Proto because the original issue was inability of Twisted Web server to obtain it's public hostname. X-Forwarded-For is another (and probably more complex) story.</div><div><br></div><div>Django indeed dropped support for X-Forwarded-For, but it does support X-Forwarded-Host [1] and X-Forwarded-Proto [2] on opt-in basis.</div><div><br></div><div>I'm agree that none of the headers should be trusted by default and that opting-in should be done at Site level.</div><div><br></div><div>-- ilya</div><div><br></div><div>[1]: <a href="https://docs.djangoproject.com/en/1.10/ref/settings/#std:setting-USE_X_FORWARDED_HOST">https://docs.djangoproject.com/en/1.10/ref/settings/#std:setting-USE_X_FORWARDED_HOST</a></div><div>[2]: <a href="https://docs.djangoproject.com/en/1.10/ref/settings/#std:setting-SECURE_PROXY_SSL_HEADER">https://docs.djangoproject.com/en/1.10/ref/settings/#std:setting-SECURE_PROXY_SSL_HEADER</a></div><div><br><div class="gmail_quote"><div dir="ltr">пн, 20 мар. 2017 г. в 21:32, Tom Most <<a href="mailto:tommost@gmail.com">tommost@gmail.com</a>>:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="gmail_msg"><div class="gmail_extra gmail_msg"><div class="gmail_quote gmail_msg">On Fri, Mar 17, 2017 at 2:52 AM, Ilya Skriblovsky <span dir="ltr" class="gmail_msg"><<a href="mailto:ilyaskriblovsky@gmail.com" class="gmail_msg" target="_blank">ilyaskriblovsky@gmail.com</a>></span> wrote:<br class="gmail_msg"><blockquote class="gmail_quote gmail_msg" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr" class="gmail_msg"><span class="m_-6904254408352713843gmail-m_388361609629121005gmail- gmail_msg"><div dir="ltr" class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg">> <span style="color:rgb(33,33,33)" class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg">The code calling request.URLPath(), in a given Resource, or application, is highly unlikely to know whether it wants to honor (x-)forwarded-for.</span></div></span><div dir="ltr" class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg"><div class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg"><span style="color:rgb(33,33,33)" class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg">You are right, I haven't thought about it.</span></div><div class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg"><span style="color:rgb(33,33,33)" class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg">But I'm in doubt whether trusting X-Forwarded-* by default can damage security if Twisted app is running with naked HTTP(S) port exposed without reverse proxy that handles these headers.</span></div><div class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg"><span style="color:rgb(33,33,33)" class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg">There are three headers:</span></div><div class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg"><span style="color:rgb(33,33,33)" class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg">1. X-Forwarded-For specifying original client IP and IPs of proxies</span></div><div class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg"><span style="color:rgb(33,33,33)" class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg">2. X-Forwarded-Host specifying original Host header from the client</span></div><div class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg"><span style="color:rgb(33,33,33)" class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg">3. X-Forwarded-Proto specifying original client's scheme</span></div><div class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg"><span style="color:rgb(33,33,33)" class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg">(there is also new-style "Forwarded:" header but it is not widely used yet, AFAIK)</span></div><div class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg"><span style="color:rgb(33,33,33)" class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg"><br class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg"></span></div><div class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg"><span style="color:rgb(33,33,33)" class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg">X-Forwarded-For definetly can't be trusted if comes from untrusted client client. Fortunately we don't need it at all for generating URLs :) It will be in question when refactoring getClientIP() somewhen later.</span><br class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg"></div><div class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg"><span style="color:rgb(33,33,33)" class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg"><br class="gmail_msg"></span></div><div class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg"><span style="color:rgb(33,33,33)" class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg">But can we trust </span><span style="color:rgb(33,33,33)" class="m_-6904254408352713843gmail-m_388361609629121005gmail-m_-525099954024514115gmail_msg gmail_msg">X-Forwarded-Host & X-Forwarded-Proto? From the first glance it isn't a problem since we are using them to display URLs for the same client, so nasty client will get his nasty URLs, that's it. But if app is doing something like storing URL in DB or (more likely) sending an email with a link to another client, this would be an issue.</span></div></div></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div></div></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_extra gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg">It's not safe to enable support for X-Forwarded-For and friends by default, since you can't know how application code will use that information and in many configurations it may be spoofed by clients.<br class="gmail_msg"><br class="gmail_msg">A proper deployment which sets these headers looks like this:<br class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">1. Configure your frontend reverse-proxy (nginx or whatever) to discard incoming X-Forwarded-* headers and <i class="gmail_msg">set</i> X-Forwarded-* as appropriate. Note that X-Forwarded-For is actually a <i class="gmail_msg">list</i> of hops[1], so if you do this naively your server may append to the list! [2]<br class="gmail_msg"></div><div class="gmail_msg">2. Configure your backend services to respect exactly the headers passed by your frontend.<br class="gmail_msg"></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Note that this requires administrative action in two places, and that if you don't do the frontend config it will probably pass the headers through, allowing them to be spoofed.<br class="gmail_msg"></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">A non-exhaustive list of possible bad stuff I client could use spoofing for:<br class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">1. Evade IP-based access control (a reasonable defense-in-depth measure).<br class="gmail_msg"></div><div class="gmail_msg">2. Evade pinning of user sessions to IP addresses or subnets.<br class="gmail_msg"></div><div class="gmail_msg">2. Evade IP-based rate limiting, e.g. as discussed at [3].<br class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">It's also probably worth noting that Django used to offer support for X-Forwarded-For and removed it[4].  X-Forwarded-* and friends just too varied in the wild to reasonably support.<br class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">If Twisted is to support this in any way, I think that it should be opt-in support for the Forwarded header as specified in RFC 7239. This should be a parameter applicable to all of twisted.web.server rather than per-method call, since it's something the administrator needs to set.<br class="gmail_msg"></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">—Tom<br class="gmail_msg"></div><div class="gmail_msg"><br class="gmail_msg">[1]: Standardized as Forwarded in <a href="https://tools.ietf.org/html/rfc7239" class="gmail_msg" target="_blank">https://tools.ietf.org/html/rfc7239</a><br class="gmail_msg"></div><div class="gmail_msg">[2]: Your frontend proxy should also validate Host is a domain you control to prevent cookie theft. Plus lots of other stuff. Web security is hard, and every default everywhere sets users up for failure.<br class="gmail_msg">[3]: <a href="http://django-ratelimit.readthedocs.io/en/v1.0.0/security.html" class="gmail_msg" target="_blank">http://django-ratelimit.readthedocs.io/en/v1.0.0/security.html</a><br class="gmail_msg">[4]: <a href="https://www.djangoproject.com/weblog/2009/jul/28/security/#secondary-issue" class="gmail_msg" target="_blank">https://www.djangoproject.com/weblog/2009/jul/28/security/#secondary-issue</a></div></div></div></div>
_______________________________________________<br class="gmail_msg">
Twisted-web mailing list<br class="gmail_msg">
<a href="mailto:Twisted-web@twistedmatrix.com" class="gmail_msg" target="_blank">Twisted-web@twistedmatrix.com</a><br class="gmail_msg">
<a href="http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web" rel="noreferrer" class="gmail_msg" target="_blank">http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web</a><br class="gmail_msg">
</blockquote></div></div></div>