๐Ÿ”ด Advanced22 min readยทUpdated Feb 18, 2026

Developer Security Checklist: Building Secure Applications

A comprehensive security checklist for developers. Covers OWASP Top 10, secrets management, dependency security, API security, and more.

The OWASP Top 10 lists the most critical web application security risks.

1. Broken Access Control

  • Users accessing other users' data by changing IDs in URLs
  • Missing function-level access checks
  • Fix: Deny by default, implement RBAC, test authorization rules
  • 2. Cryptographic Failures

  • Storing passwords in plaintext or weak hashes
  • Using HTTP instead of HTTPS
  • Fix: Use Argon2id for passwords, TLS 1.3 everywhere, encrypt sensitive data at rest
  • 3. Injection

  • SQL, NoSQL, OS, LDAP injection
  • Fix: Parameterized queries, ORMs, input validation, WAF
  • 4. Insecure Design

  • Missing threat modeling and security architecture
  • Fix: Threat model early, use secure design patterns, abuse case testing
  • 5. Security Misconfiguration

  • Default credentials, unnecessary features, verbose errors
  • Fix: Hardened configs, automated security scanning, principle of least privilege
  • 6. Vulnerable Components

  • Using libraries with known vulnerabilities
  • Fix: Dependabot/Renovate, npm audit, regular updates
  • 7. Authentication Failures

  • Weak password policies, credential stuffing, session fixation
  • Fix: Strong password policies, rate limiting, 2FA, secure session management
  • 8. Data Integrity Failures

  • Insecure deserialization, untrusted CI/CD pipelines
  • Fix: Verify software integrity, signed artifacts, secure pipeline
  • 9. Logging & Monitoring Failures

  • Not logging security events, no alerting
  • Fix: Log auth events, detect anomalies, incident response plan
  • 10. Server-Side Request Forgery (SSRF)

  • Application fetches URLs without validation
  • Fix: Allowlist URLs, validate/sanitize input, network segmentation
  • Never commit secrets to source control. This is the #1 developer security failure.

    What counts as a secret:

    • API keys and tokens
    • Database connection strings
    • Private keys (SSH, TLS, signing)
    • OAuth client secrets
    • Webhook URLs with tokens
    • Any credential or password
    • Protection layers:

      1. .gitignore โ€” Always exclude .env, .pem, .key files
    1. Pre-commit hooks โ€” Use tools like git-secrets, truffleHog, or gitleaks
    2. Environment variables โ€” Never hardcode secrets, use env vars
    3. Secrets manager โ€” Use a dedicated service:
    - HashiCorp Vault (self-hosted)
    - AWS Secrets Manager / Parameter Store
    - GCP Secret Manager
    - Azure Key Vault
    - Doppler (developer-focused)

    If you accidentally commit a secret:

    1. Rotate the secret IMMEDIATELY (revoke and create new)
    2. Remove from git history: git filter-branch or BFG Repo-Cleaner
    3. Force-push the cleaned history
    4. Assume the secret is compromised (even if removed, it may be cached)
    5. CI/CD secrets:

      • Use your CI platform's secret storage (GitHub Secrets, GitLab CI variables)
  • Never echo secrets in CI logs
  • Use OIDC federation instead of long-lived tokens where possible
  • Rotate CI/CD secrets regularly
  • Your application's dependencies are part of your attack surface.

    The threat:

    • The average JavaScript project has 1,500+ transitive dependencies
    • Typosquatting attacks: "loadsh" (typo) vs "lodash" (real)
    • Compromised maintainer accounts uploading malicious versions
    • Protestware: Maintainers intentionally sabotaging their own packages
    • Defense strategies:

      1. Audit and monitor:

      npm audit              # Check for known vulnerabilities
      npx audit-ci # Fail CI on vulnerabilities

      2. Automate updates:

    • Enable Dependabot or Renovate for automatic PRs
    • Set up automated testing to catch breaking changes
    • Update frequently โ€” small updates are safer than big jumps
    • 3. Lock dependencies:

    • Always commit lock files (package-lock.json, yarn.lock)
    • Use exact versions in production
    • Consider using shrinkwrap for extra protection
    • 4. Evaluate before adding:

    • Check: download count, last update, maintainer count, issues
    • Prefer well-maintained packages with multiple contributors
    • Consider the transitive dependency tree size
    • Ask: "Could I write this in 50 lines instead of adding a package?"
    • 5. Advanced measures:

    • Use Socket.dev for supply chain analysis
    • Run dependencies in sandboxes where possible
    • Sign and verify releases with Sigstore/cosign
  • Use SBOMs (Software Bill of Materials) for production apps
  • Authentication:

    • Use OAuth 2.0 / OpenID Connect for user authentication
    • Use API keys + HMAC for service-to-service
    • JWTs: short expiry (15 min), refresh tokens (7 days), rotate signing keys
    • Never pass tokens in URL query parameters
    • Authorization:

    • Implement at the API layer, not just the frontend
    • Use object-level access checks (not just endpoint-level)
    • Rate limit by user, IP, and API key
    • Implement scoped permissions (principle of least privilege)
    • Input validation:

    • Validate ALL input on the server side
    • Use schema validation (Zod, Joi, JSON Schema)
    • Reject unexpected fields (allowlist, not denylist)
    • Sanitize output to prevent XSS
    • Transport security:

    • TLS 1.3 required (no exceptions)
    • HSTS header with long max-age
    • Pin certificates for mobile apps (certificate transparency)
    • Error handling:

    • Never expose stack traces or internal details in production
    • Use generic error messages for clients
    • Log detailed errors server-side
    • Don't differentiate between "user not found" and "wrong password"
    • Monitoring:

    • Log all authentication events
    • Alert on unusual patterns (brute force, credential stuffing)
    • Track API usage per key/user
  • Implement request signing for high-security APIs
  • During development:

    โ˜ Threat model your architecture before writing code

    โ˜ Use security linters (ESLint security plugins, Semgrep, Bandit)

    โ˜ Review OWASP cheat sheets for your framework

    โ˜ Use parameterized queries โ€” never string concatenation for SQL

    โ˜ Sanitize HTML output with DOMPurify or framework auto-escaping

    โ˜ Set security headers: CSP, X-Frame-Options, X-Content-Type-Options

    During code review:

    โ˜ Check for hardcoded secrets

    โ˜ Verify authorization checks on all endpoints

    โ˜ Review crypto usage (no custom crypto, use libraries)

    โ˜ Check for injection vulnerabilities

    โ˜ Verify input validation on server side

    During CI/CD:

    โ˜ Run SAST (Static Application Security Testing) โ€” Semgrep, CodeQL

    โ˜ Run DAST (Dynamic Testing) โ€” OWASP ZAP

    โ˜ Run dependency audit (npm audit, pip-audit)

    โ˜ Sign artifacts and verify in deployment

    โ˜ Use ephemeral credentials (OIDC federation)

    In production:

    โ˜ Enable runtime protection (WAF, RASP)

    โ˜ Monitor for anomalies (authentication failures, unusual traffic)

    โ˜ Have an incident response plan documented and tested

    โ˜ Rotate secrets on a schedule

    โ˜ Conduct penetration testing annually (minimum)