fix(security): harden rate limits, Redis auth, resource caps, and error sanitization

- Lower LOGIN_ATTEMPT_LIMIT default from 30 to 10 (brute-force protection)
- Lower RATE_LIMIT_PER_MIN default from 1000 to 300
- Add Redis authentication (requirepass) with REDIS_PASSWORD env var
- Add Redis maxmemory 512mb cap to prevent unbounded growth
- Add mem_limit: 1g to Postgres and Redis containers
- Strip internal file paths from all error responses (defense-in-depth)
- Add startup warnings for default admin/Postgres/Redis credentials
- Update security test expectations for new defaults
This commit is contained in:
SnapOtter
2026-06-20 00:53:11 +08:00
parent b847dcc2ab
commit d61226496b
6 changed files with 42 additions and 14 deletions
+3 -2
View File
@@ -20,6 +20,7 @@ import { closeWorkers, startWorkers } from "./jobs/worker.js";
import { captureException, initAnalytics, shutdownAnalytics } from "./lib/analytics.js";
import { shouldRunStartupCleanup } from "./lib/cleanup.js";
import { buildCsp } from "./lib/csp.js";
import { stripInternalPaths } from "./lib/errors.js";
import { ensureAiDirs, recoverInterruptedInstalls } from "./lib/feature-status.js";
import { logger } from "./lib/logger.js";
import { requestDuration } from "./lib/metrics.js";
@@ -229,8 +230,8 @@ app.setErrorHandler((error: Error & { statusCode?: number }, request, reply) =>
request.log.warn({ err: error, url: request.url, method: request.method }, "Request error");
}
reply.status(statusCode).send({
error: statusCode >= 500 ? "Internal server error" : error.message,
...(statusCode < 500 && { details: error.message }),
error: statusCode >= 500 ? "Internal server error" : stripInternalPaths(error.message),
...(statusCode < 500 && { details: stripInternalPaths(error.message) }),
});
});