01Overview
Generative-AI features ship faster than security teams can review them, and the classic SAST tools that guard web apps have no concept of a prompt, an agent tool, a vector store, or a model file. The OWASP LLM Top 10 Scanner closes that gap. It is a single, self-contained Python file (owasp_llm_scanner.py, ~2,000 lines, zero third-party dependencies) that statically analyzes AI/LLM application source, config, and dependency manifests against the OWASP Top 10 for Large Language Model Applications (2025) — from prompt injection and system-prompt leakage to excessive agency, insecure output handling, and unbounded consumption.
Unlike a generic linter, every rule is written for the way LLM code actually looks: f-strings and template literals that splice user input into prompts, LangChain agents invoked on raw request bodies, torch.load() and from_pretrained(trust_remote_code=True) that turn a model file into remote code execution, ShellTool / PythonREPLTool wired into an autonomous agent, LLM output piped into eval()/exec()/subprocess/innerHTML, and ChatOpenAI clients instantiated with no max_tokens. It reads Python, JavaScript/TypeScript, .env, and YAML for pattern findings, and parses requirements.txt, Pipfile, pyproject.toml, and package.json to flag known-vulnerable LLM libraries (LangChain, transformers, torch, gradio, mlflow, litellm, llama-index, ollama, and more) by CVE and version range.
It is built for AppSec engineers, ML/platform teams, and CI/CD owners who need a fast, dependency-free gate they can drop into any pipeline. Findings carry a severity, CWE mapping, the offending line, a plain-English risk description, and concrete remediation. Output is human-readable color console or machine-readable JSON, and the process exits non-zero on any CRITICAL/HIGH finding so a build can fail the moment risky AI code is introduced.
It is notable for being a purpose-built LLM SAST scanner rather than a bolt-on ruleset: all ten OWASP LLM categories are represented, the checks map to the concrete APIs of the modern AI stack, and the whole thing runs anywhere Python 3.8+ runs with nothing to install.
02Key Capabilities
Full OWASP LLM Top 10 (2025) coverage
Ships rules for every category LLM01 through LLM10, so a single scan reports against the entire framework rather than a subset.
LLM-native prompt-injection detection
Flags user input spliced into prompts via f-strings, .format(), string concatenation, template literals, and PromptTemplate/agent invocations across Python and JS/TS.
Insecure model-loading and RCE checks
Catches torch.load() without weights_only, trust_remote_code=True in from_pretrained/load_dataset, allow_dangerous_deserialization, and pickle-based chain loading.
Improper output-handling sinks
Detects LLM output flowing into eval/exec, SQL execute, subprocess/os.system, Jinja2 |safe, innerHTML, document.write, and React dangerouslySetInnerHTML.
Excessive-agency guardrail checks
Warns when ShellTool, PythonREPLTool, unrestricted tools, unbounded AgentExecutor loops, or human_input_mode=NEVER hand too much power to an agent.
Dependency CVE scanning for the AI stack
Parses requirements.txt, Pipfile, pyproject.toml, and package.json to match LangChain, transformers, torch, gradio, mlflow, litellm and others against known CVEs by version range.
Secret and system-prompt leakage detection
Finds hardcoded OpenAI/Anthropic/HuggingFace keys, keys and system prompts in .env/YAML/client-side code, and prompts leaked via verbose mode, logs, or API responses.
Unbounded-consumption and cost controls
Flags LLM clients without max_tokens, API calls without timeouts, and generate/invoke calls inside while-True/setInterval loops that can run away on cost.
Vector and embedding weakness checks
Detects unauthenticated ChromaDB clients, unsanitized user input written to vector stores, and similarity_search results fed straight into prompts (indirect injection).
Multi-format input support
One scanner reads .py/.pyw, .js/.jsx/.ts/.tsx/.mjs/.cjs, .env, .yaml/.yml, and Python/Node dependency manifests from a file or a whole directory tree.
CI/CD-ready reporting
Color-coded console output plus a structured JSON report, severity filtering, and an exit code of 1 on CRITICAL/HIGH findings to gate builds.
Zero-install, single-file deployment
The entire scanner is one standard-library-only Python file, so it drops into any environment or pipeline with nothing to pip install.
03Architecture
The scanner is a single Python module organized as data-driven rule sets fed through a shared regex engine. A central LLMScanner class walks the target, dispatches each file to a handler by extension, and either line-matches SAST/config rules or parses a dependency manifest against a CVE database; every hit becomes a Finding that flows into console and JSON reporters. There is no external SAST framework — pattern rules, the CVE table, the version-range matcher, and the reporters are all self-contained.
04Project Structure
owasp_llm_scanner.pyThe scanner itself — rule sets, CVE database, LLMScanner engine, reporters, and CLI in one ~1,998-line file.tests/samples/vulnerable_agent.pyIntentionally vulnerable Python AI/agent fixture that exercises the Python LLM SAST rules.tests/samples/requirements.txtFixture pinning known-vulnerable LLM packages to trigger the dependency CVE checks.tests/samples/gap_services_bad.yamlYAML config fixture for the YAML rules (system prompts, hardcoded keys, trust_remote_code, missing token limits).tests/samples/.envEnvironment-file fixture with LLM API keys, ML-tracking creds, and database secrets for the .env rules.python_scanner.pySibling general-purpose Python SAST scanner (shares the single-file architecture pattern).mern_scanner.pySibling JS/TS (MERN) SAST scanner in the same repository.java_scanner.pySibling Java/Maven/Gradle/WAR SAST scanner.php_scanner.pySibling PHP SAST scanner.README.mdRepository documentation covering every scanner, inputs, categories, and usage.CLAUDE.mdArchitecture and contributor guide describing the shared scanner pattern and rule-ID conventions.banner.svgProject banner asset; LICENSE holds the MIT license.05Security Controls
06Technology Stack
- Language
- Python 3.8+
- Dependencies
- None — standard library only (re, os, sys, json, argparse, pathlib, datetime)
- Detection engine
- Line-based compiled-regex matching + version-range constraint evaluator
- Inputs
- .py/.pyw, .js/.jsx/.ts/.tsx/.mjs/.cjs, .env, .yaml/.yml, requirements.txt, Pipfile, pyproject.toml, package.json
- Output
- ANSI color console report and structured JSON (--json)
- Testing
- Intentionally vulnerable fixtures under tests/samples/ (no test framework)
- CI
- None in-repo; exit-code gating is designed for external pipelines
- Deployment
- Single self-contained file — copy and run, no install
07Quick Start
$ python3 owasp_llm_scanner.py /path/to/ai-project $ python3 owasp_llm_scanner.py agent.py --verbose $ python3 owasp_llm_scanner.py requirements.txt $ python3 owasp_llm_scanner.py /path/to/project --severity HIGH --json report.json $ python3 owasp_llm_scanner.py tests/samples/ # run the bundled vulnerable fixtures
08Compliance & Frameworks
09Integrations & Outputs
Explore OWASP LLM Top 10 Scanner
Full source, documentation, and deployment guides live on GitHub.