Cross-site request forgery (also known as CSRF) allows an attacker to induce users to perform actions that they do not intend to perform (e.g., changing passwords, making purchases).
It allows an attacker to partly circumvent the same origin policy, which is designed to prevent different websites from interfering with each other.
Vulnerable Code:
- The application relies only on cookies for authentication.
- An attacker can trick the user into sending a malicious request while they are logged in.
app.post('/change-password', (req: Request, res: Response) => {
const { newPassword } = req.body;
const userId = req.session.userId; // Assuming session-based authentication
if (!userId) {
return res.status(401).json({ message: 'Unauthorized' });
}
// Update password in the database
updatePassword(userId, newPassword);
res.json({ message: 'Password changed successfully' });
});
Fixing CSRF (TypeScript):
- CSRF token using csurf middleware.
import express, { Request, Response, NextFunction } from 'express';
import csrf from 'csurf';
import cookieParser from 'cookie-parser';
const app = express();
app.use(cookieParser());
app.use(express.json());
// Initialize CSRF protection
const csrfProtection = csrf({ cookie: true });
app.use(csrfProtection);
// Route to get CSRF token (Frontend should include it in requests)
app.get('/csrf-token', (req: Request, res: Response) => {
res.json({ csrfToken: req.csrfToken() });
});
// Secure Password Change Endpoint
app.post('/change-password', csrfProtection, (req: Request, res: Response) => {
const { newPassword } = req.body;
const userId = req.session?.userId; // Ensure session-based authentication
if (!userId) {
return res.status(401).json({ message: 'Unauthorized' });
}
updatePassword(userId, newPassword);
res.json({ message: 'Password changed successfully' });
});
2. Use satesite cookies.
app.use(require('express-session')({
secret: 'your-secret-key',
resave: false,
saveUninitialized: true,
cookie: {
secure: true, // Only send cookies over HTTPS
httpOnly: true, // Prevent access from JavaScript
sameSite: 'strict' // Block CSRF attacks
}
}));
3. Restrict cors configuration.
import cors from 'cors';
app.use(cors({
origin: 'https://trusted-site.com', // Allow only trusted frontend
methods: ['GET', 'POST'],
credentials: true // Allow cookies only for trusted requests
}));
Code Fix for Juiceshop CSRF vulnerability
- Implement CSRF Protection Middleware:
- Use the
csurf
middleware to enforce CSRF token validation for all state-changing requests (e.g., POST, PUT, DELETE).
2. Restrict CORS Policy:
- Configure cors() to allow only trusted origins.
3. Use SameSite Cookies:
- Set the
SameSite
attribute on cookies toStrict
orLax
to prevent them from being sent with cross-origin requests.


//csrf-fix
app.user(csurf({cookie: true}));
app.use(cors({origin: true, credentials: true
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
}));
app.use(cookieParser()
);
app.use((req: Request, res: Response, next: NextFunction) => {
res.cookie('XSRF-TOKEN', req.csrfToken())
next()
})
//csrf-fix
Once the changes are made and pushed to github, Snyk will automatically scan the code for changes.
Thanks for reading.
Happy Learning😊