![]()
Cross-Site Request Forgery (CSRF) is a security vulnerability where an attacker tricks a user into making unintended requests to a web application where they are authenticated. This can lead to unauthorized actions being performed on behalf of the user.
AngularJS has built-in support for CSRF protection, but proper server-side handling is also necessary. In this guide, we will cover:
- Understanding CSRF Attacks
- How CSRF Protection Works in AngularJS
- Configuring CSRF Protection in AngularJS (
XSRF-TOKEN) - Implementing CSRF Protection on the Server
- Customizing CSRF Token Handling in AngularJS
- Additional CSRF Prevention Measures
- Testing CSRF Protection
- Best Practices for CSRF Security
1. Understanding CSRF Attacks
A CSRF attack happens when:
- A victim logs into a web application (e.g.,
bank.com). - The session is authenticated using cookies.
- The victim visits a malicious website while still logged in.
- The malicious website sends a forged request (e.g., money transfer) using the victim’s session cookies.
- The request is executed because the server trusts the user’s session.
Example of a CSRF Attack
<img src="https://bank.com/api/transfer?amount=1000&to=attacker" />
If the user is logged into bank.com, the request will be executed without their consent.
2. How CSRF Protection Works in AngularJS
AngularJS mitigates CSRF attacks using anti-CSRF tokens. The mechanism works as follows:
- The server sets a CSRF token in a cookie (
XSRF-TOKEN). - The AngularJS app reads the token from the cookie and adds it to each HTTP request as the
X-XSRF-TOKENheader. - The server verifies the token before processing the request.
3. Configuring CSRF Protection in AngularJS
AngularJS automatically sends the CSRF token with every $http request.
Step 1: Enabling CSRF Support in AngularJS
Ensure your application uses $http for API requests:
var app = angular.module('myApp', []);
app.config(function($httpProvider) {
// Enable CSRF protection
$httpProvider.defaults.xsrfCookieName = 'XSRF-TOKEN';
$httpProvider.defaults.xsrfHeaderName = 'X-XSRF-TOKEN';
});
Step 2: Sending API Requests with CSRF Token
Once configured, AngularJS automatically includes the CSRF token in each request:
app.controller('MainController', function($scope, $http) {
$http.post('/api/update-profile', { name: 'John Doe' })
.then(response => {
console.log('Profile updated:', response.data);
})
.catch(error => {
console.error('Error:', error);
});
});
This request will include the X-XSRF-TOKEN header.
4. Implementing CSRF Protection on the Server
The server must:
- Set a CSRF token cookie on login or page load.
- Validate the token in incoming requests.
CSRF Protection in Different Backend Frameworks
Node.js (Express.js)
Install the csurf package:
npm install csurf cookie-parser
Set up CSRF protection:
const express = require('express');
const csrf = require('csurf');
const cookieParser = require('cookie-parser');
const app = express();
app.use(cookieParser());
app.use(csrf({ cookie: true }));
// Send CSRF token to frontend
app.get('/csrf-token', (req, res) => {
res.json({ csrfToken: req.csrfToken() });
});
// Example protected API route
app.post('/api/update-profile', (req, res) => {
res.json({ message: 'Profile updated successfully' });
});
app.use((err, req, res, next) => {
if (err.code === 'EBADCSRFTOKEN') {
res.status(403).json({ error: 'Invalid CSRF token' });
} else {
next(err);
}
});
app.listen(3000, () => console.log('Server running on port 3000'));
Django
Enable CSRF protection in settings.py:
MIDDLEWARE = [
'django.middleware.csrf.CsrfViewMiddleware',
]
Modify views to return CSRF token:
from django.middleware.csrf import get_token
from django.http import JsonResponse
def csrf_token(request):
return JsonResponse({'csrfToken': get_token(request)})
Spring Boot (Java)
Enable CSRF protection in SecurityConfig.java:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
}
5. Customizing CSRF Token Handling in AngularJS
If the backend uses a custom CSRF mechanism, update AngularJS to match it.
Custom CSRF Token Cookie Name
$httpProvider.defaults.xsrfCookieName = 'CUSTOM-CSRF-TOKEN';
$httpProvider.defaults.xsrfHeaderName = 'X-CUSTOM-CSRF-TOKEN';
Manually Fetching the CSRF Token
app.run(function($http) {
$http.get('/csrf-token').then(response => {
document.cookie = `XSRF-TOKEN=${response.data.csrfToken}`;
});
});
6. Additional CSRF Prevention Measures
Besides CSRF tokens, implement:
SameSite Cookies – Prevent cookies from being sent in cross-origin requests.
app.use(cookieParser({ sameSite: 'Strict' }));
Referer & Origin Validation – Verify Referer and Origin headers.
User Authentication Checks – Ensure requests are properly authenticated.
Use POST Instead of GET – Prevent sensitive actions via GET requests.
7. Testing CSRF Protection
Test Cases
- Valid CSRF Token – API should process the request.
- Missing CSRF Token – API should reject the request.
- Invalid CSRF Token – API should return a
403 Forbiddenerror.
Testing Using Postman
- Send a
POSTrequest withoutX-XSRF-TOKEN. It should be blocked. - Send a
POSTrequest withX-XSRF-TOKEN. It should be allowed.
Testing with an Attack Script
<form action="https://example.com/api/update-profile" method="POST">
<input type="hidden" name="name" value="Attacker" />
<input type="submit" value="Submit Attack" />
</form>
If CSRF protection is working, the request should be blocked.
