
Can “Cookie to header token” CSRF prevention be beaten with permissive CORS? - dagobah
The CSRF Wikipedia article https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;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:<p><i>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)</i><p>The article https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Same-origin_policy#Security_Applications also says:<p><i>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&#x27;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.</i><p>Is this still true if doing client side rendering and all server requests are ajax get&#x2F;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&#x27;s session cookie, and parsing the response HTML, but as far as I know a malicious site&#x27; JS can&#x27;t read another site&#x27;s cookies even with Access-Control-Allow-Origin set to the malicious site and Access-Control-Allow-Credentials set to true.<p>I know setting allow-origin to the request origin is stupid, but am just wondering if I&#x27;m missing something that makes it easy to exploit the above CSRF prevention.
======
devinl
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...](https://en.wikipedia.org/wiki/Same-
origin_policy#Security_Applications) 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.

~~~
dagobah
I think [https://en.wikipedia.org/wiki/Cross-
site_request_forgery#Coo...](https://en.wikipedia.org/wiki/Cross-
site_request_forgery#Cookie-to-header_token) 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.

------
weitzj
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

~~~
dagobah
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...](http://blog.portswigger.net/2016/10/exploiting-cors-
misconfigurations-for.html) 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.

