Security Fix: Preventing Internal Error Disclosure on /api/migrate
Security Fix: Preventing Internal Error Disclosure on /api/migrate
Release: v1.0.420
OWASP Control: SEC-05 — Security Misconfiguration
Severity: Medium
File affected: src/app/api/migrate/route.ts
Background
Defence-in-depth is a core principle of the MTD compliance platform's security posture. Even endpoints that sit behind authentication controls must not leak internal system information in error responses — because authentication is a necessary but not sufficient safeguard.
During a routine security review mapped to the OWASP Top 10, the /api/migrate endpoint was identified as returning raw error details in HTTP 500 responses.
The Vulnerability
The route's error handler contained the following pattern:
// Before — UNSAFE
return NextResponse.json(
{ success: false, error: err instanceof Error ? err.message : String(err) },
{ status: 500 }
);
This meant that any unhandled exception — a failed database connection, a missing environment variable, an unexpected file path error — would have its message serialised and returned verbatim to the HTTP caller.
Why this matters
Although the endpoint requires a bearer token, the following risks remained:
- Credential exposure — Database connection strings sometimes appear in driver error messages.
- Path disclosure — File system paths can reveal deployment topology or container layout.
- Stack trace leakage — Detailed error messages can assist an attacker in crafting further exploits.
- Insider / token-holder risk — Even legitimate holders of the bearer token should not receive raw internal diagnostics over the network.
The Fix
The catch block was updated to return a sanitised, static error message while preserving full diagnostic detail in server-side logs:
// After — SAFE
catch (err) {
console.error('[migrate] Migration error:', err);
// optionally: captureError(err);
return NextResponse.json(
{ success: false, error: 'Migration failed. Check server logs for details.' },
{ status: 500 }
);
}
Key properties of the fix:
| Concern | Before | After |
|---|---|---|
| Error detail in HTTP response | Full err.message | Generic static string |
| Server-side logging | Not guaranteed | console.error always called |
| Error monitoring hook | Absent | captureError() optional call added |
| Caller diagnostic value | High (dangerous) | None (intentional) |
| Operator diagnostic value | None | Full — logs retain all detail |
Operator Guidance
If you are operating a self-hosted instance of this platform:
- Update to v1.0.420 or later to receive this fix.
- Review your log aggregation — migration errors will now appear exclusively in server logs. Ensure your logging pipeline captures
console.erroroutput from the API process. - Do not expose
/api/migratepublicly — this endpoint is an internal operations tool and should be firewalled or placed behind a VPN/bastion in production environments, irrespective of bearer token protection. - Rotate bearer tokens if you believe the endpoint was previously called by unintended parties — while raw credentials appearing in error messages would require a specific failure mode to trigger, rotating tokens is a low-cost precaution.
OWASP Reference
This fix addresses A05:2021 — Security Misconfiguration from the OWASP Top 10. Verbose error messages returned to clients are a well-documented misconfiguration class that can facilitate reconnaissance and escalation. See the OWASP A05 entry for further reading.