Configuration vulnerabilities occur when applications are improperly configured, potentially exposing sensitive information or creating security weaknesses.
Use this file to discover all available pages before exploring further.
Configuration Vulnerabilities Overview
Configuration vulnerabilities arise when applications, frameworks, or systems are set up with insecure default settings or improper configurations. These vulnerabilities can create security weaknesses that attackers can exploit, even if the application code itself is secure.Proper configuration management is essential for maintaining security throughout the application lifecycle. This includes secure default settings, proper environment configuration, and regular security reviews of configuration changes.
Hardcoded credentials in source code are easily discoverable, especially in open-source projects or when source code is leaked.To avoid hardcoded credentials:
Use environment variables for sensitive configuration
Implement a secure configuration management system
Use secrets management services (AWS Secrets Manager, HashiCorp Vault)
Implement proper access controls for configuration files
Regularly rotate credentials
Use different credentials for different environments
Insecure default configurations can leave applications vulnerable to various attacks if not properly hardened.To implement secure configurations:
Review and harden default settings
Use security-focused middleware (like Helmet for Express)
Set appropriate size limits for requests
Configure secure cookie attributes
Disable unnecessary features and modules
Implement proper CORS configuration
Regularly update and review security configurations
Exposed Configuration Files
# Anti-pattern: Exposed configuration files in Apache<Directory /var/www/html> Options Indexes FollowSymLinks AllowOverride None Require all granted</Directory># Better approach: Protecting configuration files<Directory /var/www/html> Options FollowSymLinks AllowOverride None Require all granted</Directory># Block access to configuration files<FilesMatch "\.(env|config|ini|json|xml|yml|yaml)$"> Require all denied</FilesMatch>
Exposed configuration files can reveal sensitive information like database credentials, API keys, or internal infrastructure details.To protect configuration files:
Store configuration files outside the web root
Use appropriate file permissions
Block access to configuration files via web server rules
Verbose error messages can reveal sensitive information about the application’s internal workings, database structure, or system configuration.To implement proper error message configuration:
Configure different error handling for development and production
Log detailed errors server-side
Return generic error messages to users in production
Implement proper error handling middleware
Consider using error tracking services
Regularly review error logs for sensitive information
Insecure Cross-Origin Resource Sharing (CORS)
// Anti-pattern: Insecure CORS configurationapp.use(cors({ origin: '*', // Allow all origins credentials: true}));// Better approach: Secure CORS configurationconst allowedOrigins = [ 'https://example.com', 'https://www.example.com', 'https://app.example.com'];// For development environment onlyif (process.env.NODE_ENV === 'development') { allowedOrigins.push('http://localhost:3000');}app.use(cors({ origin: function(origin, callback) { // Allow requests with no origin (like mobile apps or curl requests) if (!origin) return callback(null, true); if (allowedOrigins.indexOf(origin) === -1) { const msg = 'The CORS policy for this site does not allow access from the specified Origin.'; return callback(new Error(msg), false); } return callback(null, true); }, methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], allowedHeaders: ['Content-Type', 'Authorization'], credentials: true, maxAge: 86400 // 24 hours}));
Insecure CORS configuration can allow unauthorized websites to make requests to your API, potentially leading to data theft or unauthorized actions.To implement secure CORS:
Insecure HTTP headers can make applications vulnerable to various attacks, including cross-site scripting, clickjacking, and information disclosure.To implement secure HTTP headers:
Use security-focused middleware (like Helmet)
Implement Content Security Policy (CSP)
Enable HTTP Strict Transport Security (HSTS)
Configure X-Content-Type-Options
Set X-Frame-Options to prevent clickjacking
Implement Referrer-Policy
Configure Feature-Policy/Permissions-Policy
Regularly test and update security headers
Excessive Permissions
// Anti-pattern: Excessive permissions in database configuration// Database user with excessive privilegesconst dbConfig = { host: process.env.DB_HOST, user: process.env.DB_USER, // User with all privileges password: process.env.DB_PASSWORD, database: process.env.DB_NAME};// Better approach: Least privilege principle// Read-only database configurationconst readOnlyDbConfig = { host: process.env.DB_HOST, user: process.env.DB_READ_USER, // User with read-only privileges password: process.env.DB_READ_PASSWORD, database: process.env.DB_NAME};// Write database configurationconst writeDbConfig = { host: process.env.DB_HOST, user: process.env.DB_WRITE_USER, // User with specific write privileges password: process.env.DB_WRITE_PASSWORD, database: process.env.DB_NAME};// Use appropriate connection based on operationfunction getUser(userId) { const connection = mysql.createConnection(readOnlyDbConfig); // Query user data...}function updateUser(userId, userData) { const connection = mysql.createConnection(writeDbConfig); // Update user data...}
Excessive permissions can amplify the impact of security breaches, allowing attackers to gain more access than necessary if a vulnerability is exploited.To implement least privilege principle:
Create separate accounts for different functions
Grant only necessary permissions
Use read-only access when possible
Implement proper role-based access control
Regularly audit and review permissions
Revoke unnecessary permissions
Use different credentials for different environments
Unnecessary services and features can increase the attack surface of an application, providing additional vectors for attackers to exploit.To minimize attack surface:
Disable unnecessary features and modules
Remove unused dependencies
Implement proper HTTP method restrictions
Disable directory listing
Remove unnecessary headers that reveal system information
Insecure file upload configuration can lead to various vulnerabilities, including code execution, path traversal, or denial-of-service attacks.To implement secure file uploads:
Store uploaded files outside the web root
Generate secure random filenames
Validate file types and content
Implement file size limits
Use proper file permissions
Scan uploaded files for malware
Serve files through a controlled endpoint
Consider using a CDN or dedicated file storage service
Improper Cache Control
// Anti-pattern: Missing cache control headersapp.get('/api/user-profile', authenticateUser, (req, res) => { getUserProfile(req.user.id) .then(profile => res.json(profile)) .catch(err => res.status(500).json({ error: err.message }));});// Better approach: Proper cache control configurationapp.get('/api/user-profile', authenticateUser, (req, res) => { // Set cache control headers for sensitive data res.set({ 'Cache-Control': 'private, no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' }); getUserProfile(req.user.id) .then(profile => res.json(profile)) .catch(err => res.status(500).json({ error: err.message }));});// For public, cacheable contentapp.get('/api/public-data', (req, res) => { // Allow caching for public data res.set({ 'Cache-Control': 'public, max-age=3600', // Cache for 1 hour 'Expires': new Date(Date.now() + 3600000).toUTCString() }); getPublicData() .then(data => res.json(data)) .catch(err => res.status(500).json({ error: err.message }));});
Improper cache control can lead to sensitive information being stored in browser caches or proxies, potentially exposing it to unauthorized users.To implement proper cache control:
Set appropriate cache control headers based on content sensitivity
Prevent caching of sensitive information
Use appropriate caching directives for public content
Consider implementing cache partitioning
Be aware of proxy caching behavior
Implement proper cache invalidation strategies
Regularly test caching behavior
Insecure Dependency Configuration
// Anti-pattern: Insecure dependency configuration// package.json with no version pinning{ "dependencies": { "express": "^4.17.1", "mongoose": "^5.9.7", "jsonwebtoken": "^8.5.1" }}// Better approach: Secure dependency configuration// package.json with exact version pinning{ "dependencies": { "express": "4.17.1", "mongoose": "5.9.7", "jsonwebtoken": "8.5.1" }, "scripts": { "audit": "npm audit", "outdated": "npm outdated", "update": "npm update" }}// Even better: Using lock files// package-lock.json or yarn.lock should be committed to version control
Insecure dependency configuration can lead to unexpected behavior, compatibility issues, or security vulnerabilities if dependencies are automatically updated to versions with security issues.To implement secure dependency management:
Pin dependency versions to specific releases
Use lock files to ensure consistent installations
Regularly audit dependencies for vulnerabilities
Update dependencies in a controlled manner
Consider using dependency scanning tools
Implement continuous monitoring for vulnerable dependencies
Have a process for emergency updates when critical vulnerabilities are discovered
Insufficient Rate Limiting
// Anti-pattern: No rate limitingapp.post('/api/login', (req, res) => { // No rate limiting for authentication authenticateUser(req.body.username, req.body.password) .then(user => { if (user) { return res.json({ token: generateToken(user) }); } res.status(401).json({ error: 'Invalid credentials' }); }) .catch(err => res.status(500).json({ error: err.message }));});// Better approach: Implementing rate limitingconst rateLimit = require('express-rate-limit');// Create different rate limiters for different endpointsconst loginLimiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 5, // 5 requests per windowMs per IP standardHeaders: true, legacyHeaders: false, message: 'Too many login attempts, please try again after 15 minutes'});const apiLimiter = rateLimit({ windowMs: 60 * 1000, // 1 minute max: 60, // 60 requests per minute per IP standardHeaders: true, legacyHeaders: false, message: 'Too many requests, please try again later'});// Apply rate limiters to specific routesapp.post('/api/login', loginLimiter, (req, res) => { authenticateUser(req.body.username, req.body.password) .then(user => { if (user) { return res.json({ token: generateToken(user) }); } res.status(401).json({ error: 'Invalid credentials' }); }) .catch(err => res.status(500).json({ error: err.message }));});// Apply general rate limiting to all API routesapp.use('/api/', apiLimiter);
Insufficient rate limiting can make applications vulnerable to brute force attacks, credential stuffing, denial-of-service attacks, or resource exhaustion.To implement proper rate limiting:
Apply stricter limits for authentication endpoints
Implement different limits for different types of resources
Consider using IP-based and user-based rate limiting
Implement proper response headers for rate limiting
Use appropriate time windows for different endpoints
Consider implementing progressive delays
Monitor for rate limit violations and potential attacks
Debug mode in production can expose sensitive information, internal system details, or debugging endpoints that should not be accessible in a production environment.To implement proper debug configuration:
Disable debug mode in production environments
Use environment variables to control debug settings