Security Rules

OWASP Alignment

  • Follow the OWASP Top 10:2025 — the 2021 version is superseded
  • Pay special attention to A02 (Security Misconfiguration) and A03 (Software Supply Chain Failures) — both were elevated in 2025
  • Follow the OWASP API Security Top 10 for all API endpoints — API-specific vulnerabilities (BOLA, mass assignment) are distinct from web vulnerabilities

Secret Management

  • Never hardcode secrets, API keys, tokens, or credentials in source code — a single leaked key can compromise entire systems

BAD: const API_KEY = "sk-abc123..." in source code GOOD: const API_KEY = process.env.API_KEY loaded at runtime

  • Use environment variables or secret managers for all sensitive configuration
  • Add .env files to .gitignore — never commit them
  • Rotate secrets immediately if exposed in version control — automated scanners find leaked keys within minutes

Secrets Scanning

  • Run a secrets scanner (Gitleaks or TruffleHog) as a pre-commit hook — catching secrets before push is the cheapest mitigation
  • Run the same scanner in CI as a required check on pull requests — pre-commit hooks can be bypassed
  • Scan the full git history periodically, not just the latest diff — secrets deleted from HEAD remain in git history indefinitely

Input Validation

  • Validate and sanitize ALL user input at system boundaries — prevents injection attacks and data corruption

BAD: db.query("SELECT * FROM users WHERE id = " + userId) GOOD: db.query("SELECT * FROM users WHERE id = $1", [userId])

  • Use parameterized queries to prevent SQL injection
  • Escape output to prevent XSS (cross-site scripting)
  • Validate file uploads: check type, size, and content — malicious uploads can execute server-side code
  • Validate and allowlist all URLs that the server fetches on behalf of users — SSRF lets attackers reach internal services and cloud metadata endpoints
  • Block requests to internal IP ranges (169.254.x, 10.x, 172.16-31.x, 192.168.x) from server-side URL fetching
  • Never deserialize untrusted data with general-purpose deserializers — use schema-validated formats (JSON with Zod/Joi, not pickle/yaml.load)

Authentication & Authorization

  • Offer passkeys (WebAuthn/FIDO2) as the primary authentication method — they are phishing-resistant by design and eliminate credential stuffing
  • Use phishing-resistant MFA for privileged accounts — NIST SP 800-63-4 (2025) requires it for AAL2
  • When passwords are used: bcrypt or Argon2id, minimum 12 characters, check against breach databases (HaveIBeenPwned API)
  • Store session tokens in HttpOnly, Secure, SameSite=Lax cookies — never in localStorage
  • Protect authentication endpoints with rate limiting and CAPTCHAs — prevents brute-force and credential-stuffing attacks
  • Enforce RLS (Row Level Security) and RBAC from day one on all sensitive data — retrofitting access control is error-prone
  • Apply principle of least privilege for all access control — users and services should only access what they need
  • Enforce object-level authorization on every API endpoint that accesses a resource by ID — BOLA is the #1 API vulnerability

API Security

  • Never return more fields than the client needs — excessive data exposure leaks sensitive information even through authorized endpoints
  • Use allowlists for mass assignment — explicitly define which fields are writable; never bind request bodies directly to models

BAD: Object.assign(user, req.body) — allows overwriting role, isAdmin, or any field GOOD: const { name, email } = req.body; user.update({ name, email }) — explicit allowlist

  • Validate and sanitize data from third-party APIs with the same rigor as user input
  • Implement rate limiting on all public endpoints — return X-RateLimit-Limit and X-RateLimit-Remaining headers

Security Headers

  • Set Content-Security-Policy to restrict script sources — CSP is the primary defense against XSS after output encoding
  • Set Strict-Transport-Security with max-age=31536000 and includeSubDomains — prevents protocol downgrade attacks
  • Always send X-Content-Type-Options: nosniff — prevents MIME-sniffing attacks
  • Set Referrer-Policy: strict-origin-when-cross-origin — limits information leakage
  • Use Permissions-Policy to disable unused browser features (camera, microphone, geolocation)
  • Never set Access-Control-Allow-Origin to * with credentials — this disables CORS protections entirely

Security Misconfiguration

  • Disable debug mode, verbose error pages, and stack traces in production — they reveal internal architecture to attackers
  • Remove or disable all default accounts and credentials before deployment
  • Review framework and library default configurations — secure defaults are not universal; verify each one
  • Automate configuration auditing in CI — drift from secure baselines should block deployment

AI-Generated Code Security

  • Review ALL AI-generated code with the same rigor as third-party code — AI models reproduce insecure patterns from training data
  • Never embed user-controlled input directly into LLM prompts — prompt injection is the #1 LLM vulnerability (OWASP LLM01:2025)
  • Validate and sanitize ALL LLM outputs before using them in downstream systems (SQL, shell, HTML)
  • Do not grant LLM agents access to credentials, databases, or admin APIs without strict sandboxing and least-privilege scoping

BAD: exec(llm_response) or db.query(llm_generated_sql) GOOD: Parse LLM output into a typed schema, validate against allowlist, then execute through parameterized interfaces

Supply Chain Security

  • Generate SBOMs (Software Bill of Materials) for all releases — required by EU CRA and US federal contracts
  • Sign artifacts using Sigstore/Cosign or equivalent — unsigned artifacts cannot be verified as authentic
  • Target SLSA Level 2 minimum: cryptographically signed provenance generated by the build system
  • Use lockfiles AND verify integrity hashes — lockfiles without hash verification still allow tampering
  • Audit dependencies regularly for known vulnerabilities — each dependency is an attack surface
  • Pin dependency versions and remove unused dependencies promptly

Container & Cloud Security

  • Use minimal base images (distroless or Alpine) — smaller images have fewer vulnerabilities
  • Run containers as non-root — a compromised process with root can escape the container
  • Scan container images in CI before deployment — block images with critical or high CVEs
  • Follow least-privilege for cloud IAM — no wildcard permissions, scope to specific resources and actions
  • Never use default credentials or leave management ports publicly accessible
  • Enable cloud provider audit logging from day one — you cannot investigate what you did not log

Code Trust

  • Treat all generated or external code as untrusted — perform strict validation before using
  • Never trust client-side validation alone — always validate server-side

General

  • Log security events without exposing sensitive data — logs themselves can become a leak vector
  • Use HTTPS for all external communications
  • Implement proper error handling that does not leak internal details