fix: полное ревью системы — 15 исправлений безопасности и надёжности
Безопасность: - tests/🆔 скрыть is_correct и explanation для студентов (P0) - SQL injection: limit/offset через placeholder вместо template literal - Stored XSS: stripTags для lesson comments, flashcards, redBook sightings - profile.html: escape e.message в showMsg (XSS через server error) - attachment_url: валидация только /uploads/* путей - requestId: генерировать UUID сервером, не доверять клиенту - register: скрыть token_version из ответа Надёжность: - register: обработка UNIQUE constraint race condition - pet buyBg: re-check баланса внутри транзакции - DB errors: скрыть e.message в testController/questionController/courseController - preferences: лимит 50KB на размер JSON UX: - board.html: debounce 250ms на search input Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
const db = require('../db/db');
|
||||
const { onLessonComplete } = require('./gamificationController');
|
||||
const { stripTags } = require('../utils/sanitize');
|
||||
|
||||
/* ── helpers ──────────────────────────────────────────────────────────── */
|
||||
function parseBlock(b) {
|
||||
@@ -249,7 +250,7 @@ function addComment(req, res) {
|
||||
const lesson = db.prepare('SELECT id FROM lessons WHERE id = ?').get(req.params.id);
|
||||
if (!lesson) return res.status(404).json({ error: 'Lesson not found' });
|
||||
|
||||
const text = (req.body.text || '').trim();
|
||||
const text = stripTags((req.body.text || '').trim());
|
||||
if (!text) return res.status(400).json({ error: 'text required' });
|
||||
if (text.length > 2000) return res.status(400).json({ error: 'Comment too long (max 2000)' });
|
||||
|
||||
|
||||
Reference in New Issue
Block a user