guidance layer
Secure Defaults
Follow these security rules by default when writing or reviewing code. Deviations require explicit justification in the design artifact.
Input Validation
- Validate and sanitize all external inputs at the system boundary before processing.
- Use an allowlist approach for accepted values when possible; reject unknown inputs.
- Enforce maximum length, type, and format constraints on every input field.
- Never trust client-side validation alone; always validate server-side.
Database and Query Safety
- Use parameterized queries or prepared statements for all database access.
- Never construct SQL, NoSQL, or ORM queries by string concatenation with user input.
- Apply principle of least privilege to database credentials (read-only where writes are not needed).
- Escape identifiers if dynamic table or column names are unavoidable.
Authentication and Authorization
- Hash passwords with a modern adaptive algorithm (bcrypt, scrypt, or argon2) with per-user salts.
- Enforce minimum password complexity or passphrase length per current NIST guidance.
- Implement rate limiting and account lockout on authentication endpoints.
- Check authorization on every request; never rely solely on client-side role checks.
- Use short-lived tokens (JWT, session) with explicit expiration and refresh rotation.
Secrets Management
- Never store secrets (API keys, tokens, passwords, private keys) in source code or config files committed to version control.
- Use environment variables or a dedicated secrets manager for runtime secrets.
- Rotate secrets on a defined schedule and immediately on suspected compromise.
- Log secret access but never log secret values.
Transport and Data Protection
- Use TLS 1.2+ for all network communication; reject plain HTTP in production.
- Encrypt sensitive data at rest using AES-256 or equivalent.
- Set Secure, HttpOnly, and SameSite attributes on all authentication cookies.
- Apply Content-Security-Policy, X-Content-Type-Options, and Strict-Transport-Security headers.
Error Handling and Logging
- Never expose stack traces, internal paths, or database details in user-facing error responses.
- Log errors with sufficient context for debugging but exclude sensitive data (PII, secrets).
- Use structured logging (JSON) with consistent severity levels.
- Return generic error messages to clients; map internal errors to safe public codes.
Dependency Security
- Pin dependency versions and use lock files to ensure reproducible builds.
- Audit dependencies for known vulnerabilities regularly (e.g., npm audit, Snyk, Dependabot).
- Prefer well-maintained packages with active security response teams.
- Remove unused dependencies to reduce attack surface.
Least Privilege and Defense in Depth
- Run services with the minimum permissions required for their function.
- Separate concerns: do not mix admin and user-facing logic in the same process.
- Apply defense in depth: assume any single layer can be bypassed.
- Validate at multiple boundaries (network edge, service boundary, data layer).
File and Resource Handling
- Validate uploaded file types, sizes, and content (not just extensions).
- Store uploaded files outside the web root with randomized names.
- Set restrictive file permissions on sensitive files (0600 for keys, 0644 for config).
- Avoid path traversal: canonicalize paths and reject
..sequences in user input.