Политика безопасности содержимого: nonce и hash
Создайте строгую CSP с nonce для встроенных скриптов, хэшами для известных фрагментов и report-uri для контроля нарушений в рабочей среде
«Политика безопасности содержимого: nonce и hash» — бесплатный урок Frontend Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Frontend Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Frontend Academy содержит 4 уроков всего.
Итоги CSP
CSP — это HTTP-заголовок, который задаёт белый список того, что браузеру разрешено загружать: скрипты, стили, изображения, шрифты, фреймы и соединения. Многоуровневая защита: даже если XSS обходит ваши фильтры, CSP часто останавливает полезную нагрузку.
Структура заголовка CSP
Каждая директива перечисляет разрешённые источники. 'self' означает тот же источник. Также можно разрешать конкретные URL.
Content-Security-Policy:
default-src 'self';
script-src 'self' https://cdn.example.com;
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
connect-src 'self' https://api.example.com;
font-src 'self' https://fonts.gstatic.com;
frame-ancestors 'none';
base-uri 'self';Распространённые директивы
default-src: запасной вариант для всего. script-src: JavaScript. style-src: CSS. img-src: изображения. connect-src: fetch/XHR/WebSocket. font-src: шрифты. frame-ancestors: кто может встроить ваш сайт во фрейм (защита от кликджекинга).
'unsafe-inline' — распространённая уязвимость
Многие сайты добавляют 'unsafe-inline', чтобы разрешить встроенные теги <script> и атрибуты onclick. Это лишает CSP её основной цели: полезные нагрузки XSS могут выполняться встроенными. Замените это значение одноразовыми значениями или хешами.
Одноразовые значения — список разрешений на один раз
Создавайте случайное одноразовое значение для каждого запроса. Добавляйте это значение к легитимным встроенным скриптам. Браузер разрешает только скрипты с совпадающими одноразовыми значениями.
// Server (Express middleware):
import crypto from 'crypto';
app.use((req, res, next) => {
res.locals.nonce = crypto.randomBytes(16).toString('base64');
res.setHeader('Content-Security-Policy',
`script-src 'nonce-${res.locals.nonce}' 'strict-dynamic'`
);
next();
});
// Template:
<script nonce="<%= nonce %>">window.config = {...};</script>'strict-dynamic'
Объединяйте одноразовое значение с 'strict-dynamic': доверенные скрипты (скрипты с одноразовым значением) могут загружать дополнительные скрипты. Это устраняет необходимость перечислять URL каждого источника скриптов. Это современная лучшая практика для CSP.
Хеши — статический белый список
Для известных неизменных встроенных скриптов (например, если ваша сборка всегда выдаёт один и тот же фрагмент начальной загрузки) вычислите его SHA-256 и добавьте его как источник-хеш. Одноразовое значение для каждого запроса не требуется.
// Hash of: console.log('hi');
Content-Security-Policy: script-src 'sha256-XwCNuB+/RUgPlAACI+yHrUKqUsm4zlpGV/Q8tEUx0Q4='Хеши встроенных стилей
Тот же приём работает для встроенных тегов <style>: вычислите их хеш и добавьте его в style-src. Для CSS это лучше, чем 'unsafe-inline'.
Режим отчётов CSP
Используйте Content-Security-Policy-Report-Only, чтобы протестировать политику без её применения. Нарушения отправляются на вашу конечную точку, но ничего не блокируют. Это отлично подходит для постепенного внедрения CSP.
Content-Security-Policy-Report-Only:
default-src 'self';
report-uri /csp-violations
// /csp-violations receives POSTs like:
{
"csp-report": {
"document-uri": "https://example.com/",
"violated-directive": "script-src 'self'",
"blocked-uri": "https://evil.com/x.js"
}
}report-to (современный вариант)
report-to вместе с Reporting-Endpoints — современная замена report-uri. Данные те же, но структура стала более организованной.
Reporting-Endpoints: csp="/csp-reports"
Content-Security-Policy: script-src 'self'; report-to cspИнтеграция с фреймворками
Next.js: задавайте CSP через middleware.ts или заголовки в next.config.js. Nuxt: модуль nuxt-security. Vite: настройте заголовки сервера разработки, а для production используйте конфигурацию заголовков вашего хостинга (Vercel, Netlify).
// next.config.js
module.exports = {
async headers() {
return [{
source: '/(.*)',
headers: [{
key: 'Content-Security-Policy',
value: "default-src 'self'; script-src 'self' 'strict-dynamic'"
}]
}];
}
};Проверка CSP
Откройте DevTools → Console: нарушения CSP записываются там. Используйте https://csp-evaluator.withgoogle.com/, чтобы оценить вашу политику. Сначала включите режим только отчётов в production, а после исправления всех нарушений перейдите к применению политики.
Быстрая проверка
Почему 'unsafe-inline' в директиве script-src считается слабым местом CSP?
Итоги: лучшие практики CSP
Устанавливайте заголовок Content-Security-Policy с директивами для каждого типа ресурса. Избегайте 'unsafe-inline' — используйте одноразовые значения + 'strict-dynamic' или хеши SHA. Устанавливайте frame-ancestors 'none' (или 'self'). Сначала тестируйте в режиме только отчётов. Отправляйте сведения о нарушениях на /csp-violations (или используйте современный report-to). Фреймворки поддерживают CSP через middleware или заголовки конфигурации.
Часто задаваемые вопросы
Урок «Политика безопасности содержимого: nonce и hash» бесплатный?
Да — полный текст урока «Политика безопасности содержимого: nonce и hash» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Frontend Academy, подпишись на CoddyKit PRO. Курс Frontend Academy содержит 4 уроков всего.
Чему я научусь в уроке «Политика безопасности содержимого: nonce и hash»?
Создайте строгую CSP с nonce для встроенных скриптов, хэшами для известных фрагментов и report-uri для контроля нарушений в рабочей среде Ты практикуешь Frontend Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Frontend Academy?
Предыдущий опыт не требуется. Frontend Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Политика безопасности содержимого: nonce и hash»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Frontend Academy?
Да. Каждый урок Frontend Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Предотвращение XSS: кодирование вывода и CSP
- CSRF: файлы cookie SameSite и токены
- Политика безопасности содержимого: nonce и hash
- Потоки OAuth на фронтенде