Development conveniences left enabled in production — debug modes, verbose stack traces in error responses, wildcard CORS, authentication bypasses — are a class of security misconfiguration documented by CWE-1188 (Insecure Default Initialization) and OWASP A05 (Security Misconfiguration). NIST 800-53 CM-6 requires baseline configurations to be documented and enforced. A /api/debug/users route that bypasses auth and returns all user records, or a productionBrowserSourceMaps: true setting that ships full TypeScript source to browsers, represents a failure mode that is easy to introduce during development and easy to forget to remove.
Low because insecure defaults don't directly expose data, but they reduce the attacker's effort — verbose errors disclose internals, and disabled auth checks provide direct access.
Gate all development conveniences behind explicit NODE_ENV checks and set secure defaults unconditionally in next.config.ts:
// next.config.ts
export default {
productionBrowserSourceMaps: false, // No source maps shipped to browsers
poweredByHeader: false, // Don't advertise Next.js version
}
// Remove or gate development middleware:
if (process.env.NODE_ENV === 'development') {
app.use(require('morgan')('dev'))
}
// Default-deny for protected routes:
const PUBLIC_ROUTES = new Set(['/api/auth/login', '/api/health'])
if (!PUBLIC_ROUTES.has(req.path) && !req.user) {
return res.status(401).json({ error: 'Unauthorized' })
}
Search for if (process.env.NODE_ENV !== 'production') — any security bypass inside that block is a vulnerability.
ID: security-hardening.dependency-security.secure-defaults
Severity: low
What to look for: List all production configuration settings (debug mode, verbose errors, dev tools, mock auth). For each, check for debug flags, development mode settings, and default credentials that might be active in production. Look for debug: true in production configuration, default admin passwords documented in README or code comments, development middleware (CORS wildcard, verbose logging) that might be active in production, and disabled authentication for convenience that was never re-enabled.
Pass criteria: Debug mode is disabled in production. No default or documented credentials accepted in production. Development middleware is gated behind environment checks. Authentication is required by default for protected routes — 100% of settings must use secure values in production (debug disabled, verbose errors off). Report: "X production settings verified, all Y use secure defaults."
Fail criteria: Debug mode enabled unconditionally. Default admin credentials accepted. Development shortcuts (skip auth, accept any CORS origin) active in production.
Skip (N/A) when: Never — secure defaults apply to all production applications.
Detail on fail: "next.config.ts has productionBrowserSourceMaps: true — full source maps served in production" or "Debug endpoint /api/debug/users returns all user data without auth check"
Remediation: Gate all development conveniences behind explicit environment checks:
// next.config.ts
const nextConfig = {
productionBrowserSourceMaps: false, // No source maps in production
poweredByHeader: false, // Don't advertise Next.js version
}
// Development-only middleware
if (process.env.NODE_ENV === 'development') {
app.use(require('morgan')('dev')) // Verbose logging in dev only
}
// Require explicit opt-in for public routes
const isPublicRoute = PUBLIC_ROUTES.has(req.path)
if (!isPublicRoute && !req.user) return res.status(401).json({ error: 'Unauthorized' })