In this case requests won't be performed from a secure context [1] and
the browser won't send the Sec-Fetch-Site header. This means non-GET
requests will be rejected because CSRF protection will fail.
With this change, we allow these requests with missing Sec-Fetch-Site
headers if:
- They happen over HTTP
- The app is not configured to force SSL
The Origin check happens in any case.
[1] https://developer.mozilla.org/en-US/docs/Web/Security/Defenses/Secure_Contexts#potentially_trustworthy_origins
And close the gap with JSON requests, which shouldn't be allowed if
Sec-Fetch-Site is 'cross-site' or 'none', only if it's empty as this
wouldn't be coming from a browser.
This is a great, solid alternative to CSRF tokens for CSRF protection
when we aren't worried about older browsers or other kind of actors
doing modifying requests in our app, and could be a good test for future
upstreaming to Rails (although there we'd need to continue using CSRF
tokens or at least letting people opt out manually).
Let's start checking the header and reporting on it when CSRF fails or
when it doesn't match the other checks Rails does, and then promote this
to be the only way to defend from CSRF.