Menu

18. Security

Next.js Master Roadmap - IT Technology

This chapter teaches how to prevent common web vulnerabilities in Next.js applications, including cross‑site scripting, cross‑site request forgery, and SQL injection. It also covers best practices for managing secrets with environment variables, API key restrictions, and secret‑management services.

No MCQ questions available for this chapter.

18. Security

Introduction

Security is a cornerstone of any production‑ready Next.js application. As developers we must protect user data, prevent unauthorized actions, and safeguard credentials. This chapter walks through the three most prevalent injection‑style attacks—Cross‑Site Scripting (XSS), Cross‑Site Request Forgery (CSRF), and SQL Injection—and shows concrete mitigation techniques that fit naturally into the Next.js ecosystem. The second half focuses on secrets management, explaining how to store API keys, database passwords, and JWT signatures safely using environment variables, naming conventions, and external vaults.

Cross‑Site Scripting (XSS)

XSS occurs when untrusted data is injected into a page and executed as JavaScript in the victim’s browser. In Next.js, the most common vector is rendering user‑supplied HTML without proper escaping.

Why the naïve approach is dangerous

<div dangerouslySetInnerHTML={{ __html: userComment }} /> // XSS if userComment contains <script>

If userComment contains a script tag, the browser will execute it, potentially stealing cookies, performing actions on behalf of the user, or defacing the site.

Safe default rendering

React (and thus Next.js) automatically escapes strings placed inside JSX curly braces:

<div>{userComment}</div> // React escapes by default

This converts characters like <, >, &, ", and ' into their HTML entities, neutralizing script tags.

When HTML is required

Sometimes you need to allow a limited set of HTML (e.g., bold, links). In those cases, sanitize the input before injecting it:

import DOMPurify from "dompurify"; <div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userComment) }} />

DOMPurify removes dangerous constructs while preserving safe markup. Remember to keep the library up‑to‑date and configure it with a whitelist that matches your application’s needs.

Additional XSS hardening tips

  • Set a strict Content‑Security‑Policy header (e.g., default-src 'self'; script-src 'self') to mitigate the impact of any slipped‑through script.
  • Avoid using dangerouslySetInnerHTML altogether unless absolutely necessary.
  • Validate input on both client and server sides; reject anything that does not conform to an expected format.

Cross‑Site Request Forgery (CSRF)

CSRF tricks an authenticated user into submitting a state‑changing request (e.g., changing email, making a purchase) without their consent. The attack exploits the fact that browsers automatically include cookies with requests to the originating site.

Mitigation strategies

  1. SameSite cookie attribute – Setting SameSite=Strict or SameSite=Lax prevents the browser from sending cookies on cross‑site requests.
  2. Anti‑CSRF tokens – A unique, unpredictable token is embedded in forms or headers and verified on the server.
  3. Origin/Referer validation – The server checks that the request originates from a trusted origin.

Next.js API route example with double‑submit cookie

The csrf-csrf package provides a convenient middleware that implements the double‑submit cookie pattern.

import { csrfProtection } from "csrf-csrf"; export default async function handler(req, res) { if (req.method