[grade=B] api: fix undeclared 'format' runtime bug in routes/ca.js + 10 lint errors

- routes/ca.js: declare format before pfx/pem/crt dispatch (was ReferenceError
  on every request that passed validation); add CA_CERT_FORMATS single source
  of truth + hardened format extraction (string-coerce, whitelist)
- routes/caddycode.js: fix upstream-validation regexes (control-char classes)
- routes/logs.js: SSE/validation lint fixes
- routes/openclaw.js: remove useless regex escape in ALLOWED_PATH_RE
- fleet-validation.js + http-caddy-admin-origin test: eslint-disable for
  intentional control-regex security sentinels
- ca-dc076.routes.test.js: regression test for declared format + behavioral
  coverage of format validation (now pre-PKI)

Judge: Qwen lane (qwen3.8-max) grade B, 0 blocking, verdict
/tmp/judge-batch1-verdict.json. API suite 2859/2859 green.
This commit is contained in:
Hermes
2026-08-31 23:37:00 -07:00
parent b6678cf591
commit c28322eb46
9 changed files with 92 additions and 11 deletions
+21
View File
@@ -139,6 +139,9 @@ module.exports = function(ctx) {
// can mis-handle; reject it to keep the password copy-paste-safe).
const CA_PFX_PASSWORD_RE = /^[A-Za-z0-9!@#%^_+,.~:-]{8,64}$/;
const CA_CERT_RATE_LIMIT = { windowMs: 60_000, max: 10 };
// Single source of truth for accepted ?format= values. `wantsPfx`, the
// password requirement, and the response dispatch all derive from this.
const CA_CERT_FORMATS = ['pfx', 'pem', 'crt', 'key', 'fullchain'];
const caCertRateBuckets = new Map(); // ip -> { count, resetAt }
function caCertRateLimit(ip) {
const now = Date.now();
@@ -175,6 +178,24 @@ module.exports = function(ctx) {
const { domain } = req.params;
// FIX: `format` was referenced in the dispatch below but never declared,
// so every request that passed validation threw ReferenceError. Default
// 'pfx' matches the `wantsPfx` check (no format param => pfx).
// Accept only a non-empty string: query strings can deliver arrays
// (?format=a&format=b) or nested objects, which must be rejected.
const rawFormat = req.query.format;
if (rawFormat !== undefined && (typeof rawFormat !== 'string' || rawFormat === '')) {
return ctx.errorResponse(res, 400,
`Invalid format parameter. Use: ${CA_CERT_FORMATS.join(', ')}.`,
{ code: 'DC-076_FORMAT_INVALID' });
}
if (rawFormat !== undefined && !CA_CERT_FORMATS.includes(rawFormat)) {
return ctx.errorResponse(res, 400,
`Invalid format '${rawFormat}'. Use: ${CA_CERT_FORMATS.join(', ')}.`,
{ code: 'DC-076_FORMAT_INVALID' });
}
const format = rawFormat || 'pfx';
// DC-076: password is REQUIRED for the pfx format (no `=`) and must
// be ≥ 8 chars. Previously `password = 'dashcaddy'` — a hardcoded
// default that silently signed every PFX with the same published