Update README and configuration to replace RSA with Ed25519 for federation security
All checks were successful
Build & Push Docker Image / build (push) Successful in 6m30s
All checks were successful
Build & Push Docker Image / build (push) Successful in 6m30s
This commit is contained in:
@@ -172,6 +172,13 @@ router.post('/', authenticateToken, async (req, res) => {
|
||||
if (moderator_code && moderator_code.length > 50) {
|
||||
return res.status(400).json({ error: 'Moderator code must not exceed 50 characters' });
|
||||
}
|
||||
// S2: validate max_participants as non-negative integer
|
||||
if (max_participants !== undefined && max_participants !== null) {
|
||||
const mp = Number(max_participants);
|
||||
if (!Number.isInteger(mp) || mp < 0 || mp > 10000) {
|
||||
return res.status(400).json({ error: 'max_participants must be a non-negative integer (max 10000)' });
|
||||
}
|
||||
}
|
||||
|
||||
const uid = crypto.randomBytes(8).toString('hex');
|
||||
const db = getDb();
|
||||
@@ -240,6 +247,13 @@ router.put('/:uid', authenticateToken, async (req, res) => {
|
||||
if (moderator_code && moderator_code.length > 50) {
|
||||
return res.status(400).json({ error: 'Moderator code must not exceed 50 characters' });
|
||||
}
|
||||
// S2: validate max_participants on update
|
||||
if (max_participants !== undefined && max_participants !== null) {
|
||||
const mp = Number(max_participants);
|
||||
if (!Number.isInteger(mp) || mp < 0 || mp > 10000) {
|
||||
return res.status(400).json({ error: 'max_participants must be a non-negative integer (max 10000)' });
|
||||
}
|
||||
}
|
||||
|
||||
await db.run(`
|
||||
UPDATE rooms SET
|
||||
@@ -641,8 +655,9 @@ router.post('/:uid/presentation', authenticateToken, async (req, res) => {
|
||||
|
||||
// Remove old presentation file if exists
|
||||
if (room.presentation_file) {
|
||||
const oldPath = path.join(presentationsDir, room.presentation_file);
|
||||
if (fs.existsSync(oldPath)) fs.unlinkSync(oldPath);
|
||||
// S8: defense-in-depth path traversal check
|
||||
const oldPath = path.resolve(presentationsDir, room.presentation_file);
|
||||
if (oldPath.startsWith(presentationsDir + path.sep) && fs.existsSync(oldPath)) fs.unlinkSync(oldPath);
|
||||
}
|
||||
|
||||
fs.writeFileSync(filepath, buffer);
|
||||
@@ -663,8 +678,9 @@ router.delete('/:uid/presentation', authenticateToken, async (req, res) => {
|
||||
if (!room) return res.status(404).json({ error: 'Room not found or no permission' });
|
||||
|
||||
if (room.presentation_file) {
|
||||
const filepath = path.join(presentationsDir, room.presentation_file);
|
||||
if (fs.existsSync(filepath)) fs.unlinkSync(filepath);
|
||||
// S8: defense-in-depth path traversal check
|
||||
const filepath = path.resolve(presentationsDir, room.presentation_file);
|
||||
if (filepath.startsWith(presentationsDir + path.sep) && fs.existsSync(filepath)) fs.unlinkSync(filepath);
|
||||
}
|
||||
|
||||
await db.run('UPDATE rooms SET presentation_file = NULL, presentation_name = NULL, updated_at = CURRENT_TIMESTAMP WHERE uid = ?', [req.params.uid]);
|
||||
|
||||
Reference in New Issue
Block a user