Security Advisory: SEC-21 — Hardcoded Fallback in INTERNAL_SECURITY_LOG_SECRET
Security Advisory: SEC-21 — Hardcoded Fallback in INTERNAL_SECURITY_LOG_SECRET
Severity: High
Control: SEC-21
Category: Data Protection
Fixed in: v1.0.57
Affected files:
src/middleware.tssrc/app/api/auth/security-log/route.ts
Background
Calmony Pay maintains an internal security audit trail in the auth_security_log database table. Writes to this table are gated by the /api/auth/security-log route, which validates each request against a shared secret supplied via the INTERNAL_SECURITY_LOG_SECRET environment variable.
Vulnerability
Both src/middleware.ts and src/app/api/auth/security-log/route.ts previously resolved the secret using a nullish-coalescing fallback:
// BEFORE — vulnerable
const secret = process.env.INTERNAL_SECURITY_LOG_SECRET ?? 'insecure-dev-secret';
If a production deployment was missing the INTERNAL_SECURITY_LOG_SECRET environment variable, the application accepted the hardcoded string 'insecure-dev-secret' as a valid credential. An external party who knew or guessed this value could:
- Write arbitrary entries to
auth_security_log. - Flood the audit log, making genuine security events harder to identify.
- Inject false records to obscure real incidents during an investigation.
Fix
1. Remove the hardcoded fallback
The fallback expression has been removed. The secret is now read strictly from the environment:
// AFTER — secure
const secret = process.env.INTERNAL_SECURITY_LOG_SECRET;
2. Fail closed when the variable is absent
If INTERNAL_SECURITY_LOG_SECRET is not set, the /api/auth/security-log route returns 500 immediately rather than proceeding with an insecure default:
if (!secret) {
return new Response('Server misconfiguration', { status: 500 });
}
3. Production startup guard
A startup check throws at boot time when running in production without the secret configured:
if (process.env.NODE_ENV === 'production' && !process.env.INTERNAL_SECURITY_LOG_SECRET) {
throw new Error(
'INTERNAL_SECURITY_LOG_SECRET must be set in production. Refusing to start.'
);
}
This prevents the application from ever reaching a serving state while misconfigured.
Required Operator Action
Before upgrading to or deploying v1.0.57 in any production environment:
-
Generate a strong secret (minimum 32 random bytes, e.g. using
openssl rand -hex 32). -
Set the environment variable in your hosting platform:
INTERNAL_SECURITY_LOG_SECRET=<your-generated-secret> -
Verify the value is present before starting the application — the process will exit on startup if the variable is absent in
NODE_ENV=production.
Note: If you are running in
NODE_ENV=developmentorNODE_ENV=test, the startup guard is intentionally skipped to avoid friction in local development. You should still set the variable locally to exercise the full authentication path during testing.
Impact Assessment
| Dimension | Assessment |
|---|---|
| Confidentiality | No direct data exposure — the vulnerability affects integrity of the audit log, not read access to sensitive records. |
| Integrity | High — arbitrary log entries could be injected, masking real security events. |
| Availability | Medium — the log table could be flooded, degrading query performance on auth_security_log. |
| Exploitability | Moderate — requires knowledge of the fallback string, which was visible in the open source codebase. |
References
- Internal control: SEC-21
- Affected release: v1.0.57 Changelog