Defense in Depth: Least Privilege, Secrets & Dependencies
Least Privilege
Grant only the minimum access a component actually needs — an app's DB user should have SELECT/INSERT/UPDATE on specific tables, not full admin rights, limiting damage if that credential leaks.
Secrets Management
Never commit API keys/passwords to source control — git history retains old commits even after a later commit removes the secret. Use environment variables or a dedicated secrets manager. A leaked secret should be treated as compromised and rotated, not just deleted from the current code.
Server-Side Validation & Rate Limiting
Client-side validation is UX only — it can always be bypassed by a direct API call. Server-side validation is the actual security boundary. Rate limiting (especially on login endpoints) slows brute-force and credential-stuffing attempts.
Dependencies & Supply Chain
Outdated dependencies with known, publicly disclosed vulnerabilities are an active target — run npm audit / Dependabot / Snyk regularly. A supply-chain attack compromises a trusted upstream package itself, spreading to every project that installs the compromised version — pin versions and use lockfiles to reduce exposure.
CSP, CORS & Error Handling
Content-Security-Policy restricts which sources can execute — defense-in-depth even if an XSS injection slips through. CORS: avoid Access-Control-Allow-Origin: * on endpoints returning authenticated/sensitive data. Show generic errors to users, log full stack traces server-side only — detailed errors handed to attackers are free reconnaissance.
Don't Roll Your Own Crypto
Use established, publicly-vetted algorithms (AES, bcrypt) — cryptography is notoriously easy to get subtly wrong even for experienced developers, and a custom scheme lacks the years of scrutiny established algorithms have survived.
Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free