security-misconfiguration
SKILL.md
Security Misconfiguration (OWASP A06)
Detect and fix insecure default configurations, missing security headers, exposed debug info, and cloud misconfigurations.
When to Use
- Configuring web servers (Nginx, Apache)
- Setting up cloud resources (AWS, GCP, Azure)
- Deploying applications to production
- Reviewing security headers
- Auditing CORS configuration
- Checking for exposed sensitive endpoints
Common Misconfigurations
| Issue | Risk | Impact |
|---|---|---|
| Debug mode enabled | HIGH | Information disclosure |
| Default credentials | CRITICAL | Full system compromise |
| Missing security headers | MEDIUM | XSS, clickjacking |
| Directory listing | MEDIUM | Information disclosure |
| Verbose error messages | MEDIUM | Attack surface exposure |
| Open cloud storage | CRITICAL | Data breach |
| Unnecessary services | MEDIUM | Increased attack surface |
Detection Patterns
Debug Mode in Production
// VULNERABLE - Debug mode enabled
app.set('env', 'development');
DEBUG=* node app.js
// VULNERABLE - Stack traces in errors
app.use((err, req, res, next) => {
res.status(500).json({
error: err.message,
stack: err.stack // Never in production!
});
});
// VULNERABLE - Source maps in production
// webpack.config.js
devtool: 'source-map' // Exposes source code
Missing Security Headers
// VULNERABLE - No security headers set
app.get('/', (req, res) => {
res.send('<html>...</html>');
});
// Check current headers
curl -I https://example.com
// Missing: X-Frame-Options, CSP, etc.
CORS Misconfiguration
// VULNERABLE - Allow all origins
app.use(cors({
origin: '*',
credentials: true // Dangerous with wildcard!
}));
// VULNERABLE - Reflecting origin
app.use(cors({
origin: req.headers.origin, // Reflects any origin
credentials: true
}));
Cloud Storage Misconfiguration
// VULNERABLE - Public S3 bucket policy
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*"
}]
}
Secure Implementation
1. Security Headers (Express.js)
const helmet = require('helmet');
app.use(helmet({
// Content Security Policy
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'"], // Adjust as needed
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:", "https:"],
connectSrc: ["'self'", "https://api.example.com"],
fontSrc: ["'self'", "https://fonts.gstatic.com"],
objectSrc: ["'none'"],
frameAncestors: ["'none'"],
upgradeInsecureRequests: []
}
},
// Prevent clickjacking
frameguard: { action: 'deny' },
// Prevent MIME type sniffing
noSniff: true,
// XSS filter
xssFilter: true,
// HSTS
hsts: {
maxAge: 31536000,
includeSubDomains: true,
preload: true
},
// Referrer policy
referrerPolicy: { policy: 'strict-origin-when-cross-origin' },
// Permissions policy
permittedCrossDomainPolicies: { permittedPolicies: 'none' }
}));
// Additional headers
app.use((req, res, next) => {
res.setHeader('X-Content-Type-Options', 'nosniff');
res.setHeader('X-Permitted-Cross-Domain-Policies', 'none');
res.setHeader('Permissions-Policy', 'geolocation=(), microphone=(), camera=()');
next();
});
2. CORS Configuration
const cors = require('cors');
const allowedOrigins = [
'https://example.com',
'https://app.example.com',
'https://admin.example.com'
];
app.use(cors({
origin: (origin, callback) => {
// Allow requests with no origin (mobile apps, curl)
if (!origin) return callback(null, true);
if (allowedOrigins.includes(origin)) {
callback(null, true);
} else {
callback(new Error('CORS not allowed'));
}
},
credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization'],
exposedHeaders: ['X-Total-Count'],
maxAge: 86400 // 24 hours
}));
3. Production Error Handling
// Environment-aware error handler
app.use((err, req, res, next) => {
// Log full error for debugging
logger.error('Unhandled error', {
error: err.message,
stack: err.stack,
path: req.path,
method: req.method,
userId: req.user?.id
});
// Send safe response
const statusCode = err.statusCode || 500;
const response = {
error: {
message: statusCode === 500
? 'Internal server error' // Generic message in production
: err.message,
code: err.code || 'UNKNOWN_ERROR',
requestId: req.id // For support tickets
}
};
// Include stack trace only in development
if (process.env.NODE_ENV === 'development') {
response.error.stack = err.stack;
}
res.status(statusCode).json(response);
});
4. Nginx Secure Configuration
server {
listen 443 ssl http2;
server_name example.com;
# SSL Configuration
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# Security Headers
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline';" always;
# Hide server version
server_tokens off;
# Disable directory listing
autoindex off;
# Block access to hidden files
location ~ /\. {
deny all;
}
# Block access to sensitive files
location ~* \.(git|env|config|sql|log|bak|swp)$ {
deny all;
}
# Restrict methods
if ($request_method !~ ^(GET|POST|PUT|DELETE|OPTIONS)$) {
return 405;
}
}
5. AWS S3 Secure Configuration
// Secure S3 bucket policy
const s3BucketPolicy = {
Version: '2012-10-17',
Statement: [
{
Sid: 'DenyPublicAccess',
Effect: 'Deny',
Principal: '*',
Action: 's3:*',
Resource: [
'arn:aws:s3:::my-bucket',
'arn:aws:s3:::my-bucket/*'
],
Condition: {
Bool: {
'aws:SecureTransport': 'false'
}
}
}
]
};
// Block public access settings
const publicAccessBlock = {
BlockPublicAcls: true,
IgnorePublicAcls: true,
BlockPublicPolicy: true,
RestrictPublicBuckets: true
};
# AWS CLI - Block public access
aws s3api put-public-access-block \
--bucket my-bucket \
--public-access-block-configuration \
"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
6. Environment Configuration
// config/index.js - Environment-aware configuration
const config = {
development: {
debug: true,
logLevel: 'debug',
sourceMaps: true,
showErrors: true
},
production: {
debug: false,
logLevel: 'error',
sourceMaps: false,
showErrors: false,
helmet: true,
rateLimit: true
}
};
module.exports = config[process.env.NODE_ENV] || config.production;
7. Docker Security
# Use specific version, not 'latest'
FROM node:20.11-alpine
# Run as non-root user
RUN addgroup -g 1001 appgroup && \
adduser -u 1001 -G appgroup -s /bin/sh -D appuser
WORKDIR /app
# Copy package files first (better caching)
COPY package*.json ./
RUN npm ci --only=production
# Copy application
COPY . .
# Switch to non-root user
USER appuser
# Don't expose unnecessary ports
EXPOSE 3000
# Use exec form, not shell form
CMD ["node", "server.js"]
Security Configuration Checklist
Server Configuration
- Debug mode disabled in production
- Server version headers hidden
- Directory listing disabled
- Default pages removed
- Unnecessary services disabled
- TLS 1.2+ only
- Strong cipher suites
Application Configuration
- Security headers set (CSP, HSTS, etc.)
- CORS properly configured
- Error messages don't leak info
- Source maps disabled in production
- Default credentials changed
- Secrets in environment variables
Cloud Configuration
- S3 buckets not public
- IAM roles use least privilege
- Security groups restrict access
- Logging enabled
- Encryption at rest enabled
Testing Tools
# Check security headers
curl -I https://example.com
# Online header checker
# https://securityheaders.com
# SSL/TLS configuration
# https://www.ssllabs.com/ssltest/
# Check for exposed .git
curl -I https://example.com/.git/HEAD
# Check for directory listing
curl https://example.com/images/
# S3 bucket checker
aws s3 ls s3://bucket-name --no-sign-request
Best Practices
- Use Configuration Management: Ansible, Terraform, etc.
- Automate Security Scans: In CI/CD pipeline
- Environment Separation: Different configs for dev/staging/prod
- Regular Audits: Review configurations periodically
- Principle of Least Privilege: Minimal permissions
- Defense in Depth: Multiple security layers
- Monitor Changes: Alert on configuration changes
Weekly Installs
2
Repository
latestaiagents/…t-skillsGitHub Stars
2
First Seen
Feb 4, 2026
Installed on
mcpjam2
claude-code2
replit2
junie2
windsurf2
zencoder2