unsafe-inline и unsafe-eval в CaddyfileКонтекст: В deploy/Caddyfile:40 Content-Security-Policy использует 'unsafe-inline' и 'unsafe-eval' для script-src. Это ослабляет XSS-защиту.
Content-Security-Policy:
default-src 'self';
script-src 'self' 'unsafe-inline' 'unsafe-eval';
style-src 'self' 'unsafe-inline';
img-src 'self' data: blob: https://*.basemaps.cartocdn.com;
font-src 'self' data:;
connect-src 'self' wss: https://api.{$DOMAIN};
frame-ancestors 'none';
'unsafe-inline' для скриптов: Next.js использует inline-скрипты для гидратации и данных страницы (__NEXT_DATA__, __NEXT_LOADED_PAGES__ и т.д.)'unsafe-eval': Нужен для source maps в development. Next.js 14 также может использовать eval() для некоторых динамических импортов и Webpack HMR.'unsafe-inline' для стилей: Tailwind CSS использует JIT-генерацию стилей, которые вставляются через <style>.'unsafe-inline' и 'unsafe-eval' — самые опасные директивы CSP:
Next.js 14 поддерживает nonce через middleware:
// frontend/src/middleware.ts
import { NextResponse } from 'next/server'
import crypto from 'crypto'
export function middleware(request: Request) {
const nonce = crypto.randomBytes(16).toString('base64')
const csp = [
`default-src 'self'`,
`script-src 'self' 'nonce-${nonce}'`,
`style-src 'self' 'nonce-${nonce}'`,
`img-src 'self' data: blob: https://*.basemaps.cartocdn.com`,
`font-src 'self' data:`,
`connect-src 'self' wss: https://api.{$DOMAIN}`,
`frame-ancestors 'none'`,
].join('; ')
const response = NextResponse.next()
response.headers.set('Content-Security-Policy', csp)
response.headers.set('X-Nonce', nonce)
return response
}
Когда nonce работает, можно перейти на 'strict-dynamic':
script-src 'self' 'nonce-{random}' 'strict-dynamic';
'strict-dynamic' говорит браузеру доверять только скриптам с nonce и скриптам, загруженным этими доверенными скриптами. Все inline-скрипты без nonce блокируются.
Добавить report-uri или report-to для сбора нарушений CSP без блокировки:
Content-Security-Policy-Report-Only:
... ;
report-uri https://example.com/csp-report;
| Подход | Уровень защиты | Сложность внедрения |
|---|---|---|
| Nonce + middleware | Высокий | Средняя — нужно модифицировать Next.js |
| strict-dynamic + nonce | Очень высокий | Высокая — ломает сторонние скрипты |
Хеши ('sha256-...') |
Средний | Низкая — но хеши меняются при каждом деплое |
| Report-Only (начать с этого) | Мониторинг | Низкая — не блокирует, только логирует |
Для production: XSS через внедрение inline-скрипта. Если злоумышленник найдёт XSS-уязвимость, CSP не остановит его.
HttpOnly cookie для refresh tokenSameSite=Strict для CSRFframe-ancestors 'none' — защита от clickjackingX-Content-Type-Options: nosniffX-Frame-Options: DENYunsafe-inline и unsafe-evalCode review PhotoPlaces 2026-06. deploy/Caddyfile:40.
#security #csp #frontend #nextjs #production #hardening