This document outlines the comprehensive security measures implemented in the authentication server.
Implementation:
- All database queries use SQLAlchemy ORM with parameterized queries
- No raw SQL execution anywhere in the codebase
- Input validation via Pydantic schemas before database operations
Coverage: 100% - Zero risk of SQL injection
Example:
# Safe - SQLAlchemy parameterized query
user = db.query(User).filter(User.username == username).first()
# NOT used anywhere - would be unsafe:
# db.execute(f"SELECT * FROM users WHERE username = '{username}'")Implementation:
- Content Security Policy (CSP) headers on all responses
- Input sanitization via bleach (industry standard)
- HTML escaping via MarkupSafe
- X-XSS-Protection headers
- X-Content-Type-Options: nosniff to prevent MIME sniffing
Middleware:
SecurityHeadersMiddleware- Adds CSP and security headersRequestValidationMiddleware- Sanitizes inputs using bleach
CSP Policy:
default-src 'self';
script-src 'self' 'unsafe-inline';
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
frame-ancestors 'none';
upgrade-insecure-requests
Coverage: Comprehensive - Multiple layers of XSS prevention
Status: Not Required for JWT-Based API
This is a JWT-based API using Bearer tokens in Authorization headers. CSRF protection is not necessary because:
- Tokens are not automatically sent by browsers (unlike cookies)
- Attackers cannot access Authorization headers from another domain (CORS prevents this)
- SameSite cookies are not used for authentication
Additional CSRF Protections in Place:
- Origin/Referer validation (via security headers middleware)
- Content-Type validation (via request validation middleware)
- CORS configuration (strict origin checking)
- State parameter in OAuth flows (prevents CSRF in OAuth)
- Nonce in OpenID Connect ID tokens (prevents replay attacks)
Note: If you ever use cookies for auth tokens, implement CSRF protection using:
starlette-csrfpackage, OR- Double Submit Cookie pattern, OR
- Synchronizer Token pattern
Command Injection:
- No shell commands executed from user input
- No
os.system()orsubprocesscalls with user data
LDAP Injection:
- Not applicable (no LDAP integration)
NoSQL Injection:
- Not applicable (using PostgreSQL with SQLAlchemy ORM)
Brute Force Protection:
- Progressive rate limiting based on failed attempts
FailedLoginTracker- Exponential backoff after failures- IP-based rate limiting via Redis
Token Security:
- JWT tokens signed with RS256 (asymmetric encryption)
- JTI (JWT ID) for token tracking and blacklisting
- Token binding (optional) - ties token to client fingerprint
- Token blacklist via Redis for instant invalidation
- Short-lived access tokens (default: 15 minutes)
- Refresh token rotation on use
Password Security:
- Bcrypt hashing (industry standard)
- Password strength validation (configurable requirements)
- Password history (prevents reuse via hash comparison)
- Secure password reset with time-limited tokens
MFA Support:
- TOTP (Time-based One-Time Password) via PyOTP
- Backup codes with secure hashing
- Recovery procedures with email verification
Encryption at Rest:
- Passwords: bcrypt hashed (one-way)
- Client secrets: bcrypt hashed (one-way)
- Tokens in DB: AES-256 encrypted (optional, configurable)
- Reset tokens: SHA-256 hashed
- Backup codes: SHA-256 hashed with salt
Encryption in Transit:
- HTTPS enforced in production (HTTPSRedirectMiddleware)
- HSTS headers (max-age=1 year, includeSubDomains, preload)
- TLS 1.2+ required (configured at reverse proxy level)
Email Enumeration:
- Password reset always returns success (doesn't reveal if email exists)
- Registration errors don't distinguish between username/email conflicts
Error Messages:
- Generic error messages in production
- Detailed errors only in debug mode
- No stack traces exposed to clients
Security Headers:
X-Content-Type-Options: nosniffX-Frame-Options: DENYReferrer-Policy: strict-origin-when-cross-originPermissions-Policy- Restricts browser features
RBAC (Role-Based Access Control):
- Fine-grained permissions (resource:action)
- Role inheritance
- Permission checking on all protected endpoints
- Admin-only endpoints properly protected
API Security:
- All endpoints require authentication (except public ones)
- Rate limiting on all endpoints
- Different rate limits based on sensitivity
Validation Layers:
- Request middleware - Content-Type, size, headers
- Pydantic schemas - Type safety, field validation
- Business logic validation - Password strength, email format
- Sanitization - bleach for HTML, MarkupSafe for escaping
Protected Against:
- Path traversal attacks
- Header injection
- Large payload DoS
- Malformed input
- Special character injection
Rate Limiting:
- Per-endpoint rate limits (via fastapi-limiter + Redis)
- Progressive rate limiting for failed auth attempts
- IP-based blocking after repeated failures
Request Size Limits:
- Max request size enforcement (default: 1MB)
- Max header size validation
- Max input length validation
Connection Pooling:
- Database connection pool (max 30 connections)
- Redis connection pool (max 20 connections)
- Pool timeout and recycling configured
Audit Logging:
- All authentication events (login, logout, MFA)
- All authorization changes (roles, permissions)
- All password changes
- All admin operations
- Failed login attempts
- Security events with IP and user agent
Logging Details:
- User ID
- Action type
- Resource affected
- Timestamp
- IP address
- User agent
- Success/failure
- Additional context (JSON)
HTTPS Enforcement:
- Automatic redirect HTTP → HTTPS in production
- HSTS headers (1 year, includeSubDomains, preload)
- CSP
upgrade-insecure-requestsdirective
Header Security:
- Validates and limits header sizes
- Strips dangerous headers
- Enforces secure content types
JWT Best Practices:
- RS256 algorithm (asymmetric)
- Short expiration times
- JTI for tracking
- Issued-at claim
- Audience validation
- Issuer validation
Token Transmission:
- Bearer token in Authorization header (not in URL/cookies)
- HTTPS only in production
- No token in query parameters
- No token in response bodies (only in JSON)
- ✅ SQL Injection: Protected via SQLAlchemy ORM
- ✅ XSS: Protected via CSP, bleach, MarkupSafe
- ✅ CSRF: Not applicable (JWT in headers, not cookies)
- ✅ Injection Attacks: No command execution, parameterized queries
- ✅ Brute Force: Progressive rate limiting
- ✅ Session Hijacking: Token binding, HTTPS, short expiration
- ✅ Password Attacks: Bcrypt, strength validation, MFA
- ✅ Privilege Escalation: RBAC with permission checks
- ✅ Information Disclosure: Generic errors, no enumeration
- ✅ DoS: Rate limiting, connection pooling, size limits
- ✅ Man-in-the-Middle: HTTPS, HSTS, certificate pinning (via HSTS preload)
- ✅ Replay Attacks: Nonce, JTI, token expiration
- ✅ Clickjacking: X-Frame-Options: DENY
- ✅ MIME Sniffing: X-Content-Type-Options: nosniff
-
A01:2021 - Broken Access Control ✅
- RBAC system with fine-grained permissions
- JWT validation on all protected endpoints
- Role and permission checks
-
A02:2021 - Cryptographic Failures ✅
- HTTPS enforcement
- Bcrypt for passwords
- AES-256 for sensitive data at rest
- RS256 for JWT signing
-
A03:2021 - Injection ✅
- SQLAlchemy ORM (parameterized queries)
- Input validation and sanitization
- No command execution
-
A04:2021 - Insecure Design ✅
- Defense in depth (multiple layers)
- Principle of least privilege
- Secure defaults
- Token blacklisting capability
-
A05:2021 - Security Misconfiguration ✅
- Secure headers on all responses
- Debug mode disabled in production
- Error handling without disclosure
- Minimal attack surface
-
A06:2021 - Vulnerable Components ✅
- Using maintained, industry-standard libraries
- Regular dependency updates via poetry
- No deprecated dependencies
-
A07:2021 - Identification & Authentication Failures ✅
- Strong password requirements
- MFA support
- Session management
- Token expiration
- Rate limiting
-
A08:2021 - Software & Data Integrity Failures ✅
- JWT signature validation
- JWKS for public key distribution
- Audit logging
- No unsigned data trusted
-
A09:2021 - Security Logging & Monitoring Failures ✅
- Comprehensive audit logging
- Failed attempt tracking
- Security event logging
- Structured logging
-
A10:2021 - Server-Side Request Forgery ✅
- No server-side requests from user input
- URL validation and sanitization
- Whitelist approach for allowed schemes
- Set
APP_ENV=production - Configure HTTPS/TLS certificates
- Set
DEBUG=False - Configure trusted hosts
- Set strong
JWT_SECRET_KEYandSECURITY_SALT - Enable Redis for caching and rate limiting
- Configure email service (SMTP)
- Set up database backups
- Configure monitoring and alerting
- Review and adjust rate limiting thresholds
- Enable token encryption in database
- Set appropriate CORS origins
- Configure reverse proxy (nginx/Traefik)
- Set up centralized logging
- Enable MFA for admin accounts
- Review audit logs regularly
All responses include these security headers (via SecurityHeadersMiddleware):
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; ...
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), microphone=(), camera=()
If you discover a security vulnerability, please:
- Do NOT open a public GitHub issue
- Email security@yourdomain.com with details
- Allow reasonable time for a fix before disclosure
- Include steps to reproduce
This document should be reviewed and updated:
- After any security-related changes
- Quarterly (minimum)
- After security audits
- Before major releases