Fix 16 HIGH/MEDIUM security bugs across API

HIGH fixes:
- TOTP disable now requires valid code verification
- TOTP secret removed from plaintext file storage
- Container ID validated before update/check-update/logs operations
- DNS server parameter restricted to configured servers (SSRF prevention)
- Backup export no longer includes encryption key
- Backup restore of sensitive files requires TOTP re-authentication

MEDIUM fixes:
- Session cookie Secure flag added
- Caddy reload errors no longer leaked to client
- saveConfig uses atomic locked updates via configStateManager
- Log file path traversal prevented via symlink resolution
- Credential cache entries now expire after 5 minutes
- _httpFetch enforces 10MB response size limit
- External URL path injection into Caddyfile blocked
- Custom volume host paths validated against allowed roots
- Error logs endpoint no longer returns stack traces
- Logo delete path traversal prevented via path.basename()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-07 00:15:28 -08:00
parent 6979302fb7
commit 59b6d7d360
12 changed files with 172 additions and 69 deletions

View File

@@ -30,7 +30,8 @@ module.exports = function(ctx) {
if (!response.ok) {
const errorText = await response.text();
return ctx.errorResponse(res, 500, `[DC-303] Caddy reload failed: ${errorText}`);
ctx.log.error('caddy', 'Caddy reload failed', { error: errorText });
return ctx.errorResponse(res, 500, '[DC-303] Caddy reload failed. Check server logs for details.');
}
res.json({ success: true, message: 'Caddy configuration reloaded successfully' });
@@ -202,6 +203,13 @@ module.exports = function(ctx) {
const hostHeader = preserveHost ? `\n header_up Host {upstream_hostport}` : '';
const urlObj = new URL(externalUrl);
// Validate URL components are safe for Caddyfile syntax
const unsafeCaddyChars = /[{}\n\r]/;
if (unsafeCaddyChars.test(urlObj.host) || unsafeCaddyChars.test(urlObj.pathname)) {
return ctx.errorResponse(res, 400, 'External URL contains characters not safe for Caddy configuration');
}
const baseUrl = `${urlObj.protocol}//${urlObj.host}`;
const urlPath = urlObj.pathname.replace(/\/$/, '');