CORS vs. CSRF: Understanding the Two Most Confusing Web Security Concepts
Security of web application is one of the most important topic in software development. Two important concepts of web application security are CORS (Cross Origin Resource Sharing) and CSRF (Cross Site Request Forgery). While they both sound like scary security concepts involving web browsers, CORS and CSRF solve two completely different problems.
CORS (Cross-Origin Resource Sharing)
While the Same-Origin Policy normally blocks cross-site requests, CORS provides a way to selectively grant permission for those connections to happen. By default, a website at a.com cannot read data from b.com.
Suppose, if your React app is on localhost:3000 and your API is on localhost:8000, they are different "origins". When a web browser sends a cross-origin request, it includes Origin header in the request. Then the server will decide whether to allow or deny the request based on the CORS policy . The browser will block the React app from reading the API response unless the server sends a CORS header saying, "I trust localhost:3000."
Main goal of CORS is to allow a trusted front-end to access a back-end on a different domain.
CSRF (Cross-Site Request Forgery)
CSRF is an attack that tricks a victim into performing actions on a website where they are already logged in.
Imagine you are logged into your bank. You visit a malicious site in another tab. That site has a hidden form that submits a "Transfer Money" request to your bank's URL. Because your browser automatically attaches your session cookies, the bank thinks you made the request.
CSRF Protection Mechanism
1. SameSite Cookie Attribute
To protect from CSRF attack, on of the most effective way is by using SameSite attribute on session cookies, which tells the browser whether to send cookies with cross-site requests. SameSite attributes can have these values:
- Strict: Cookies are only sent for requests originating from the same site where the cookie was created.
- Lax(Default in modern browsers): Cookies are not sent on cross-site sub-requests (like images or frames) but sent when a user navigates to the origin site (like clicking a link).
- None: Cookies are sent in all contexts.
So, it's considered best to set our session cookies to SameSite=Lax or Strict to be protected most CSRF attempts instantly.
2. JWT (JSON Web Token) stored in Local/Session storage
If we store the JWT in the browser's localStorage or sessionStorage and send it via a custom HTTP header (like Authorization: Bearer <token>), we are naturally protected from CSRF.
While storing a token in localStorage makes your app immune to CSRF, it makes the token highly vulnerable to XSS (Cross-Site Scripting), another type of security threat. Use localStorage if you have implemented very strong XSS defense system.
To summarize, we can think of CORS as a "permission slip" for sharing resources, and CSRF protection as a "signature forgery" protection.
Leave a comment
Comments