
Scan LLM outputs and AI-generated content for data exfiltration signals (EchoLeak, CVE-2025-32711) before they reach users or downstream systems
Scan LLM outputs and AI-generated content for data exfiltration signals before they reach users, logs, or downstream systems.
Modern LLM applications routinely process sensitive prompts, internal documents, API responses, and user data. That creates a new security boundary: the output layer.
The EchoLeak family of attacks (including CVE-2025-32711) demonstrated how hidden or obfuscated payloads can be embedded in generated text and used to exfiltrate data through tools, links, or parsing chains.
Traditional scanners focus on files, dependencies, and runtime traffic. They do not inspect generated model output in a purpose-built way.
exfil-scan provides a "virus scanner for LLM responses":
| Category | Severity | What is detected |
|---|---|---|
| Hidden Text | HIGH | Zero-width and invisible Unicode sequences used to hide payloads |
| Encoded Data | HIGH | Base64/hex/octal/unicode escape runs likely carrying encoded content |
| Data-in-URL | MEDIUM | Suspiciously long query strings and encoded URL parameter payloads |
| Metadata Leaks | HIGH | Credential-like keys and token formats in structured/unstructured outputs |
| Unicode Steganography | MEDIUM | Bidirectional controls and mixed-script homoglyph-style words |
| Structural Anomalies | LOW | Extreme newline/tab runs and replacement-character encoding artifacts |
low, medium, highstdin, single file, or directorytext, json, markdown, or htmlgit clone https://github.com/your-org/exfil-scan.git
cd exfil-scan
pip install -e .
pip install exfil-scan
pip install -e ".[dev]"
pytest
echo 'api_key: sk-ABCDEFGHIJKLMNOPQRSTUVWXYZ123456' | exfil-scan
exfil-scan --input output.txt
exfil-scan --directory ./model-logs --recursive
Notes:
--input or --directory, not both.stdin.1.exfil-scan --input suspicious.txt --format text
Expected style:
exfil-scan report
=================
Scanned targets: 1
Total findings: 2
1. [HIGH] metadata_leaks/known_token_format:openai_key
Location: suspicious.txt:1:10
Description: Matched known credential/token format (openai_key).
exfil-scan --input suspicious.txt --format json
Expected shape:
{
"finding_count": 2,
"scanned_targets": ["suspicious.txt"],
"findings": [
{
"category": "metadata_leaks",
"rule": "known_token_format:openai_key",
"severity": "HIGH",
"description": "Matched known credential/token format (openai_key).",
"location": "suspicious.txt:1:10",
"snippet": "..."
}
]
}
exfil-scan --directory ./outputs --recursive --format html --output report.html
Expected behavior:
exfil-scan --input suspicious.txt --format markdown --output report.md
Expected style:
# exfil-scan Report
- Scanned targets: 1
- Total findings: 2
The repository ships with default-config.yaml.
You can pass your own file with --config.
Sensitivity tuning:
low: fewer false positives, larger thresholdsmedium: balanced defaultshigh: catches more subtle patternsCLI sensitivity override:
exfil-scan --input out.txt --sensitivity high
You can add your own token formats and metadata keys:
sensitivity: medium
rules:
metadata_keys:
- api_key
- db_password
- internal_token
token_patterns:
custom_jwt: "\\beyJ[A-Za-z0-9_\\-]{10,}\\.[A-Za-z0-9_\\-]{10,}\\.[A-Za-z0-9_\\-]{10,}\\b"
corp_secret: "\\bcorp_[A-Za-z0-9]{24,}\\b"
Then run:
exfil-scan --input response.log --config ./my-config.yaml
Module responsibilities:
exfil_scan/cli.py: argument parsing, input selection, output rendering, exit handlingexfil_scan/config.py: defaults, YAML loading, recursive merge, profile normalizationexfil_scan/scanner.py: six detection engines, finding dataclasses, report formattingtests/test_scan.py: detection and output-format regression testsExecution flow:
| Code | Meaning |
|---|---|
0 | No findings (clean) |
1 | Findings detected |
2 | Runtime or argument error |
This makes CI integration straightforward:
exfil-scan --directory ./artifacts --recursive --format json --output exfil-report.json
If any detection is found, your job can fail fast based on exit code 1.
Run tests:
pytest
Coverage includes:
exfil-scan is a heuristic scanner.
It is designed to reduce risk and surface suspicious output, not prove content safety.
Recommended deployment pattern:
This project is licensed under the MIT License.
See LICENSE for full terms.
Contributions are welcome. When opening a PR, include:
| Option | Type | Default | Description |
|---|
-i, --input | path | none | Scan one input file |
-d, --directory | path | none | Scan all supported files in a directory |
-r, --recursive | flag | false | Recurse nested directories with --directory |
-c, --config | path | none | YAML config file path |
-s, --sensitivity | low|medium|high | config/default | Override sensitivity profile |
-f, --format | text|json|html|markdown | text | Render report format |
-o, --output | path | stdout | Write rendered report to a file |
--version | flag | n/a | Print CLI version |
-h, --help | flag | n/a | Show usage and arguments |