Hacker News new | comments | show | ask | jobs | submit login
Can “Cookie to header token” CSRF prevention be beaten with permissive CORS?
4 points by dagobah 10 months ago | hide | past | web | favorite | 4 comments
The CSRF Wikipedia article https://en.wikipedia.org/wiki/Cross-site_request_forgery#Cookie-to-header_token describes Cookie-to-header_token as sending a CSRF token to users in a cookie, and then using JavaScript to read the cookie and set it as a custom header (I think a post param would work too) when making ajax calls. It also adds:

The protection provided by this technique can be thwarted if the target website disables its same-origin policy using one of the following techniques: Permissive Access-Control-Allow-Origin Cross-origin resource sharing header (with asterisk argument)

The article https://en.wikipedia.org/wiki/Same-origin_policy#Security_Applications also says:

The user visiting the malicious site would expect that the site he or she is visiting has no access to the banking session cookie. While it is true that the JavaScript has no direct access to the banking session cookie, it could still send and receive requests to the banking site with the banking site's session cookie. Because the script can essentially do the same as the user would do, even CSRF protections by the banking site would not be effective.

Is this still true if doing client side rendering and all server requests are ajax get/post calls with a required token in cookies plus custom header? I think the token can be stolen, if the server is rendering the CSRF token into forms, by sending a GET with the user's session cookie, and parsing the response HTML, but as far as I know a malicious site' JS can't read another site's cookies even with Access-Control-Allow-Origin set to the malicious site and Access-Control-Allow-Credentials set to true.

I know setting allow-origin to the request origin is stupid, but am just wondering if I'm missing something that makes it easy to exploit the above CSRF prevention.

So from reading this over it sounds like you are enabling an endpoint on your site with both CSRF protection enabled that also sends CORS headers to allow for cross origin ajax calls. This could be a workable solution for cross domain calls on the same subdomain (like a.example.com and b.example.com but not malware.com). Since you can scope cookies to domain suffixes, you can have a csrf cookie that can be read from javascript from a number of subdomains and included in a header but can't be read from other domains. Same origin policy prevents domains from reading cookies not scoped to their domain so this should not have any security issues. Note that if you care about confidentiality, you would have to put your CSRF protection on the GET requests (which is a bit abnormal) with CORS since Access-Control-Allow-Origin allows for reading data cross origin (in addition to making requests).

On the other hand, it seems like https://en.wikipedia.org/wiki/Same-origin_policy#Security_Ap... is flawed and should be fixed. The section seems to be directly describing a CSRF attack and then saying CSRF protections are not effective which doesn't make sense.

I think https://en.wikipedia.org/wiki/Cross-site_request_forgery#Coo... is flawed too because "Access-Control-Allow-Origin: *" doesn't let browsers send cookies with the request, so any of the CSRF prevention methods shouldn't be broken by it. I was just using "Access-Control-Allow-Origin: malware.com" as an example of a worst case scenario where I still don't think the cookie-to-header method is exploitable, unless I'm missing something. The articles don't give examples or link to sources, so I'm guessing both are slightly wrong. I could try to edit them, but wanted to make sure I wasn't wrong first.

As far as I understood, to prevent CSRF, you do a double submit:

- server sends an HTTP only cookie, which cannot be read from JavaScript - server sends a new CSRF token via Header/Form for each request

On POST send back the CSRF token via FORM/Header and let browser send along the HTTP only cookie

The owasp cheat sheets are a good read

Yea, but doing it that way requires same origin policy not to be weakened like from CORS being misconfigured. http://blog.portswigger.net/2016/10/exploiting-cors-misconfi... talks about exploits from this.

But what I am wondering is if using "Access-Control-Allow-Origin: evil-site.example.com or *" can be used to exploit the cookie-to-header technique with a token for every request (GETS included), no form GETS (so token doesn't appear in url query), https, and no browser bugs or XSS vulnerabilities. The wiki articles suggest it could be exploited, but I'm thinking they're just worded conservatively.

Applications are open for YC Winter 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact