View RSS Feed

Fb1h2s aka Rahul Sasi's Blog

Trusting 302 Redirects and Content Security Policies security.

Rating: 18 votes, 4.94 average.
My new year resolution is to blog as much as possible. My writing skills sucks and there's just too great a chance, i'll lower the standards. Any way the show must go on. So am planning to share my weekend notes here from now on.

Name:  CSP_Shield_Logo.jpg
Views: 5973
Size:  19.4 KB

Few weeks back I had to design a solution for a challenging web application issue.

The scenario was as follows.


A secure Web Application has a Secret Access token . This token needs to be shared with a Desktop client application. And based on receiving the secure-token the desktop application performs few critical tasks. The secret-token is in the form of an application cookie. So for passing the cookie to the desktop app, application uses a javascript code that reads the cookie and sent a GET request using it to the localhost Desktop App.

1) Java Script -- > Reads Cookies [ document cookie ]
2) Cookies Sent to Desktop client via an xmlhttp GET request to Desktop client [ http://127.0.0.1/?Secure_cookie=2121212 .


Now the issues is I need to protect the Secret-token no matter what. So even if there is an XSS in the app the secret cookie should not be lost. Well for preventing cookie read via JS we can mark the cookie HTTP-ONLY but then it would halt the entire implementation . As the legitimate JS would not be able to read the cookies and sent to Desktop App.

One solution here was to use a 302 redirects and mark the cookie http-only. So our application uses POST method requesting the Secret-token .And on receiving the post request the application does a 302 redirect to the localhost and a url variable will have the secret-cookie.

1) An http POST method is used to request the secret-token from a Secret token[cookie] page page in a new tab.
2) The secret token page 302 redirects to [http://127.0.0.1/?secure_cookie=2121212 ]


The security of this implementation is based on the fact that an XHR request cannot access response headers. So even if we have an XSS in the app, a malicious xml-http-request would not be able fake a post request to read the response headers.

As per xmlhttprequest RFC .


http://www.w3.org/TR/XMLHttpRequest/


"If the redirect violates infinite loop precautions this is a network error.

Otherwise, run these steps:

Set the request URL to the URL conveyed by the Location header.

If the source origin and the origin of request URL are same origin transparently follow the redirect while observing the same-origin request event rules.

"
The following is how XHR handle 302 redirects. So there is no way a JS would be able to get the redirect location thereby revealing our secret token. One more thing is that, in our scenario our final redirect url is a different domain[127.0.0.1]. So that means our source and origin is different there by causing a CSP error if requested using XHR .

Error:
"
XMLHttpRequest cannot load http://exploit-analysis.com/302/ajax.php. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://172.16.139.145' is therefore not allowed access.
"

This cross origin error error will contain the 302 location url, but is not accessible for javascripts.


So my secure implementation was based on these browser security features.

You can check out the implementation over here:
http://exploit-analysis.com/302/index.php?xss=sas .

But soon this proposal was challenged by https://twitter.com/skeptic_fx .

His cool bypass method was using the CSP violation reports.

https://developer.mozilla.org/en-US/...lation_reports

He simply collected the CSP log reports on the server. And this logs will contain the violated domains.

PHP Code:
hea der("Content Security-Policy: frame-src 'self' domain.com fb1h2s.domain.com ; report-uri report.php;"); 
HTML Code:
POST report.php HTTP/1.1
Host: domain.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Length: 344
Content-Type: application/json
Connection: keep-alive

{"csp-report":{"document-uri":"http://domain.com/csp.php","referrer":"","blocked-uri":"http://rc2wedwsze.sas.domain.com/","violated-directive":"frame-src http://domain.com:80 http://test.domain.com:80 http://domain.com:80","original-uri":"http://domain.com/post.php"}}
But for my current implementation the above trick is not as harmful as it could only leak the domain name , rather than the full URl.


Remember in our implementation we do a 302 redirect with .

http://127.0.0.1/secret_key.php?key=56787653567898876

Here even if you leak the domain[127.0.0.1[ name its of no use, as the objective is to leak the entire url to reveal the secret key.

But with CSP reports one can only leak the domain name not the entire url. I tested it on multiple browser and it does not work because CSP strictly follows same origin in newer browsers.

Actual Specification for CSP: http://www.w3.org/TR/CSP/#violation-reports

Here blocked-uri is the one that leaks the url.
blocked-uri : "URI of the resource that was prevented from loading due to the policy violation, with any <fragment> component removed"

"If the origin of the blocked-uri is not the same as the origin of the protected resource, then replace the blocked-uri with the ASCII serialization of the blocked-uri's origin."
Browsers Tested:

1) In chrome it does not sent the entire URI.
2) In firefox it does not sent entire URI.
https://developer.mozilla.org/en-US/...lation_reports
3) Webkit Also seems to implement this correctly.

Here is the list of other CSP supported browser versions. http://caniuse.com/contentsecuritypolicy


So CSP follows the same origin policy and blocks the entire url from being revealed. I have seen a lot of people complaining about CSP not able to capture the entire cross origin request . So thought this article would be useful for highlighting security issues concerning CSP features.

While I was writing this blog homakov published an article explaining few privacy violations issues regarding CSP.

Take a look. http://homakov.blogspot.in/2014/01/u...-for-evil.html.

I am looking for more suggestions on how much I can trust 302 redirects for such a secure implementation . Or any potential bypass that could circumvent this secure implementation.


Update:

Nafeez put up a G4H CTF challenge for the issue .

The challange was to leak the entire 302 redirect URL or just the domain name of a 302 redirect.

test.skepticfx.com/challenge/2014/1/?xss=123<script>alert(%27xss%27)</script>

And we dint get any solution that could leak the entire url except the domain name. Which at some cases could be dangerous.

Here is the solution for the bypass. Nishant Das Patnaik broke the challenge.

http://test.skepticfx.com/challenge/...E%3C/iframe%3E

The solution uses a parent and child Iframe . Set the parent iframe to report CSP errors to server. Make child frame to do a 302 redirect. Since the redirected domain is different, this will cause an CSP error . This error report will have the redirected domain.


Name:  Screen Shot 2014-01-20 at 11.43.24 am.jpg
Views: 1564
Size:  23.3 KB

Regards.
Rahul Sasi
Tags: None Add / Edit Tags
Categories
Uncategorized

Comments

Trackbacks

Total Trackbacks 0
Trackback URL: