MENU
Security
When a Server Action is created and exported, it automatically generates a public HTTP endpoint by default, so it should be handled with caution.
This section illustrates the security features built into Next.js and explores the best security pratices that a Next.js developer should adopt.
To enhance security, Next.js includes the following built-in features:
- Secure Action IDs: Next.js generates encrypted, non-deterministic IDs that allow the client to reference and call Server Actions securely. These IDs are regenerated whenever a new build is triggered or when the build cache is invalidated.
- Dead Code Elimination: Unused Server Actions (referenced by their IDs) are removed from the client bundle, preventing public access by third parties.
- Closed Variable Encryption: When a Server Action is defined within a component, it gains access to outer scope variables (clousure), which are sent to the client and back to the server when invoked. To secure sensitive data, Next.js encrypts these variables, generating a unique private key for each action with every new build, allowing actions to be invoked only for that specific build.
- POST CSRF Protection: Server Actions, which can be triggered within a <form> element, use the POST method exclusively. This restriction, along with the default use of SameSite cookies, helps protect against most CSRF attacks in modern browsers.
- Same-origin Verification: In Next.js, Server Actions verify that the Origin and Host (or X-Forwarded-Host) headers match. If they don't, the request is aborted, ensuring that Server Actions can only be called from the same host as the page that contains them.
A Next.js developer should adopt the following security pratices:
- Authenticate Access: Ensure the user is authorized before allowing them to perform a server action.
- Use Taint APIs: Use React's taint APIs to prevent specific data from being sent to the client.
- Rotate Encryption Key and Sign Across Multiple Hosts: When self-hosting a Next.js app across multiple servers, different encryption keys may cause inconsistencies. To ensure consistency, set the process.env.NEXT_SERVER_ACTIONS_ENCRYPTION_KEY environment variable, providing a persistent encryption key across all server instances. This approach is essential for applications needing consistent encryption across deployments. For security, consider practices like key rotation and signing. Note: Vercel deployments handle this automatically.
- Configure serverActions.allowedOrigins: For large applications with reverse proxies or multi-layered backends, use the serverActions.allowedOrigins configuration option to define a list of trusted origins. This option takes an array of strings specifying safe origins.
// next.config.js
/** @type {import('next').NextConfig} */
module.exports = {
experimental: {
serverActions: {
allowedOrigins: ['my-proxy.com', '*.my-proxy.com'],
},
},
}Read the blog here for more information about security best practices in Next.js.