After this lesson, you will be able to: Apply the core secure-development principles that cut across every vulnerability class: defense in depth, least privilege, secure by default, input validation, secrets management, dependency auditing, and code review.
Individual fixes patch individual bugs. These principles prevent whole classes of them. This lesson collects the security best practices a professional developer applies on every project, the habits that make insecure code the exception rather than the default.
Defense in depth: layer controls so no single failure is fatal (WAF + input validation + parameterized queries + least-privilege DB user all guard against injection). Least privilege: every user, service, and credential gets the minimum access needed, nothing more (the Capital One IAM role should never have had broad S3 access). Secure by default: the safe configuration is the out-of-the-box one; security is opt-out, not opt-in. Fail securely: when something errors, deny rather than allow. These principles are why a single mistake does not become a breach.
Never trust input; encode for the context you output into.
// VALIDATE input against an allow-list (what's permitted), not a deny-listconst schema = z.object({email: z.string().email(),age: z.number().int().min(13).max(120),role: z.enum(['student', 'tutor']), // only these are valid});const data = schema.parse(req.body); // reject anything else, fail closed// ENCODE output for its destination context:// - HTML body: HTML-encode (prevents XSS)// - SQL: parameterized queries / prepared statements (prevents injection)// - shell: avoid; if unavoidable, use arg arrays, never string concat// Rule: validate on input, encode on output, and do both on the server.
Two habits that prevent a large share of real breaches.
Secrets: never hardcode API keys, passwords, or tokens in source or commit them to git.
Load secrets from environment variables or a secrets manager (Vault, AWS Secrets Manager, cloud KMS).
Rotate secrets regularly and immediately if one leaks; scan repos for committed secrets (git-secrets, truffleHog).
Dependencies: run npm audit / pip-audit and enable Dependabot/Renovate so known CVEs surface automatically.
Pin versions with lockfiles and remove unused dependencies (less code, fewer CVEs).
Gate CI on High/Critical findings so a vulnerable dependency fails the build.
Security-focused review catches what scanners miss. On every pull request, ask: Is all user input validated and output encoded? Are database queries parameterized? Does every endpoint check authentication AND authorization (ownership + role)? Are secrets kept out of the code and logs? Are errors generic to the user and detailed only in server logs? Are new dependencies necessary and audited? Are security-relevant events logged? Treat a 'no' to any of these as a blocking comment, the same as a failing test.
Pick the best answer.
Sign in and purchase access to unlock this lesson.