Web security is horribly broken, and lot has been said about CSRF, XSS, DNS-Pinning, etc, but not enough about what we can do to fix the mess.
I think we could adapt an idea like HttpOnly to tackle CSRF - I'd like to see a "SameRefererOnly" marker for cookies.
SameRefererOnly is an indication that a cookie should only be sent to a Site when the referring domain matches the destination domain.
A number of people have commented that you could use server based referer checking to fix CSRF, however that doesn't work for 2 reasons, firstly sometimes referers are not sent, and secondly using old versions of Flash, you can forge referer headers anyway.
However if we move the checking into the browser, then we should be able to instruct browsers to be more careful what they do without our cookies.
Set-Cookie: <name>=<value>[; <name>=<value>][; expires=<date>] \ [; domain=<domain_name>][; path=<some_path>][; secure]
Microsoft's HttpOnly spec adds this to the end:
I propose that we further add this:
Any cookie marked SameRefererOnly MUST only be sent to servers when the domain of the cookie matches the referring domain. The cookie MUST NOT be sent when there is no referring domain (this might help to prevent CSRF / Phishing mash-ups).
It's worth noting that this protection breaks in the presence of XSS flaws in a site, because XSSed commands come from the compromised domain, however that does not make this protection useless.
Plug-ins like Java and Flash that have their own HTTP pipelines generally don't send cookies so these systems probably do not need to be patched.
This proposal has 3 places where it can come in handy:
- As an additional defence-in-depth layer of protection for a site that already has other CSRF protection.
- On an Intranet site where access through browsers that implement SameRefererOnly can be mandated
- In a future world where enough browsers implement this, that other browsers can be excluded.
Note on spelling: The pedant might note that this should be spelt SameReferrerOnly - i.e. with a double 'r', and the pedant would normally be correct however this misspelling is so common that the HTTP spec makes it, and hence we all follow unquestioningly.
I'm sure there must be some holes in this suggestion, but I make it anyway so someone can move the discussion on.