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:
@@ -27,11 +27,17 @@ async function register(req, res, next) {
|
||||
|
||||
const cleanName = stripTags(name.trim());
|
||||
const hash = await bcrypt.hash(password, BCRYPT_ROUNDS);
|
||||
const { lastInsertRowid } = db.prepare(
|
||||
'INSERT INTO users (email, password_hash, name) VALUES (?, ?, ?)'
|
||||
).run(email, hash, cleanName);
|
||||
let lastInsertRowid;
|
||||
try {
|
||||
({ lastInsertRowid } = db.prepare(
|
||||
'INSERT INTO users (email, password_hash, name) VALUES (?, ?, ?)'
|
||||
).run(email, hash, cleanName));
|
||||
} catch (e) {
|
||||
if (e.message?.includes('UNIQUE')) return res.status(409).json({ error: 'Email already registered' });
|
||||
throw e;
|
||||
}
|
||||
|
||||
const user = db.prepare('SELECT id, email, name, role, token_version FROM users WHERE id = ?').get(lastInsertRowid);
|
||||
const user = db.prepare('SELECT id, email, name, role FROM users WHERE id = ?').get(lastInsertRowid);
|
||||
const token = signToken(user);
|
||||
res.status(201).json({ token, user });
|
||||
} catch (err) { next(err); }
|
||||
|
||||
Reference in New Issue
Block a user