A have a Django app using the built-in settings called ALLOWED_HOSTS that whitelists request Host headers. This is needed as Django uses the Host header provided by the client to construct URLs in certain cases.
ALLOWED_HOSTS=djangoapp.com,subdomain.djangoapp.com
I made ten requests with a fake host header (let's call it fakehost.com
) to the Django endpoint: /example
.
curl -i -s -k -X $'GET' \
-H $'Host: fakehost.com' -H $'Accept-Encoding: gzip, deflate' -H $'Accept: */*' -H $'Accept-Language: en' -H $'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36' -H $'Connection: close' \
$'https://subdomain.djangoapp.com/example'
In the application logs I see the django.security.DisallowedHost
error was raised ten times. However, according to the logs of fakehost.com
, it did receive one request for /example
.
As I understand, this is a server-side request forgery (SSRF) vulnerability as the Django server can be made to make requests to an arbitrary URL.
It makes debugging hard and is strange that the issue doesn't occur consistently. Also strange that the fake host seems to be recognised by Django, but one request still somehow reached fakehost.com
.
Does anyone have any ideas what I could investigate further in order to fix the apparent vulnerability in this Django app? Is the problem potentially on the server level not the application level?