Security Fundamentals
Stack-agnostic security principles and practices for building secure applications.
Core Principles
1. Defense in Depth
code
Never rely on a single security measure. Layers: - Network (firewalls, VPNs) - Infrastructure (hardening, least privilege) - Application (validation, authentication) - Data (encryption, access control)
2. Least Privilege
code
Grant minimum required permissions. Examples: - Database users: Only necessary tables - API tokens: Only needed scopes - File permissions: Only required access - IAM roles: Specific actions only
3. Fail Secure
code
When in doubt, deny access.
Example:
if (!hasPermission(user, resource)) {
return DENIED; // Fail closed
}
4. Input Validation
code
Never trust input from untrusted sources. Validate at: - API boundaries (external input) - Service boundaries (inter-service calls) - Database boundaries (before queries)
OWASP Top 10 Quick Reference
| # | Vulnerability | Prevention |
|---|---|---|
| A01 | Broken Access Control | Auth checks on every request |
| A02 | Cryptographic Failures | Strong encryption, no secrets in code |
| A03 | Injection | Parameterized queries, input validation |
| A04 | Insecure Design | Threat modeling, secure defaults |
| A05 | Security Misconfiguration | Hardened defaults, minimal footprint |
| A06 | Vulnerable Components | Dependency updates, audits |
| A07 | Auth Failures | Strong passwords, MFA, rate limiting |
| A08 | Data Integrity | Signature verification, secure CI/CD |
| A09 | Logging Failures | Comprehensive logging, no PII in logs |
| A10 | SSRF | URL validation, allowlists |
Secret Management
Never Hardcode Secrets
code
BAD: api_key = "sk-1234567890abcdef" database_url = "postgres://user:password@host/db" GOOD: api_key = os.environ["API_KEY"] database_url = os.environ["DATABASE_URL"]
Environment Files
code
# .env.example (commit this) API_KEY=your-api-key-here DATABASE_URL=postgres://user:pass@localhost/db # .env (NEVER commit) API_KEY=sk-actual-secret-key DATABASE_URL=postgres://real:secret@prod/db
.gitignore Pattern
gitignore
# Environment files .env .env.local .env.*.local .env.production # Secrets *.pem *.key *.p12 secrets/ credentials.json
Input Validation Patterns
Allowlist vs Denylist
code
PREFER ALLOWLIST: - Define what IS allowed - Reject everything else AVOID DENYLIST: - Trying to block bad input - Always incomplete
Validation Schema Pattern
code
Define schema: - Type constraints - Length limits - Format patterns - Required fields Validate: - Parse input against schema - Reject if invalid - Use validated data only
Authentication Security
Password Requirements
code
Modern recommendations: - Minimum 12 characters - No composition rules (upper/lower/number/special) - Check against breach databases - Use bcrypt/argon2/scrypt (not MD5/SHA1)
Session Security
code
Cookie attributes: - HttpOnly: Prevent XSS access - Secure: HTTPS only - SameSite: CSRF protection - Short expiration
Token Best Practices
code
Access tokens: - Short expiration (15-60 minutes) - Minimal claims - Validate on every request Refresh tokens: - Longer expiration - Rotate on use - Store securely
Authorization Patterns
Check on Every Request
code
Pattern: 1. Authenticate user 2. Load resource 3. Check permission 4. Return or deny NEVER: - Rely on URL obscurity - Trust client-side checks - Cache permissions without invalidation
Resource-Level Checks
code
Example: 1. User requests /documents/123 2. Load document 123 3. Verify user.id == document.owner_id OR user.isAdmin 4. Return document or 403
Logging Security
What to Log
- •Authentication attempts (success and failure)
- •Authorization failures
- •Input validation failures
- •System errors (sanitized)
- •Configuration changes
What NOT to Log
- •Passwords (even hashed)
- •API keys or tokens
- •PII (names, emails, addresses)
- •Credit card numbers
- •Session tokens
Dependency Security
Regular Audits
Each ecosystem has standard dependency audit tools. Use the security-auditor agent or stack-detector skill to identify the appropriate commands for your stack.
Audit checklist:
- •Known CVEs in dependencies
- •Outdated packages with security patches
- •Transitive dependency vulnerabilities
- •License compliance (if required)
Update Strategy
code
1. Monitor for vulnerabilities 2. Test updates in CI 3. Apply security patches promptly 4. Schedule regular dependency updates
Rules (L1 - Hard)
Security rules are L1 by default. These prevent vulnerabilities and data breaches.
- •NEVER hardcode secrets (use environment variables or secret managers)
- •ALWAYS validate untrusted input at all boundaries
- •NEVER trust client-side validation alone (always validate server-side)
- •ALWAYS use parameterized queries (prevent SQL injection)
- •NEVER log sensitive data (passwords, tokens, PII)
- •ALWAYS hash passwords with strong algorithms (bcrypt, argon2, scrypt)
Defaults (L2 - Soft)
Important practices that may have context-specific exceptions.
- •Expose stack traces only in development, never in production
- •Keep dependencies updated (balance security vs stability)
- •Use HTTPS for all external communications
- •Implement rate limiting on authentication endpoints
Guidelines (L3)
Recommendations that improve security posture.
- •Consider implementing Content Security Policy (CSP)
- •Prefer allowlist over denylist for input validation
- •Consider using security headers (HSTS, X-Frame-Options)
- •Review OWASP Top 10 periodically for new vulnerabilities