What is the vulnerability ALLOWED_HOSTS is defendi

2019-02-18 11:15发布

问题:

The example is from the Python Django framework but is applicable to all web applications. How does the ALLOWED_HOSTS setting protect your site and users, i.e. if ALLOWED_HOSTS was set to "*" how would a malicious user go about "poisoning caches and password reset emails with links to malicious hosts"?

ALLOWED_HOSTS Default: [] (Empty list)

A list of strings representing the host/domain names that this Django site can serve. This is a security measure to prevent an attacker from poisoning caches and password reset emails with links to malicious hosts by submitting requests with a fake HTTP Host header, which is possible even under many seemingly-safe web server configurations.

Values in this list can be fully qualified names (e.g. 'www.example.com'), in which case they will be matched against the request’s Host header exactly (case-insensitive, not including port). A value beginning with a period can be used as a subdomain wildcard: '.example.com' will match example.com, www.example.com, and any other subdomain of example.com. A value of '*' will match anything; in this case you are responsible to provide your own validation of the Host header (perhaps in a middleware; if so this middleware must be listed first in MIDDLEWARE_CLASSES).

回答1:

how would a malicious user go about "poisoning caches and password reset emails with links to malicious hosts"?

A caching system should cache responses from requests sent with a particular host header in order to identify the URL. For example, if there was a GET request to /foo the cache will only know that it was in fact a request to www.example.com/foo if it checks the host header (rather than simply destination IP). By leaving the ALLOWED_HOSTS setting to "*" you are allowing this cache to be filled up with rubbish (i.e. poisoned) if the output page contains the reflected host name and the host header is not checked by the caching layer or server.

e.g. if a page on your site outputs

<script src="//[hostname]/script.js"></script>

And if an attacker points attacker-site.co.uk to your server and requests the page, your server will respond with:

<script src="//attacker-site.co.uk/script.js"></script>

Therefore, any caching layers (e.g. CDNs) between a user and your site (example.com) will have legitimate requests for the page poisoned with the previously injected host header:

<script src="//attacker-site.co.uk/script.js"></script>

This lets the attacker run their malicious JavaScript on your domain, breaking the Same Origin Policy. For example, they may have installed a JavaScript keylogger to get passwords, or a script to send the contents of the DOM.

In addition, if the host name is not output encoded correctly then it could be directly used to inject script, even if no external JavaScript tags exist on the page.

" /><script>alert('xss')</script>

will render:

<img src="//[hostname]/img.jpg" />

as

<img src="//" /><script>alert('xss')</script>/img.jpg" />

The password reset email is a similar concept. Say the template for the password reset email is:

You requested a password reset. Please go to https://[HOST]/reset?token=[TOKEN] in order to reset it.

and the attacker points their domain www.evil.com at your server and requests a reset for a user. Their DNS setting can simply be for themselves, using a hosts file.

The user will then get an email saying

You requested a password reset. Please go to https://www.evil.com/reset?token=XYZ in order to reset it.

Once the link is clicked, as the public DNS for www.evil.com points at the attacker's site, the attacker gets the password reset token and can gain access to the account.

See this link for some more detail on these type of attacks.



标签: security