Clone
2
Security
s.zotov edited this page 2026-04-13 12:25:01 +05:00
This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Безопасность

Pug Injection Protection

Проблема (исправлена): Pug-код рендерится на сервере через Node.js. Вредоносный Pug мог выполнить произвольный код:

div(data-calc=process.cwd()) test
- let x = require('child_process').execSync('ls -la').toString()

Решение: В email-gen-api/server.js добавлена функция validatePugSafety(), которая проверяет Pug перед рендером. Запрещённые паттерны:

Паттерн Что блокирует
require( Подключение модулей
process Доступ к process
child_process Запуск процессов
exec, execSync, spawn Выполнение команд
eval(, Function( Динамическое выполнение
global Глобальный объект
__dirname, __filename Пути файловой системы
fs. Файловые операции
Buffer Работа с буферами

При обнаружении возвращается 400 Bad Request с описанием найденного паттерна.

Дополнительная защита: email-gen-api работает в Docker-контейнере без привилегий и без доступа к хостовой файловой системе (кроме email-gen volume).

Конкурентность рендера

Проблема (исправлена): renderWithNode() писал результат в общий файл public/index.html. При одновременных запросах один пользователь мог получить HTML другого.

Решение: Каждый запрос генерирует уникальное имя файла через crypto.randomBytes(16):

render_a1b2c3d4e5f6.html

Файл создаётся, читается, удаляется — атомарно для каждого запроса.

Авторизация

  • Хэширование: scrypt (salt 16 bytes + hash 64 bytes)
  • Сессии: Cookie z51_token, HttpOnly, SameSite=Lax, TTL 7 дней
  • Очистка: Просроченные сессии удаляются каждые 30 минут
  • Middleware: Все /api/ endpoints (кроме /api/auth/*) требуют авторизацию
  • Admin: /api/admin/* доступен только пользователям с role: admin
  • Проекты: userCanAccessProject() проверяет user.projects (массив или ["*"])

Аудит-логи

Формат: JSONL файлы data/_system/logs/YYYY-MM.jsonl, одна строка = одно действие:

{"ts":1712345678000,"userId":"abc123","login":"admin","action":"letter","project":"Реаспект","details":{},"ip":"172.17.0.1"}

Что логируется:

  • Все успешные мутации (POST/PUT/DELETE) — автоматически через обёртку send()
  • Логин (успешный и неудачный) — явный вызов
  • Логаут — явный вызов

Фильтрация: Admin UI (Настройки → Логи) с фильтрами по пользователю, проекту, действию, пагинация.

Ротация: Файлы старше 6 месяцев удаляются при старте сервера.

Сетевая безопасность

  • Docker порты проброшены только на 127.0.0.1 (не наружу)
  • Nginx — единственная точка входа (80/443)
  • HTTP → HTTPS редирект
  • TLS 1.2+, strong ciphers
  • client_max_body_size 30m (для GIF-загрузок)

Ограничения

  • Сессии хранятся в памяти Node.js — теряются при перезапуске контейнера (пользователи перелогинятся)
  • MAX_BODY_SIZE = 30 MB — достаточно для GIF, но ограничивает загрузку очень больших файлов