Overview
Security vulnerabilities are bugs with consequences. A null pointer dereference crashes your program; an unchecked buffer overflow hands an attacker control of your server. The difference is not in the code, but in the threat model: who might exploit the bug, what they could gain, and what you stand to lose. Software security, then, is not a separate discipline from software engineering. It is software engineering with an adversary in the loop.
This chapter brings AI into every stage of the secure software development lifecycle. We begin with threat modeling, where structured frameworks like STRIDE and attack trees help you enumerate what could go wrong before you write a line of code. We then move to AI-assisted security review, where static analysis tools (Semgrep, Bandit, CodeQL), fuzz testing (Atheris, Hypothesis), and symbolic execution discover vulnerabilities that manual review misses. Finally, we build a security review pipeline that combines LLM-driven threat analysis with automated scanning into a continuous, reproducible process integrated with the Discovery Workbench.
The connection to discovery runs deep. Vulnerability discovery is literally a search problem: the space of possible inputs is vast, and the attacker is searching for the one input that triggers unexpected behavior. This connects directly to the search framework of Chapter 1. The testing techniques from Chapter 18 (property-based testing, fuzzing, mutation analysis) reappear here with a security lens. And the debugging strategies from Chapter 19 become triage workflows when the "bug" is an exploitable vulnerability.
Prerequisites
Readers should have completed
Chapter 18: AI-Assisted Testing and QA
(which introduced property-based testing, fuzzing, and mutation analysis) and
Chapter 19: AI-Assisted Debugging
(which covered root-cause analysis and fault localization). Familiarity with HTTP APIs,
basic authentication flows, and the Python subprocess module is assumed.
Experience with FastAPI or Flask is helpful but not required; all web framework code
is self-contained.
Learning Outcomes
- Apply STRIDE threat modeling and attack tree analysis to systematically identify security risks in software systems.
- Use static analysis tools (Semgrep, Bandit, CodeQL) to detect common vulnerability patterns in Python codebases.
- Perform AI-assisted fuzz testing with Atheris and Hypothesis to discover input-handling vulnerabilities.
- Build LLM-driven security review agents that analyze code for injection, authentication, and data-exposure flaws.
- Design sandboxing and output-validation strategies for secure AI coding agents.
- Construct an end-to-end security review pipeline that produces a threat model, runs automated scans, and generates regression tests.
Sections
20.1 Threat Modeling
STRIDE threat categories and attack tree construction. Systematic enumeration of spoofing, tampering, repudiation, information disclosure, denial of service, and elevation of privilege. Dataflow diagrams and trust boundaries. AI-assisted threat model generation for web services and scientific APIs.
20.2 AI-Assisted Security Review
Vulnerability discovery with SAST (Semgrep, Bandit, CodeQL), fuzz testing (Atheris), and symbolic execution. LLM-driven code review for security flaws. AI red teaming: prompt injection, data exfiltration, and jailbreak defense. Secure coding agents with sandboxing and output validation.
20.3 Building a Security Review Pipeline
Recipe: end-to-end AI security review of a FastAPI service. Automated threat model generation, multi-tool vulnerability scanning, LLM triage and severity classification, regression test generation, and Discovery Workbench integration.
Bibliography
Foundational Papers
The definitive guide to STRIDE-based threat modeling, establishing the methodology used throughout Section 20.1 for systematic security analysis of software systems.
Evaluates LLM ability to repair security vulnerabilities without examples, finding that models fix 100% of synthetic and 58% of real-world CWEs with appropriate prompting.
Demonstrates that LLM agents given vulnerability descriptions can autonomously write exploits, motivating the defensive techniques in Section 20.2.
Tools and Libraries
Pattern-based static analysis with a rule language accessible to non-experts. Supports custom rules for project-specific vulnerability patterns. Central to Sections 20.2 and 20.3.
Python-specific security linter that checks for hardcoded passwords, SQL injection, shell injection, and unsafe deserialization. Used in Section 20.2.
Query-based static analysis that treats code as data, enabling complex taint-tracking and dataflow queries for vulnerability discovery.
Coverage-guided fuzzer for Python that integrates with libFuzzer, used in Section 20.2 for discovering input-handling vulnerabilities.
Property-based testing framework used here with a security lens, generating adversarial inputs from strategies that target boundary conditions and injection vectors.
Research Frontiers
A benchmark for evaluating whether LLMs generate secure code, finding that models produce vulnerable code 25-40% of the time without security-specific prompting.
Proposes adversarial testing of LLM code generation to discover security-relevant failure modes, motivating the red-teaming approach in Section 20.2.
A sober assessment of current LLM limitations in vulnerability detection, finding high false-positive rates and inconsistent reasoning, motivating the multi-tool pipeline approach in Section 20.3.
The industry-standard categorization of web application vulnerabilities, providing the taxonomy used throughout this chapter for classifying discovered flaws.