Mitigating CSRF attacks in Single Page Applications
Cross-Site Request Forgery (or CSRF or XSRF or “sea-surf”) is one of the oldest attacks against web apps. It means that by embedding a form or URL into a malicious site, the attacker can get a request executed on the vulnerable server as if the visitor of their site made it. There are many ways of protecting your applications, with differing levels of complexity. In Single Page Apps (or SPAs) the simplest ones may be the best.
What is CSRF?
CSRF is an attack against cookie-based authentication. A site is vulnerable if they check the user’s login state based on a cookie with no (or insufficient) additional checks to see where the request originated. It generally works like this:
- The user logs into the vulnerable site as part of their normal use.
- The site sets up the session cookies in the browser of the user.
- The user visits the malicious site, that has a hidden form embedded.
- The hidden form submits a POST request to the vulnerable site or an embedded
<img>makes a GET request to it.
- The browser executes the request sending the saved credentials along.
- The server sees that the request came from the user, and assumes it’s legitimate and executes it, posting pictures of cats on your social media. (or something way more malicious)
How is it different in SPAs?
A Single Page Application (SPA) is a website, that doesn’t do full page reloads and rewrites the page content instead, to provide a smoother user experience. These include sites built with Angular, React, and other popular frameworks.
The relevant part to CSRF is that you don’t do top-level navigation, don’t submit forms and you handle your server API through
fetch() (or some library built upon these). This is important because top-level navigation is handled differently by same-site cookies and you can rely on CORS if you choose to move your API to a subdomain…