I'm planning to use synchronizer tokens for CSRF prevention, but OWASP recommends checking the referrer and origin headers too. I've been trying to figure out the correct logic for this, but my experiments suggest that there is no valid way to check due to the way Firefox behaves.
Firefox doesn't send the origin header for same origin requests, which I would have thought means you have to allow requests through that lack an origin header. I've just experimented with data URIs though and it looks like Firefox doesn't send the origin header from them either, which would mean an attacker can just direct the user to a Data URI that auto submits a malicious form.
This
data:text/html;base64,PGZvcm0gYWN0aW9uPSJodHRwOi8vd3d3LmV4YW1wbGUuY29tIiBtZXRob2Q9IkdFVCI+CjxpbnB1dCB0eXBlPSJzdWJtaXQiPgo8L2Zvcm0+
is a link to a data URI containing a form that submits to example.com.
Which is the following code base64 encoded:
<form action="http://www.example.com" method="GET">
<input type="submit">
</form>
When I open it in Firefox with the web console open it shows no origin or referrer header being sent.
What am I missing here? Is there some logic I should use on the server that will allow through requests from FIrefox but not malicious requests from data URIs?