Severity: MEDIUM — found in deep security review (2026-06-09). Grouped hardening items.
-
CORS preflight falls back to configured origin on rejection — src/middleware/builtin/security/cors-simple.ts:18: validation.allowedOrigin || origin sends the configured origin (default *) even when validation rejected the origin. Reject the preflight (403) when allowedOrigin is null.
-
OAuth error leaks env var names — src/oauth/providers/base.ts:248-249: Missing ${clientIdEnvVar} or ${clientSecretEnvVar}. Replace with "OAuth provider credentials are not configured".
-
API keys cached in frozen global singleton — src/config/environment-config.ts:172-176: openaiApiKey/anthropicApiKey/googleApiKey/githubToken/apiToken live for process lifetime, visible in heap/core dumps. Remove these fields; read on demand via getEnv() (the pattern already used in src/config/env.ts).
-
Rate limiter shared "unknown" bucket — src/security/rate-limit/middleware.ts:32: clients with no X-Forwarded-For/X-Real-IP collapse into one bucket (DoS amplification / bypass). Require a proxy header, use transport remote addr, or fail closed.
-
Cross-project module fetch has no size limit — src/modules/server/module-server.ts:769, src/modules/react-loader/ssr-module-loader/cross-project-import-loader.ts:83: response.text() with no Content-Length cap → OOM vector. Add a max-size guard (e.g. 5MB).
-
HTTP-import allowlist regex evadable — src/routing/api/module-loader/http-validator.ts:6-7: template-literal / concatenated dynamic imports bypass the regex; the direct Deno import path (loader.ts loadTSModuleDirect) skips the esbuild enforcement layer.
-
Hosted-deployment auth redirect uses full URL — src/proxy/handler.ts:448-452: uses url.toString() as redirect target for *.production.veryfront.org; prefer relative pathname + search.
Severity: MEDIUM — found in deep security review (2026-06-09). Grouped hardening items.
CORS preflight falls back to configured origin on rejection —
src/middleware/builtin/security/cors-simple.ts:18:validation.allowedOrigin || originsends the configured origin (default*) even when validation rejected the origin. Reject the preflight (403) whenallowedOriginis null.OAuth error leaks env var names —
src/oauth/providers/base.ts:248-249:Missing ${clientIdEnvVar} or ${clientSecretEnvVar}. Replace with"OAuth provider credentials are not configured".API keys cached in frozen global singleton —
src/config/environment-config.ts:172-176:openaiApiKey/anthropicApiKey/googleApiKey/githubToken/apiTokenlive for process lifetime, visible in heap/core dumps. Remove these fields; read on demand viagetEnv()(the pattern already used insrc/config/env.ts).Rate limiter shared "unknown" bucket —
src/security/rate-limit/middleware.ts:32: clients with noX-Forwarded-For/X-Real-IPcollapse into one bucket (DoS amplification / bypass). Require a proxy header, use transport remote addr, or fail closed.Cross-project module fetch has no size limit —
src/modules/server/module-server.ts:769,src/modules/react-loader/ssr-module-loader/cross-project-import-loader.ts:83:response.text()with noContent-Lengthcap → OOM vector. Add a max-size guard (e.g. 5MB).HTTP-import allowlist regex evadable —
src/routing/api/module-loader/http-validator.ts:6-7: template-literal / concatenated dynamic imports bypass the regex; the direct Deno import path (loader.tsloadTSModuleDirect) skips the esbuild enforcement layer.Hosted-deployment auth redirect uses full URL —
src/proxy/handler.ts:448-452: usesurl.toString()as redirect target for*.production.veryfront.org; prefer relativepathname + search.