Skip to main content

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, description
  • recommendations: List[str] — actionable remediation steps
  • turn_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.

Metadata

Release files for stripllm 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for stripllm 0.1.0
File Size Uploaded Provenance Actions
stripllm-0.1.0.tar.gz 18.0 kB Without provenance Details for stripllm-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for stripllm 0.1.0
File Interpreter ABI Platform Actions
stripllm-0.1.0-py3-none-any.whl Python 3 none any Details for stripllm-0.1.0-py3-none-any.whl

Total release size: 32.6 kB

Release files / stripllm-0.1.0.tar.gz

Download URL stripllm-0.1.0.tar.gz
Size 18.0 kB
Tags Source
SHA-256 checksum
How to use checksums
1a2b5ad2e340b09665c22952d844edaa56f7ba2fb8e21b490d516695bea5277f
BLAKE2b-256 checksum
How to use checksums
c86c9daf2df2fb1c034de585f093a334e28c496517a9d7cdc988b06984b75f18
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release files / stripllm-0.1.0-py3-none-any.whl

Download URL stripllm-0.1.0-py3-none-any.whl
Size 14.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
01a4c958166509b180315eacb6f06b36f9a613b05615a0079ad9dff863cca849
BLAKE2b-256 checksum
How to use checksums
36d036da8377bfbffcb08c9a04a78d4652a7b0cb065fa009b3e75819eaa18d91
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Security for stripllm 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page