Code Scanner

ai-blackteam includes a static analysis scanner that finds LLM-specific security vulnerabilities in Python and JavaScript/TypeScript code. It catches the things traditional linters miss — prompt injection vectors, secrets in prompts, unsafe output handling, and excessive agency.

Quick Start

# Scan current directory
ai-blackteam scan .

# Scan a specific file
ai-blackteam scan app.py

# JSON output for CI pipelines
ai-blackteam scan src/ --format json -o findings.json

# Filter by severity
ai-blackteam scan . --severity critical

What It Detects

The scanner ships with 11 rule categories, each mapped to OWASP LLM Top 10:
Rule IDNameSeverityOWASPWhat It Catches
BTSC-001Prompt Injection: User Input in System PromptCriticalLLM01f-strings, .format(), concatenation in system role messages
BTSC-002Secrets in Prompt TemplatesHighLLM02API keys, env vars, passwords embedded in prompts
BTSC-003LLM Output Run as CodeCriticalLLM05Dangerous code paths with LLM response variables
BTSC-004LLM Output Rendered as HTML (XSS)HighLLM05innerHTML, dangerouslySetInnerHTML, v-html with LLM output
BTSC-005LLM Output in SQL QueryCriticalLLM05Unparameterized SQL with LLM response variables
BTSC-006Excessive Agency: Unrestricted Shell AccessCriticalLLM06@tool decorator with subprocess shell=True, os.system
BTSC-007Excessive Agency: Unrestricted File AccessHighLLM06@tool decorator with open() on arbitrary paths
BTSC-008Missing max_tokens LimitMediumLLM10LLM API calls without max_tokens set
BTSC-009Hardcoded System Prompt with Sensitive ContentMediumLLM07Long system prompts with business logic, URLs, secrets
BTSC-010No Input Validation Before LLM CallMediumLLM01HTTP request body flows directly to LLM API
BTSC-011RAG Retrieval Without Access ControlHighLLM08Vector DB query without user-level filtering

Output Formats

Table (default)

ai-blackteam scan src/
Prints a Rich-formatted table with file path, line number, rule ID, severity, and message.

JSON

ai-blackteam scan src/ --format json -o scan-results.json
Returns an array of finding objects:
[
  {
    "file": "src/app.py",
    "line": 42,
    "rule_id": "BTSC-001",
    "rule_name": "Prompt Injection: User Input in System Prompt",
    "severity": "critical",
    "owasp": "LLM01",
    "message": "User input should only go into role:'user' messages. System prompts must be static strings."
  }
]

CI Integration

The scanner returns exit code 1 if critical findings are detected, exit code 0 otherwise. Use it as a pre-merge check:
- name: Scan for AI vulnerabilities
  run: ai-blackteam scan src/ --severity critical

File Types

The scanner reads .py, .js, .ts, .tsx, and .jsx files. It skips binary files, node_modules, and hidden directories automatically.

Programmatic Usage

from ai_blackteam.scanner import scan_file, scan_directory

# Scan a single file
findings = scan_file("app.py")

# Scan a directory
findings = scan_directory("src/")

for f in findings:
    print(f"{f['file']}:{f['line']} [{f['severity']}] {f['message']}")