Overview of #545: OWASP Top 10 (2025 List) for Python Devs
This episode of Talk Python to Me (host Michael Kennedy) features Tanya Janca reviewing the OWASP Top 10 (2025 release) with a practical Python focus. They cover what changed in the list (notably the expanded treatment of supply chain risk and a new item for mishandling exceptional conditions), real-world examples (Django, Docker, CI, JS sourcemaps), AI / “vibe coding” risks, and concrete mitigations Python developers can apply today. Tanya also demos how directed AI prompts can surface security problems and points listeners to a free prompt library for secure AI code generation.
Key takeaways
- OWASP Top 10 (2025) released Dec 31, 2025; it’s an awareness document based on community data and surveys.
- Supply chain security was expanded beyond outdated libs to include malicious packages, CI/CD misconfigurations, compromised developer machines, and other developer-facing attack surfaces.
- New item: mishandling of exceptional conditions (errors/exceptions not handled or leaked) — closely tied to logging/alerting and resilience.
- “Vibe coding” / agentic AI (dark factories) creates significant, often invisible risks; AI-generated code tends to reflect bad examples it was trained on unless prompted for secure assumptions.
- Practical Python fixes (pinning deps, pip-compile/lockfiles, pip-audit, safe YAML parsing, avoid pickle for untrusted data, correct Docker port exposure) are emphasized repeatedly.
- Use actionable guidance: checklists, automated scanners (plus reachability / SCA improvements), and AI prompts that force the model to state security assumptions.
OWASP Top 10 (2025) — summary with Python-focused notes
Note: OWASP items are categories; below are their essence plus Python-specific examples and mitigations mentioned in the episode.
1) Broken Access Control
- What: Missing or incorrect authorization checks (APIs, endpoints, file access, record-level control).
- Python notes: don’t rely on login_required alone for admin actions in Django; always enforce role checks server-side; avoid sending entire datasets to clients and filtering client-side.
- Mitigation: server-side authorization per request/record, least privilege, use proven access control libraries/tools or policies.
2) Misconfiguration (Security/Hardening)
- What: Wrong configs, debug enabled in production, missing security headers, exposed sensitive files (e.g., JS sourcemaps).
- Python notes: Django DEBUG must be False in prod; enforce HSTS, CSP, X-Frame-Options; ensure sensitive files/maps are excluded from production bundles and git.
- Mitigation: CI checks, environment-aware configs, checklists, security-focused deployment pipeline.
3) Software Supply Chain Failures (expanded)
- What: Beyond vulnerable dependencies — malicious packages, compromised CI, stolen credentials, compromised dev machines.
- Python notes: pin dependencies (lockfiles), use pip-compile / pip-tools, use pip-audit, validate package integrity, adopt provenance and package signing where possible.
- Mitigation: SCA tools that support reachability analysis (so you don’t drown in noise), pin-and-update workflows, protect developer machines and CI secrets, vet package sources.
4) Cryptographic Failures
- What: Weak or missing encryption, poor key handling, reversible password storage, exposing secrets.
- Python notes: use proper password hashing (Argon2, bcrypt), never store keys and plaintext passwords together; prefer proven crypto libraries.
- Mitigation: adopt current algorithms (Argon2id), use vaults/secret stores, secure TLS config.
5) Injection
- What: Treating data as code (SQL, NoSQL, template injection, deserialization).
- Python notes: SQL parameterized queries / ORM usage, beware of MongoDB-style JSON injections, avoid pickle for untrusted data, validate/escape user input.
- Mitigation: parameterized queries, strong input validation (allow-list), escape where needed, avoid unsafe deserialization.
6) Insecure Design
- What: Design-level problems — missing threat modeling, no security requirements, client-side-only controls, lack of rate limiting.
- Python notes: design APIs to be behind an API gateway, define security requirements and threat models early.
- Mitigation: threat modeling, design reviews, security requirements as part of specs.
7) Authentication Failures
- What: Weak authentication or session management leading to account takeover (credential stuffing, brute force).
- Python notes: avoid home-rolled auth; use mature providers or well-tested libraries; implement MFA / passkeys; device/browser trust/ fingerprinting to reduce friction.
- Mitigation: rate-limiting, MFA, passkeys, trusted-device policies, protect against credential stuffing.
8) Software and Data Integrity Failures
- What: Tampered software or data (supply chain tampering, changed data in transit, compromised CDNs).
- Python notes: verify downloads, use SRI for CDN assets, check package integrity/provenance, ensure CI artifacts are signed if possible.
- Mitigation: integrity checks, subresource integrity for JS/CSS, artifact signing, provenance tracking.
9) Logging and Monitoring Failures
- What: Incomplete or missing security logs/alerts; inability to investigate incidents.
- Python notes: log security events (authentication failures, input validation failures) with sufficient context (user id, timestamps), do not strip failures.
- Mitigation: structured security logging, centralized logging/alerting, include failures and success events for audits.
10) Mishandling Exceptional Conditions (new)
- What: Poor error/exception handling: swallowing exceptions, printing stack traces to users, failing to recover cleanly.
- Python notes: avoid bare excepts that hide errors; don’t leak stack traces in responses; use transactions to maintain data integrity.
- Mitigation: explicit error handling, user-friendly but non-leaking error messages, proper rollback and resilience patterns.
Extra notes: the team also called out three additional concerns for consideration (tie item, memory safety, and “vibe coding”/AI-assisted code generation) — these are highlighted in the release as important adjuncts.
Notable insights & examples from the episode
- OWASP Top 10 is meant to be actionable — avoid vague buckets like “poor code quality.”
- Real-world incident illustrations: leaked JS sourcemaps (Cloudflare/Cloud code style issues), developer machine compromise via home services (Plex), and SolarWinds-style deep pipeline compromises.
- Docker + UFW caveat: published container ports (docker run -p) can bypass host firewall rules (UFW) and expose DB ports (e.g., Postgres 5432) to the internet if not bound to localhost. Always bind to localhost or use appropriate network controls.
- AI-generated code tends to reproduce insecure patterns because training data includes many insecure examples; you must explicitly require a model to list security assumptions and follow secure coding prompts.
- Reachability in SCA: a reported vulnerability in a package may not be exploitable by your app if the vulnerable code path is not reachable — tools that perform reachability analysis reduce noise.
Practical, prioritized action items for Python devs
- Pin dependencies and use lockfiles (pip-compile, pip-tools, poetry lock) and adopt a safe update cadence (e.g., allow updates after a short vetting window).
- Scan builds automatically (pip-audit, SCA tools) and aim for reachability analysis where possible to reduce noise.
- Use proven auth/session providers or solid libraries; enable MFA/passkeys and rate-limiting on authentication endpoints.
- Turn off DEBUG in Django in production; enable HSTS, CSP, and other security headers; audit build artifacts (no sourcemaps in prod unless secure).
- Avoid unsafe deserialization (pickle) for untrusted data; use safe YAML parsing (safe_load) and validated JSON schemas.
- Parameterize all DB queries, validate input with allow-lists, and escape necessary characters; beware NoSQL injection vectors.
- Implement integrity checks: SRI for public CDNs, package signing/verification where feasible.
- Improve logs: capture failed auth attempts, input validation failures, and other security-relevant events; centralize and alert.
- Handle exceptions explicitly (no empty excepts), sanitize error responses, and ensure transactions/rollbacks where data integrity matters.
- Protect developer machines and CI secrets (secrets management, least privilege in CI, limit token access), and consider hardening developer endpoints.
AI and “vibe coding” guidance
- If you use AI to generate code, always:
- Require the model to list all security assumptions.
- Run automated secure code reviews and vulnerability prompts (Tanya’s prompt library provides layered prompts: always-run rules, design-time templates, and feature-specific hardening prompts).
- Apply the same tests/scanners to AI-generated code as you would for human code (unit tests, SCA, pip-audit, static analysis).
- Tanya’s secure prompt library: securemyvibe.ca (free, requires sign-up/newsletter). It includes multi-level prompts for generating and auditing secure code.
Resources mentioned
- OWASP Top 10 (2025) — visit owasp.org and the OWASP Top 10 GitHub repository for the release, historical lists, and markdown resources.
- OWASP Cheat Sheets — searchable guidance on specific topics (authentication, authorization, input validation, etc.).
- Tanya Janca: SheHacksPurple.ca — blog, DevSec Station podcast, and resources.
- Secure prompt library: securemyvibe.ca (free, newsletter opt-in).
- Scanning/tools: pip-audit, pip-compile/pip-tools, lockfiles, SCA tools (seek reachability features).
- Temporal sponsor (workflows for Python) — temporal.io / talkpython.fm/Temporal (sponsor mention in episode).
Final notes
- The 2025 OWASP Top 10 emphasizes actionable items you can implement today and highlights supply chain and AI-driven risks that have become central.
- Start with checklists, automated scans, and reducing the blast radius (pin deps, protect CI/dev machines, proper auth & logging). Use OWASP cheat sheets as concrete recipes and consider joining your local OWASP chapter for community support.
