LLM sanitization SDK — DOMPurify, but for LLM context windows.
Project description
StripLLM
DOMPurify, but for LLM context windows.
StripLLM is an open-source Python SDK that sanitizes LLM inputs and outputs in your existing pipeline — no infrastructure changes, no external API calls, sub-10ms latency.
pip install stripllm
Quickstart
from stripllm import StripLLM
strip = StripLLM()
# 1. Block prompt injection before it reaches the LLM
safe_input = strip.clean(user_message)
# 2. Redact PII — get a mapping back for rehydration
redacted, mapping = strip.redact("Email me at john@acme.com")
# redacted → "Email me at [EMAIL_1]"
# mapping → {"[EMAIL_1]": "john@acme.com"}
# After LLM responds, restore originals in the output
response = strip.rehydrate(llm_response, mapping)
# 3. Validate LLM output — enforce schema, catch leaks & hallucinations
validated = strip.enforce(llm_response, schema="json")
# 4. Full conversation risk audit
report = strip.audit(conversation)
print(report.risk_score) # → 0.12
print(report) # → formatted findings + recommendations
API Reference
StripLLM(threshold=0.3)
Initialize the sanitizer. threshold controls how sensitive clean() is (0.0–1.0, lower = stricter).
strip.clean(text: str) → str
Detects prompt injection, jailbreak attempts, and unicode tricks. Raises InjectionDetectedError if risk score meets or exceeds threshold.
Detects:
- Classic overrides: "ignore previous instructions", "forget your training"
- Role hijacking: DAN, "you are now", "act as an unrestricted AI"
- System prompt extraction attempts
- Zero-width character attacks
- Unicode homoglyph tricks (NFKC normalization)
try:
safe = strip.clean(user_input)
except InjectionDetectedError as e:
print(f"Blocked. Risk score: {e.risk_score}")
Non-raising variant:
result = strip.scan(text)
result.detected # bool
result.risk_score # float 0.0–1.0
result.matched_patterns # list of matched signatures
strip.redact(text: str, entities=None) → (str, dict)
Replaces PII with typed placeholders. Returns (redacted_text, mapping).
Supported entity types:
| Type | Example | Placeholder |
|---|---|---|
EMAIL |
john@acme.com | [EMAIL_1] |
PHONE |
415-555-1234 | [PHONE_1] |
SSN |
123-45-6789 | [SSN_1] |
CREDIT_CARD |
4111111111111111 | [CREDIT_CARD_1] |
IP_ADDRESS |
192.168.1.1 | [IP_ADDRESS_1] |
PASSPORT |
A12345678 | [PASSPORT_1] |
URL |
https://internal.corp/secret | [URL_1] |
# Target specific entity types only
redacted, mapping = strip.redact(text, entities=["EMAIL", "SSN"])
# Restore originals after LLM processing
final_response = strip.rehydrate(llm_output, mapping)
strip.enforce(text: str, schema=None, raise_on_error=True) → str
Validates LLM output for safety and structural correctness.
# Require valid JSON
validated = strip.enforce(response, schema="json")
# Require specific keys and types
validated = strip.enforce(response, schema={"status": str, "count": int})
# Check for leaks only (no schema)
validated = strip.enforce(response)
Detects:
- Invalid JSON (when schema specified)
- Missing or wrong-typed keys
- Leaked system prompt delimiters (
<system>,[INST],<<SYS>>, etc.) - Suspicious / likely-hallucinated URLs
Non-raising variant:
result = strip.validate(text, schema="json")
result.valid # bool
result.errors # list of error strings
result.warnings # list of warning strings
result.output # best-effort cleaned output
strip.audit(conversation: list) → AuditReport
Full security audit of a multi-turn conversation.
conversation = [
{"role": "user", "content": "My email is alice@corp.com. Help me with my account."},
{"role": "assistant", "content": "Sure, I can help with that."},
]
report = strip.audit(conversation)
print(report.risk_score) # 0.1
print(report.findings) # list of Finding objects
print(report.recommendations) # list of action strings
print(report) # formatted summary
AuditReport fields:
risk_score: float— overall conversation risk (0.0–1.0)findings: List[Finding]— per-turn findings with severity, category, descriptionrecommendations: List[str]— actionable remediation stepsturn_count: int
Why StripLLM vs Alternatives?
| StripLLM | Lakera Guard | Rebuff | DIY Regex | |
|---|---|---|---|---|
| Local (no API calls) | ✅ | ❌ | ❌ | ✅ |
| Latency | <10ms | ~100ms | ~200ms | <1ms |
| PII rehydration | ✅ | ❌ | ❌ | ❌ |
| Output validation | ✅ | ❌ | ❌ | ❌ |
| Conversation audit | ✅ | ❌ | ❌ | ❌ |
| Open source | ✅ MIT | ❌ | ❌ | ✅ |
| Zero config | ✅ | ❌ | ❌ | ✅ |
Use Cases
Customer support bots — prevent prompt extraction, redact customer PII before sending to LLM
RAG pipelines — sanitize retrieved documents before injecting into context window
AI coding assistants — validate generated code output, catch leaked credentials
Healthcare / Finance — HIPAA/PCI-DSS compliant PII handling with full audit trail
Running Tests
pip install -e ".[dev]"
pytest
License
MIT — see LICENSE
Enterprise?
Need centralized LLM security across your entire organization? Check out Context Firewall — a reverse proxy / API gateway that applies StripLLM-style protection to every LLM request in your stack, with a real-time dashboard, SOC 2 audit trail, and RBAC.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file stripllm-0.1.0.tar.gz.
File metadata
- Download URL: stripllm-0.1.0.tar.gz
- Upload date:
- Size: 18.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1a2b5ad2e340b09665c22952d844edaa56f7ba2fb8e21b490d516695bea5277f
|
|
| MD5 |
8f85a6116eb652843b328ab47264fde2
|
|
| BLAKE2b-256 |
c86c9daf2df2fb1c034de585f093a334e28c496517a9d7cdc988b06984b75f18
|
File details
Details for the file stripllm-0.1.0-py3-none-any.whl.
File metadata
- Download URL: stripllm-0.1.0-py3-none-any.whl
- Upload date:
- Size: 14.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
01a4c958166509b180315eacb6f06b36f9a613b05615a0079ad9dff863cca849
|
|
| MD5 |
377413c7e07d0e5c153c6d260d65f873
|
|
| BLAKE2b-256 |
36d036da8377bfbffcb08c9a04a78d4652a7b0cb065fa009b3e75819eaa18d91
|