Closed
Bug 649354
Opened 14 years ago
Closed 14 years ago
Django's anti-CSRF Referer validation can be bypassed using the X-FORWARDED-HOST header
Categories
(addons.mozilla.org Graveyard :: Developer Pages, defect)
addons.mozilla.org Graveyard
Developer Pages
Tracking
(Not tracked)
VERIFIED
FIXED
People
(Reporter: albinowax, Unassigned)
Details
(Keywords: reporter-external, wsec-csrf, Whiteboard: [infrasec:csrf][ws:critical])
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) Gecko/20110103 Fedora/3.6.13-1.fc14 Firefox/3.6.13
Build Identifier:
When Django receives a POST request it validates the Referer header against the Host. However, if the X-Forwarded-Host header is present, it validates the referer against that instead. That header can be spoofed to match the referer, so Django accepts the request.
When combined with the csrf-token overriding attack outlined in https://bugzilla.mozilla.org/show_bug.cgi?id=648881 this probably exposes all AMO users with non-updated browsers to potentially account-hijacking CSRF.
( On slightly out of date browsers, using the technique outlined in http://lists.webappsec.org/pipermail/websecurity_lists.webappsec.org/2011-February/007533.html attackers can make victims spoof the X-Forwarded-Host header cross domain. )
Reproducible: Always
Steps to Reproduce:
1. Browse to https://addons.mozilla.org/en-US/firefox/users/edit, click 'update'
2. Intercept the request and change the 'Referer' value to 'https://cow.org/
3. Add a new header 'X-FORWARDED-HOST: cow.org'
4. Observe that the request succeeds ('302 found' rather than '403 forbidden')
The X-Forwarded-Host trick was suggested by 'barbarianbob'. I'll try and get his email so he can see the bug. If he agrees, any bounty can be split 50/50.
Comment 1•14 years ago
|
||
Django starts the Referer checking when the request is https[1].
It compares HTTP_REFERER[2] to request.get_host()[3] which checks for (in this order) HTTP_X_FORWARDED_HOST, HTTP_HOST, or SERVER_NAME + SERVER_PORT. It returns the first one of those it finds.
I haven't tried to reproduce but it looks valid from browsing the code.
[1] https://github.com/django/django/blob/master/django/middleware/csrf.py#L118
[2] https://github.com/django/django/blob/master/django/middleware/csrf.py#L134
[3] https://github.com/django/django/blob/master/django/http/__init__.py#L153
Status: UNCONFIRMED → NEW
Ever confirmed: true
Comment 2•14 years ago
|
||
Why not just overwrite the Referer header from the start instead of adding the X-Forwarded-Host header?
Reporter | ||
Comment 3•14 years ago
|
||
The Referer header can't be spoofed using that technique, since it's blacklisted: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/URLRequestHeader.html
If it wasn't for that blacklist, the token injection into the cookie could be done that way, too.
Comment 4•14 years ago
|
||
(In reply to comment #3)
> The Referer header can't be spoofed using that technique, since it's
> blacklisted:
> http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/URLRequestHeader.html
>
> If it wasn't for that blacklist, the token injection into the cookie could be
> done that way, too.
Makes sense. Thanks.
This issue will be addressed in its entirety by django's CSRF upgrade to include tokens within
Comment 5•14 years ago
|
||
I've confirmed this issue is valid. To summarize:
Django's CSRF defense will verify the csrf token and the referrer (for HTTPS)
1. This issue requires the attacker to know (or have set) the CSRF token (e.g. bug 648881)
2. The x-forward-for issue discussed in this bug addresses the referrer checking.
Comment 6•14 years ago
|
||
The solution to this issue is to get rid of CSRF tokens in cookies (something I'm all for).
Updated•14 years ago
|
Whiteboard: [infrasec:csrf][ws:critical]
Comment 9•14 years ago
|
||
Jbalogh,
Is this issue now addressed with our CSRF enhancements?
Comment 10•14 years ago
|
||
(In reply to comment #9)
> Jbalogh,
>
> Is this issue now addressed with our CSRF enhancements?
Yes, we don't care about the Referer anymore since the token is never in a cookie.
Status: NEW → RESOLVED
Closed: 14 years ago
Resolution: --- → FIXED
Updated•13 years ago
|
Status: RESOLVED → VERIFIED
Reporter | ||
Comment 11•13 years ago
|
||
Could the security sensitive flag be removed?
Updated•11 years ago
|
Flags: sec-bounty+
Updated•10 years ago
|
Group: client-services-security
Assignee | ||
Updated•9 years ago
|
Product: addons.mozilla.org → addons.mozilla.org Graveyard
Updated•4 months ago
|
Keywords: reporter-external
You need to log in
before you can comment on or make changes to this bug.
Description
•