When Sir Timothy (aka Tim Berners-Lee) designed the first version of his new information system in 1989 (that became the Web two years later), it was meant for connecting various research documents via references. Back then, and even later when the budding Web started to grow, there was no need for tracing the reader’s progress – when a page was revisited, it was opened from the beginning again. To this day, the main protocol of the Web, HTTP, is a bit like a senile senior to whom his/her children must re-introduce themselves all over every time they pay a visit.
The Web Today
But in today’s Web, we need to log into websites, carry out different interactions (e.g. online purchases, bank transfers) and also customize the sites on the fly (e.g. choosing the language that we know best). To address this, different means like Web cookies and sessions were developed later on. While these have a lot of legitimate uses, they can also bring along new threats.
A very telling example – in two different ways – is the one described at PrivacyLog (What happens when you send a zero day to a Bank). First off, it shows that the fact that significant amounts are involved does not necessarily mean that the website handling them is secure. Second, it is a prime example of the deadly combo of incompetence and boneheadedness from the site owners’ part – instead of thanking the informer and fixing the problem, they made several attempts to shoot the messenger while totally ignoring the actual security risk. Unfortunately, this is by far not a lone case of managerial ignorance in information security.
The Cross-Site Request Forgery (CSRF) is one of the common Web attacks that re-uses the user’s session information to perform various tasks defined by the attacker. While it was ranked 8th in the OWASP Top 10 in 2017, it is still very effective if the website is vulnerable to it. In short, it is a situation where the user (and his/her Web browser) is trusted by the website – e.g. the user has logged in with valid username and password – and the attacker has crafted another website for delivering the attack. Now when the user is visiting the initial website, the attack will be executed on the user’s browser and with his/her credentials. Most importantly, the user is not aware that anything has happened at all, as the browser is completing the requested instructions.
There are some conditions that need to be met in order to carry out a CSRF attack (due to these, the attack method is actually less common than some others):
- The targeted user must be logged in to the system
- The attacker must possess good knowledge about the target website (e.g. which fields must be filled in a form)
- The targeted user must be tricked to visit the malicious web page.
What makes the attack much more dangerous is the fact that it can be used on network devices like routers (see specific cases describing a very popular dd-wrt router software vulnerability and how TP-Link routers can be exploited) and increasingly other connected equipment forming the Internet of Things.
Prevention and protection ain’t that simple
Many modern frameworks like Django and Ruby on Rails have CSRF protection methods already implemented. The frameworks add additional safeguards like
X-CSRF-Token header automatically to the application code (Rails) whereas Django uses CSRF middleware that is enabled by default.
Possibly the best protection against CSRF attacks is provided by
same-site cookies. Regrettably this feature is only supported by Chrome and Opera at the moment, other browsers will just ignore it. Basically it just takes adding a new attribute to cookies, called
Set-Cookie: sess=xyz987; path=/; SameSite
The attributes are
"Strict" (the default, just
"Samesite" equals to
"Samesite=Strict") allowing ony requests from the same site, and “Lax” that allows some cross-site activity but still mitigates some risks.
Other means to counter CSRF attacks include
- validate referer header
- without the token in submitted form, the user has to re-validate identity
- FORM protection with CSRFToken (secret validation token)
- Custom HTTP headers