CSRF | CORS
CORS Is Not a CSRF Prevention Mechanism. … Any request generated by an HTML form will necessarily be a simple request and will never be preflighted. Form submissions can be sent from any origin to any other origin. … While a properly configured CORS policy is important, it does not in itself constitute a CSRF defense.
Scenario
- The target, Joe, is logged into their account at
https://bank.com
. - The target then visits the web site of the perp, Tom, at
https://foo.com
. - Tom places the malicious URL at his own site exploiting the fact that Tom is logged in at the
bank.com
site.
The perp knows the proper bank.com
URL for requesting a transfer of money from Joe's account into Tom's account …
<a href="https://bank.com/transfer.do?acct=TOM&amount=100000">View my Pictures!</a>
Or as a 0x0 fake image:
<img src="https://bank.com/transfer.do?acct=TOM&amount=100000" width="0" height="0" border="0">
The server does not know this is a cross-origin request because it fails to match request header Referer
against that of Host
, and so allows the exploit.
Mitigate
Validate request headers; either "
Referer
" or "Origin
", matching the value against that of "Host
" request header.Strong test, i.e., test against host string of
//foo.com/
, not merely/foo.com
or worse stillfoo.com
, which may be of originfoo.com.bad.com
.if !strings.Contains(r.Referer(), "//"+r.Host) && r.Referer() != "" { err = errors.New("no hotlinks") }
Enforce Same-site policy
- No CORS, or tightly controlled, server-side
- Cookie set per "
SameSite: strict
"
Prevent XSS using CSP HTTP header along with Subresource Integrity (nonces)
-
- By default, browsers do not allow scripts (JS) to make cross-origin requests with custom headers.
Stateless CSRF mitigation a.k.a. Double Submit Cookie method.
- Server sends nonce with HTML form per hidden form key attribute and/or HTTP header, which client returns with the subsequent POST request per both request parameter (e.g., form key value) and HTTP header (
X-CSRF-Token: 1qlkhh12u15...
); validate per match and same-site tests.
- Server sends nonce with HTML form per hidden form key attribute and/or HTTP header, which client returns with the subsequent POST request per both request parameter (e.g., form key value) and HTTP header (