Security Headers for Defense in Depth
Security Headers for Defense in Depth
Security headers provide browser-enforced protections that complement server-side SQL injection defenses:
# Nginx configuration with comprehensive security headers
server {
listen 443 ssl http2;
server_name api.example.com;
# Content Security Policy - Prevents XSS that could lead to SQL injection
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://trusted-cdn.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; connect-src 'self' https://api.example.com; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; report-uri /csp-report" always;
# Prevent clickjacking attacks that might trick users into submitting malicious data
add_header X-Frame-Options "DENY" always;
# Disable MIME type sniffing
add_header X-Content-Type-Options "nosniff" always;
# Enable XSS protection (though modern browsers have this by default)
add_header X-XSS-Protection "1; mode=block" always;
# Referrer Policy to prevent leaking sensitive URLs
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Permissions Policy (formerly Feature Policy)
add_header Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=(), usb=(), magnetometer=(), accelerometer=(), gyroscope=()" always;
# Custom security headers for API protection
add_header X-API-Version "2.0" always;
add_header X-RateLimit-Limit "1000" always;
# HSTS to ensure HTTPS usage
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
}
Implement application-level security headers:
# Flask application with security headers
from flask import Flask, request, jsonify, make_response
from functools import wraps
import hashlib
import hmac
app = Flask(__name__)
def add_security_headers(response):
"""Add security headers to all responses"""
response.headers['X-Content-Type-Options'] = 'nosniff'
response.headers['X-Frame-Options'] = 'DENY'
response.headers['X-XSS-Protection'] = '1; mode=block'
response.headers['Referrer-Policy'] = 'strict-origin-when-cross-origin'
# Add CSP with nonce for inline scripts
nonce = generate_nonce()
response.headers['Content-Security-Policy'] = f"default-src 'self'; script-src 'self' 'nonce-{nonce}'"
# Custom headers for API protection
response.headers['X-Request-ID'] = generate_request_id()
response.headers['X-RateLimit-Remaining'] = str(get_rate_limit_remaining(request))
return response
@app.after_request
def after_request(response):
return add_security_headers(response)
# API endpoint with additional injection protection
@app.route('/api/data', methods=['POST'])
@validate_api_signature # Custom decorator to verify request signatures
def secure_api_endpoint():
# Verify Content-Type to prevent injection via wrong parsing
if request.content_type != 'application/json':
return jsonify({'error': 'Invalid Content-Type'}), 400
# Size limit to prevent large payload attacks
if request.content_length > 1024 * 100: # 100KB limit
return jsonify({'error': 'Payload too large'}), 413
# Process request safely
try:
data = request.get_json(force=False)
# ... process with parameterized queries
except Exception as e:
logger.error(f"Request processing failed: {e}")
return jsonify({'error': 'Invalid request'}), 400