fix(security): харднинг загрузки файлов, контроль доступа и XSS
Подхвачено из закрытой параллельной сессии (план project_hardening_2026). Загрузки: magic.js получает safeExt/EXT_FOR_MIME — имя файла на диске берёт расширение из проверенного MIME, а не из client originalname (анти stored-XSS .html/.svg). avatar/flashcard/chat-загрузки дополнительно проверяют magic-байты: содержимое должно соответствовать MIME, иначе файл удаляется и 400. Доступ: fileController.getFolderAccess отдаёт список раздачи только владельцу или админу (была утечка имён/email учеников). testController.getOne гейтит видимость как list() — ученик не прочитает тексты заданий черновиков/вариантов по id. XSS: classes.html escJ() экранирует строку для JS-литерала в inline-onclick (имя ученика с кавычкой больше не ломает обработчик). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ const path = require('path');
|
||||
const fs = require('fs');
|
||||
const db = require('../db/db');
|
||||
const { audit } = require('../utils/audit');
|
||||
const { checkMagicBytes } = require('../utils/magic');
|
||||
|
||||
const AVATARS_DIR = path.join(__dirname, '../../uploads/avatars');
|
||||
|
||||
@@ -9,6 +10,13 @@ const AVATARS_DIR = path.join(__dirname, '../../uploads/avatars');
|
||||
function requestAvatar(req, res) {
|
||||
if (!req.file) return res.status(400).json({ error: 'Файл не загружен' });
|
||||
|
||||
// Содержимое должно соответствовать заявленному MIME (client mimetype не доверяем).
|
||||
const filePath = path.join(AVATARS_DIR, req.file.filename);
|
||||
if (!checkMagicBytes(filePath, req.file.mimetype)) {
|
||||
try { fs.unlinkSync(filePath); } catch {}
|
||||
return res.status(400).json({ error: 'Содержимое файла не является изображением' });
|
||||
}
|
||||
|
||||
// Cancel any previous pending request from this user (replace it)
|
||||
const prev = db.prepare(
|
||||
"SELECT filename FROM avatar_requests WHERE user_id=? AND status='pending'"
|
||||
|
||||
Reference in New Issue
Block a user