fix: DeepSeek audit — header injection + IAM limit + bump 0.5.22

- src/api/routes/entries.js: санитизация filename в /api/v1/entries/export
- ui/routes/export.js: санитизация filename в UI /export
- src/auth.js: лимит 100KB для IAM-ответов
- src/api/routes/entries.js: fallback для пустого allowedIds
This commit is contained in:
2026-06-04 15:48:16 +03:00
parent 58e34042de
commit c1df27d29d
5 changed files with 238 additions and 6 deletions
+3 -2
View File
@@ -54,7 +54,8 @@ function createEntriesRouter({ q }) {
const allowedIds = req.user.profiles && req.user.profiles.length
? req.user.profiles.map(p => p.client_id)
: (req.user.allClientIds || []);
const effectiveClientId = (requestedId && allowedIds.includes(requestedId))
// Если список компаний пуст (IAM не ответил, token без claims) — доверяем requestedId
const effectiveClientId = (requestedId && (!allowedIds.length || allowedIds.includes(requestedId)))
? requestedId
: req.user.clientId;
// companyName: для переключённой компании — находим в profiles или используем clientId
@@ -104,7 +105,7 @@ function createEntriesRouter({ q }) {
const cidrs = await q.getExportCIDRs(companyId);
const aggregated = aggregateCIDRs(cidrs);
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
const fname = req.query.filename || 'white-list.txt';
const fname = (req.query.filename || 'white-list.txt').replace(/[^\w\-_. ]/g, '_');
const disp = req.query.view === '1' ? 'inline' : 'attachment';
res.setHeader('Content-Disposition', `${disp}; filename="${fname}"`);
res.send(aggregated.join('\n') + (aggregated.length ? '\n' : ''));