CSRF in Next.js Apps: When Server Actions and Cookies Become a Security Risk
What is CSRF and How Does it Affect Next.js Apps
CSRF (Cross-Site Request Forgery) is a security vulnerability that occurs when an attacker tricks a user into performing unintended actions on a web application that the user is authenticated to. In Next.js apps, server actions and cookies can become a security risk if not properly validated, allowing attackers to execute malicious requests on behalf of the user.
For example, consider a Next.js app that uses cookies to store user authentication tokens. If an attacker can trick a user into visiting a malicious website that sends a request to the Next.js app, the app may perform the requested action without validating the request, potentially leading to security breaches.
How CSRF Attacks Work
A CSRF attack typically involves an attacker creating a malicious website that sends a request to the vulnerable web application. The request is sent with the user's cookies, which includes the authentication token, allowing the web application to authenticate the request.
To demonstrate this, let's consider an example of a vulnerable Next.js page that updates a user's profile information:
import { NextApiRequest, NextApiResponse } from 'next';
const updateProfile = async (req: NextApiRequest, res: NextApiResponse) => {
const { name, email } = req.body;
// Update user profile information
res.status(200).json({ message: 'Profile updated successfully' });
};
export default updateProfile;
In this example, the updateProfile function updates the user's profile information without validating the request. An attacker can create a malicious website that sends a request to this endpoint, potentially updating the user's profile information without their knowledge or consent.
Validating Requests to Prevent CSRF Attacks
To prevent CSRF attacks, it's essential to validate requests to ensure they come from a trusted source. One common approach is to use a CSRF token, which is a unique token generated by the server and included in the request.
Here's an example of how to implement CSRF token validation in a Next.js page:
import { NextApiRequest, NextApiResponse } from 'next';
import { v4 as uuidv4 } from 'uuid';
const updateProfile = async (req: NextApiRequest, res: NextApiResponse) => {
const csrfToken = req.cookies.csrfToken;
if (!csrfToken || csrfToken !== req.body.csrfToken) {
return res.status(403).json({ message: 'Invalid CSRF token' });
}
const { name, email } = req.body;
// Update user profile information
res.status(200).json({ message: 'Profile updated successfully' });
};
export default updateProfile;
In this example, the updateProfile function checks the csrfToken cookie and the csrfToken field in the request body. If the tokens don't match, it returns a 403 error.
Using SameSite Cookies to Prevent CSRF Attacks
Another approach to preventing CSRF attacks is to use SameSite cookies, which restrict the cookie to only be sent with requests from the same site.
Here's an example of how to set a SameSite cookie in a Next.js page:
import { NextApiRequest, NextApiResponse } from 'next';
const setCookie = (res: NextApiResponse) => {
res.setHeader(
'Set-Cookie',
'csrfToken=token; SameSite=Lax; Secure; HttpOnly'
);
};
const updateProfile = async (req: NextApiRequest, res: NextApiResponse) => {
setCookie(res);
// Update user profile information
res.status(200).json({ message: 'Profile updated successfully' });
};
export default updateProfile;
In this example, the setCookie function sets a SameSite cookie with the Lax attribute, which allows the cookie to be sent with GET requests from the same site.
Automatically Detecting CSRF Vulnerabilities with SecuriSky
SecuriSky is a security scanner that can automatically detect CSRF vulnerabilities in Next.js apps, including issues with server actions and cookies. By using SecuriSky, developers can quickly identify and fix security risks before they become major issues.
For example, consider a Next.js app that uses a library to handle authentication. If the library has a known vulnerability, SecuriSky can detect it and alert the developer.
import requests
def check_vulnerability(url):
response = requests.get(url)
if response.status_code == 200:
print("Vulnerability detected")
else:
print("No vulnerability detected")
check_vulnerability("https://example.com/login")
Quick Fix Checklist
Try it free
Scan your app for these issues now
Paste your URL and get a full security, performance, and SEO report in under 2 minutes — no signup required.
Run a free scan