Security mindset & threat modeling
Security begins with mindset: assume attackers will probe your system for weaknesses. Threat modeling is the process of identifying assets, entry points, threats, and mitigations before writing code.
Simple threat modeling steps:
- Identify assets (user data, credentials, servers).
- Map attack surface (APIs, auth endpoints, file uploads).
- Enumerate threats (injection, broken auth, data exfiltration).
- Prioritize risks by impact and likelihood, then mitigate with design and controls.
Secure coding fundamentals
Follow these baseline practices in every project:
- Validate inputs and encode outputs.
- Use least privilege (for services, users, databases).
- Fail securely—deny access by default and give minimal error information to users.
- Avoid rolling your own crypto or auth—use vetted libraries.
- Keep dependencies up-to-date and track vulnerabilities (dependabot, Snyk).
Example: prefer high-level APIs that prevent common mistakes (parameterized queries instead of string concatenation for SQL).
# Bad: vulnerable to SQL injection (do NOT do this)
query = "SELECT * FROM users WHERE email = '" + email + "'"
# Good: parameterized query (example in Python + psycopg2)
cursor.execute("SELECT * FROM users WHERE email = %s", (email,))
Input validation & output encoding
Treat all inputs as untrusted. Validate type, length, format, and range. Use a whitelist approach (allow only what’s expected) rather than blacklists.
Output encoding
Encode output for the intended context (HTML, JavaScript, URL, SQL) to prevent injection attacks (XSS, SQLi). For web templates, use frameworks with built-in escaping or template engines that auto-escape by default.
<!-- In templating frameworks like Jinja2, prefer autoescaping and avoid inserting raw HTML -->
<div></div>
If you must render HTML from user content, sanitize it with a strict allowlist (e.g., Bleach for Python).
Authentication & session management
Authentication failures lead to account takeover and data leaks. Implement robust authentication and session controls:
- Use proven frameworks/services (OAuth providers, Auth0, Firebase Auth) when possible.
- Store password hashes using a slow, adaptive algorithm (bcrypt, Argon2) with per-user salts.
- Protect session cookies: use
Secure,HttpOnly, andSameSiteattributes. - Implement multi-factor authentication (MFA) for critical actions.
# Example cookie flags (Express.js)
res.cookie('sid', sessionId, { httpOnly: true, secure: true, sameSite: 'Strict' });
Rotate credentials and session tokens on sensitive events (password change, suspicious activity). Limit session lifetime and implement logout/invalidation.
Encryption & key management
Encryption protects data at rest and in transit. Use TLS (HTTPS) with modern ciphers and HSTS for transport security. For data at rest, use vetted encryption libraries and manage keys securely.
Key management
- Do not hardcode secrets in source code or config files.
- Use secret managers (Vault, AWS Secrets Manager, GCP Secret Manager).
- Rotate keys and limit access with IAM policies.
# Example: do not store credentials in repo
# BAD: in source
DATABASE_PASSWORD = "supersecret"
# GOOD: read from environment or secret manager
DATABASE_PASSWORD = os.environ.get("DATABASE_PASSWORD")
OWASP Top 10 — quick defenses
The OWASP Top 10 highlights the most critical web application security risks. Brief defenses for common items:
1. Injection (SQL, NoSQL, OS, LDAP)
Use parameterized queries, ORM APIs, and avoid constructing queries from user input.
2. Broken Authentication
Use strong password policies, MFA, and secure session management.
3. Sensitive Data Exposure
Encrypt data in transit & at rest, minimize data collection, and mask logs.
4. XML External Entities (XXE)
Disable external entity processing in XML parsers.
5. Broken Access Control
Enforce authorization checks server-side; never rely on client checks.
6. Security Misconfiguration
Harden servers, remove default creds, and automate configuration via IaC with secure defaults.
7. Cross-Site Scripting (XSS)
Escape output, use CSP, and sanitize user HTML inputs.
8. Insecure Deserialization
Avoid accepting serialized objects from untrusted sources; validate or use safe formats like JSON.
9. Using Components with Known Vulnerabilities
Scan dependencies, apply patches, and use tools like dependabot or Snyk.
10. Insufficient Logging & Monitoring
Log security events and monitor for anomalies with alerting and retention policies.
Secure deployment & CI/CD
Security must extend to build and deployment pipelines:
- Run builds in ephemeral, minimal privilege environments.
- Scan artifacts and images for vulnerabilities before deployment.
- Sign release artifacts and use provenance tracking.
- Limit who can merge to main and require passing security checks (SAST, dependency scanning).
# Example: GitHub Actions job snippet that scans dependencies (pseudo)
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run dependency scan
run: snyk test || true
Use network segmentation and firewalls for production infrastructure. Ensure secrets used by CI are stored in secret stores and not printed in logs.
Logging, monitoring & incident response
Good logging and monitoring detect issues early. Protect logs from tampering and avoid storing sensitive data in logs.
Monitoring & alerting
- Collect metrics (auth failures, spike in 500s) and set meaningful alerts.
- Use centralized logging (ELK, Splunk, Datadog) with retention and role-based access.
Incident response
Have an incident playbook: identification, containment, eradication, recovery, and post-mortem. Practice tabletop exercises to improve response times.
Data privacy & compliance
Understand legal obligations (GDPR, CCPA) if you process personal data. Minimize data collection, document processing, and provide mechanisms for data subject requests.
Pseudonymize or anonymize data where possible, and ensure data retention policies are enforced.
FAQ
Q: Do I need to be a security expert to build secure apps?
A: No — you need to follow secure defaults, use vetted libraries, and have basic hygiene (validation, encryption, patching). For critical systems consult security experts and perform formal reviews.
Q: How do I handle a data breach?
A: Follow your incident response plan, contain the breach, rotate secrets, notify affected users and authorities as required, and perform a post-mortem. Legal obligations depend on jurisdiction.
Q: What simple steps reduce most risk?
A: Enforce HTTPS, avoid storing plain-text secrets, require strong password hashing, validate inputs, keep dependencies patched, and monitor logs.
Key takeaways & practice
- Adopt secure defaults: least privilege, fail-safe defaults, and use vetted libraries.
- Threat model early and iterate—security-by-design beats security-as-an-afterthought.
- Automate security scans and patching in CI/CD, and protect secrets with proper key management.
- Document incident plans and practice them periodically.
- Keep logs, metrics, and alerting tuned to detect suspicious behavior quickly.
Practice challenge: Pick a small web app and perform a short security review: run dependency scans, test for XSS and SQLi with safe tools, ensure TLS is enforced, and add an automated security check to the CI pipeline.