Rules Hub
Coding Rules Library
Rule priority, scope & exceptions
Use this to align rules with the senior-level structure (P0/P1/P2, scope, exceptions/tradeoffs).
Ship a strict Content-Security-Policy without unsafe-inline/unsafe-eval
Set an explicit CSP that disallows unsafe-inline and unsafe-eval, uses nonces or hashes for required inline scripts, and locks default-src down — as defense-in-depth against XSS and clickjacking.
Bad example
| 1 | // next.config.js |
| 2 | async headers() { |
| 3 | return [ |
| 4 | { |
| 5 | source: '/:path*', |
| 6 | headers: [ |
| 7 | { |
| 8 | key: 'Content-Security-Policy', |
| 9 | // unsafe-inline + unsafe-eval + wildcard = CSP that protects nothing |
| 10 | value: |
| 11 | "default-src * 'unsafe-inline' 'unsafe-eval' data: blob:;", |
| 12 | }, |
| 13 | ], |
| 14 | }, |
| 15 | ]; |
| 16 | } |
Explanation (EN)
default-src * with 'unsafe-inline' and 'unsafe-eval' permits inline <script> blocks, injected event handlers, and eval-based payloads from any origin — exactly the vectors CSP exists to block. This policy passes scanners that only check 'a CSP header exists' while providing zero real XSS mitigation.
Objašnjenje (HR)
default-src * uz 'unsafe-inline' i 'unsafe-eval' dopusta inline <script> blokove, ubacene event handlere i eval payloade s bilo kojeg origina — upravo vektore koje CSP postoji da blokira. Ova politika prolazi skenere koji samo provjeravaju 'postoji li CSP header' dok pruza nula stvarne XSS zastite.
Good example
| 1 | // middleware.ts (Next.js) - per-request nonce |
| 2 | import { NextResponse, type NextRequest } from 'next/server'; |
| 3 |
|
| 4 | export function middleware(req: NextRequest) { |
| 5 | const nonce = crypto.randomUUID().replace(/-/g, ''); |
| 6 | const csp = [ |
| 7 | "default-src 'self'", |
| 8 | `script-src 'self' 'nonce-${nonce}' 'strict-dynamic'`, |
| 9 | "style-src 'self' 'unsafe-inline'", // styles only; scripts use nonce |
| 10 | "img-src 'self' data: https:", |
| 11 | "object-src 'none'", |
| 12 | "base-uri 'self'", |
| 13 | "frame-ancestors 'none'", |
| 14 | ].join('; '); |
| 15 |
|
| 16 | const res = NextResponse.next({ request: { headers: new Headers({ 'x-nonce': nonce }) } }); |
| 17 | res.headers.set('Content-Security-Policy', csp); |
| 18 | return res; |
| 19 | } |
Explanation (EN)
default-src 'self' plus a per-request script nonce means only your own scripts and explicitly-nonced inline scripts run; injected attacker script has no matching nonce and is blocked. object-src 'none', base-uri 'self', and frame-ancestors 'none' close off plugin, base-tag, and clickjacking vectors. The nonce is read from x-nonce in your root layout and applied to <script> tags.
Objašnjenje (HR)
default-src 'self' uz per-request script nonce znaci da se izvode samo tvoje skripte i eksplicitno noncane inline skripte; ubacena napadaceva skripta nema odgovarajuci nonce i blokira se. object-src 'none', base-uri 'self' i frame-ancestors 'none' zatvaraju plugin, base-tag i clickjacking vektore. Nonce se cita iz x-nonce u root layoutu i primjenjuje na <script> tagove.
Notes (EN)
OWASP CSP Cheat Sheet. frame-ancestors 'none' supersedes the legacy X-Frame-Options for clickjacking on modern browsers.
Bilješke (HR)
OWASP CSP Cheat Sheet. frame-ancestors 'none' zamjenjuje zastarjeli X-Frame-Options za clickjacking na modernim preglednicima.
Exceptions / Tradeoffs (EN)
Roll out with Content-Security-Policy-Report-Only first and a report endpoint to find breakage before enforcing. style-src 'unsafe-inline' is a common pragmatic concession (CSS injection is far lower risk than script) until you can hash/nonce styles. Third-party widgets may force specific host allowlist entries — add the exact host, not a wildcard.
Iznimke / Tradeoffi (HR)
Prvo uvedi Content-Security-Policy-Report-Only s report endpointom da nades sto puca prije nego sto pocnes provoditi. style-src 'unsafe-inline' je cesto pragmaticno popustanje (CSS injection je puno manji rizik od skripte) dok ne mozes hashati/nonceati stilove. Third-party widgeti mogu nametnuti odredene host unose — dodaj tocan host, ne wildcard.