fix: harden auth site access and SSH validation

This commit is contained in:
Gustavo
2026-09-28 14:54:03 -03:00
parent 5b926d637b
commit c4db0dc1e2
33 changed files with 992 additions and 125 deletions
+10 -1
View File
@@ -9,12 +9,13 @@ import { Router } from 'express';
import type { Request, Response } from 'express';
import { requireAuth, requireWrite } from '../middleware/auth';
import { siteScopeByDevice } from '../utils/siteScope';
import { activeSite } from '../middleware/site';
import { activeSite, enforceSiteAccess, unauthorizedDeviceIds } from '../middleware/site';
import { query, queryOne } from '../config/database';
import { commandRunner } from '../services/CommandRunner';
const router = Router();
router.use(requireAuth);
router.use(enforceSiteAccess);
/** Commands that change how a device is reached, and so deserve a warning. */
const RISKY_PATTERNS: { pattern: RegExp; why: string }[] = [
@@ -46,6 +47,10 @@ router.post('/preview', async (req: Request, res: Response) => {
if (!Array.isArray(device_ids) || device_ids.length === 0) {
return res.status(400).json({ error: 'device_ids array is required' });
}
const forbidden = await unauthorizedDeviceIds(req, device_ids);
if (forbidden.length) {
return res.status(403).json({ error: 'One or more devices are outside your authorized sites', device_ids: forbidden });
}
const size = Math.max(1, Math.min(50, Number(wave_size) || 1));
const devices = await query<{ id: number; name: string; ip_address: string; status: string }>(
@@ -85,6 +90,10 @@ router.post('/runs', requireWrite, async (req: Request, res: Response) => {
if (!Array.isArray(device_ids) || device_ids.length === 0) {
return res.status(400).json({ error: 'device_ids array is required' });
}
const forbidden = await unauthorizedDeviceIds(req, device_ids);
if (forbidden.length) {
return res.status(403).json({ error: 'One or more devices are outside your authorized sites', device_ids: forbidden });
}
const size = Math.max(1, Math.min(50, Number(wave_size) || 1));
const run = await queryOne<{ id: number }>(