feat: CSP enabled via src/middleware/csp.js (unsafe-inline, blocks external/frame/object)
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* src/middleware/csp.js — Content Security Policy через helmet.
|
||||
*
|
||||
* Текущее ограничение: EJS-шаблоны используют inline <style>, inline <script>
|
||||
* и атрибуты onclick/style= — поэтому 'unsafe-inline' пока необходим.
|
||||
* Это всё равно лучше отключённого CSP: блокируются внешние ресурсы,
|
||||
* фреймирование, object/embed, переопределение base.
|
||||
*
|
||||
* Что блокирует эта политика:
|
||||
* - Загрузку скриптов/стилей с внешних доменов (CDN-инъекции, supply chain)
|
||||
* - Фреймирование страниц (clickjacking) — frame-ancestors 'none'
|
||||
* - <object>, <embed>, <applet> — object-src 'none'
|
||||
* - Переопределение <base href> — base-uri 'self'
|
||||
* - POST форм на внешние домены — form-action 'self'
|
||||
*
|
||||
* TODO (при переносе стилей в .css и скриптов в .js):
|
||||
* убрать 'unsafe-inline', добавить nonce или hash для оставшихся inline-блоков.
|
||||
*
|
||||
* Экспортирует: cspMiddleware — передавать напрямую в app.use().
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const helmet = require('helmet');
|
||||
|
||||
/**
|
||||
* Возвращает helmet CSP middleware.
|
||||
* Вынесено в функцию чтобы легко заменить директивы без правки server.js.
|
||||
* @returns {import('express').RequestHandler}
|
||||
*/
|
||||
function createCspMiddleware() {
|
||||
return helmet.contentSecurityPolicy({
|
||||
directives: {
|
||||
defaultSrc: ["'self'"],
|
||||
// 'unsafe-inline' нужен пока стили и скрипты inline в EJS.
|
||||
scriptSrc: ["'self'", "'unsafe-inline'"],
|
||||
styleSrc: ["'self'", "'unsafe-inline'"],
|
||||
imgSrc: ["'self'", 'data:'], // data: для SVG-иконок если появятся
|
||||
fontSrc: ["'self'"],
|
||||
connectSrc: ["'self'"],
|
||||
objectSrc: ["'none'"], // блок <object>/<embed>/<applet>
|
||||
baseUri: ["'self'"], // блок переопределения <base>
|
||||
formAction: ["'self'"], // POST только на свой домен
|
||||
frameAncestors: ["'none'"], // clickjacking protection
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const cspMiddleware = createCspMiddleware();
|
||||
|
||||
module.exports = { cspMiddleware };
|
||||
Reference in New Issue
Block a user