Module 4: Input & Output Sanitization
1. Introduction: Input & Output Sanitization
Overview
In Module 3 you built defenses against prompt injection — intentional attacks where a user manipulates the model into executing unauthorized instructions. Your Injection Defense Pipeline detects malicious patterns, blocks override attempts, and protects the system prompt. That's a critical layer. But there's a problem: prompt injection is just one of the ways data can cause harm in your AI system.
An input doesn't need to be malicious to be dangerous. A user who pastes text with invisible Unicode characters can cause your model to process hidden instructions. An input with 50,000 characters can drain your token budget in a single request. A model output that contains malformed JSON can break your frontend. An output with toxic content can destroy your company's reputation. An output that includes PII (personally identifiable information) from another user can violate GDPR. None of these problems is prompt injection — but all of them require defenses.
This module builds the data hygiene layer that complements the anti-injection defenses from Module 3. If Module 3 was "defend against intentional attacks", this module is "make sure everything that enters and leaves your AI system is clean, valid, and safe." It's the difference between a security guard (M3) and a quality inspector (M4) — you need both.
The main focus of this module is mitigating LLM05: Improper Output Handling, one of the most underestimated vulnerabilities in the OWASP LLM Top 10 2025. LLM05 happens when the application blindly trusts the LLM's output and passes it directly to another system, UI, or database without validation. It's the AI equivalent of trusting a web form field without sanitizing it — except the "form" is a model that generates unpredictable content.
Why a whole module for sanitization?
The decision to dedicate a module to input and output sanitization (separate from prompt injection) is deliberate. There are three reasons:
1. Prompt injection is an attack; sanitization is hygiene
Module 3 defends against an active adversary that tries to manipulate your system. This module defends against data that causes problems simply by its nature: malformed, too long, with inconsistent encoding, with inappropriate content, or with unexpected structure. You don't need an attacker to get a toxic output — the model can produce one on its own.
2. LLM05 (Improper Output Handling) requires its own defenses
In Module 2 (capsule 05), you saw that LLM05 happens when a model output is executed in a downstream system without validation. The model generates JavaScript → your frontend renders it as HTML → XSS. The model generates SQL → your backend executes it → data exfiltration. The model generates a URL → your system follows it → SSRF. These aren't model vulnerabilities — they're vulnerabilities in your application that trusts the model without verifying.
3. Data quality affects system quality
An input with mixed Unicode produces inconsistent embeddings. An input that isn't normalized generates different results for the same question phrased with different accents. An output without schema validation breaks downstream integrations. Sanitization isn't only security — it's engineering quality.
What will you learn in this module?
By the end of this module you'll be able to:
- Implement complete input sanitization: Unicode normalization, character whitelisting, per-endpoint length limits, encoding normalization, detection of malformed inputs
- Validate LLM outputs with Pydantic schemas: structured outputs with OpenAI, fallback strategies when validation fails, retry with an adjusted prompt, default response
- Filter content in outputs: toxicity detection with heuristics and moderation API, off-topic response detection, flags for possible hallucinations
- Build deep guardrails that go beyond basic validation: guardrails-ai framework, NeMo Guardrails concepts, chained custom guardrails
- Design the complete pipeline: Input → Sanitize → Validate → LLM → Validate Output → Filter → Sanitize Output → Respond, implemented as FastAPI middleware
- Handle production edge cases: streaming responses, multi-modal inputs, batch processing, integrated rate limiting, caching of sanitized inputs
- Implement robust fallback strategies: what to do when an input fails sanitization, what to do when an output fails validation, how many retries before fallback
- Build a complete Sanitization Pipeline as a project: reusable FastAPI middleware with input sanitizer, output validator, content filter, guardrails, and audit logging
Module roadmap
This module has 8 capsules that build the sanitization pipeline layer by layer:
| # | Capsule | What you'll learn |
|---|---|---|
| 01 | Introduction: Input & Output Sanitization | Why this module, roadmap, connection with the project, setup |
| 02 | Input Sanitization: Fundamentals | Cleaning inputs, Unicode normalization, whitelisting, length limits, InputSanitizer class |
| 03 | Output Validation with Pydantic | Structured validation of LLM outputs, schemas, retry strategies, OpenAI structured outputs |
| 04 | Content Filtering | Toxicity, off-topic detection, moderation API, content policies, custom filters |
| 05 | Deep Guardrails | guardrails-ai, NeMo Guardrails, custom guardrails, chaining, performance |
| 06 | Complete Input → Output Pipeline | Full flow as FastAPI middleware, error handling per stage, fallbacks |
| 07 | Edge Cases and Production | Streaming, multi-modal, batch processing, caching, pipeline versioning |
| 08 | Project: Sanitization Pipeline | Complete reusable pipeline with all layers integrated |
The progression is: context (01) → input (02) → output (03-04) → guardrails (05) → integration (06) → production (07) → project (08).
Capsules 02-04 build the individual pieces of the pipeline. Capsule 05 adds guardrails as an orchestration layer. Capsule 06 integrates everything into a complete flow. Capsule 07 tackles the edge cases that only appear in production. Capsule 08 is the project where you build the Sanitization Pipeline as a reusable artifact.
Context within the guide
This guide has 8 modules organized into 3 phases:
Phase 1: Security Foundations (Modules 1-3)
├── Module 1: AI Security Landscape & Threat Model ✅ COMPLETED
├── Module 2: OWASP LLM Top 10 Deep Dive ✅ COMPLETED
└── Module 3: Prompt Injection — Attacks & Defenses ✅ COMPLETED
Phase 2: Defense Implementation (Modules 4-6)
├── Module 4: Input & Output Sanitization ← YOU ARE HERE
├── Module 5: Secrets Management
└── Module 6: Data Privacy & PII Protection
Phase 3: Production Security (Modules 7-8)
├── Module 7: Security Testing & Auditing
└── Module 8: Capstone Project — Secured AI System
Module 1 gave you the threat map. Module 2 gave you the OWASP framework to classify threats. Module 3 implemented the defense against threat #1 (LLM01: Prompt Injection). Now Module 4 tackles the next layer: complete hygiene of the data flow, with a focus on LLM05 (Improper Output Handling).
The relationship with Module 3 is complementary, not repetitive:
Module 3 (Injection Defense) Module 4 (Sanitization)
───────────────────────── ─────────────────────────
Detects intentional attacks Cleans malformed data
Blocks prompt injection Normalizes encoding
Protects the system prompt Validates output structure
Prevents instruction override Filters toxic content
Focus: LLM01 Focus: LLM05
Together, the M3 and M4 pipelines form the system's secure data flow: injection detection (M3) + input sanitization (M4) → LLM → output validation (M4) + output filtering (M4).
Prerequisites
For this module you need:
- Modules 1-3 completed: Threat Model Document, OWASP Mapping Audit, Injection Defense Pipeline
- Python 3.10+ installed
- An OpenAI API key (or compatible provider)
- Familiarity with Pydantic v2 — validators, BaseModel, Field
- Familiarity with FastAPI — middleware, dependencies, request/response lifecycle
Technical setup
If you already have the environment from the previous modules, activate it and add the new dependencies:
source security-guide-env/bin/activate # macOS/Linux
# security-guide-env\Scripts\activate # Windows
pip install openai pydantic fastapi uvicorn httpx bleach
pip install unicodedata2 # For advanced Unicode normalization (optional)
If you're starting from this module:
python -m venv security-guide-env
source security-guide-env/bin/activate
pip install openai pydantic fastapi uvicorn httpx bleach
export OPENAI_API_KEY="sk-..."
Quick check:
import unicodedata
from pydantic import BaseModel, Field
from openai import OpenAI
text = "Héllo Wörld"
normalized = unicodedata.normalize("NFKC", text)
print(f"Original: {text!r}")
print(f"Normalized: {normalized!r}")
class TestOutput(BaseModel):
answer: str = Field(min_length=1)
confidence: float = Field(ge=0.0, le=1.0)
client = OpenAI()
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Say 'Sanitization check OK'."}],
temperature=0,
)
print(response.choices[0].message.content)
# Expected output:
# Original: 'Héllo Wörld'
# Normalized: 'Héllo Wörld'
# Sanitization check OK
If you see the three outputs, your setup is ready. The key dependencies for this module are:
| Package | For what |
|---|---|
pydantic | Output validation with schemas |
fastapi | Middleware pipeline |
bleach | HTML/markdown sanitization |
httpx | Async calls to moderation APIs |
unicodedata (stdlib) | Unicode normalization |
Connection with the module project
This module closes with the Sanitization Pipeline project: a reusable FastAPI middleware that implements the complete input → output sanitization flow. It's the guide's fourth artifact and integrates directly with the Injection Defense Pipeline from Module 3.
The Sanitization Pipeline includes:
- Input Sanitizer — Unicode normalization, length limits, character whitelisting, encoding cleanup
- Output Validator — Pydantic schemas to validate the structure of LLM responses
- Content Filter — Toxicity, off-topic detection, content policy enforcement
- Guardrails Integration — Orchestration of validations with fallback strategies
- Audit Logger — Logging of each pipeline activation with metrics
The pipeline is mounted as FastAPI middleware:
Request
│
▼
┌──────────────────────────┐
│ Input Sanitizer │ ← Normalizes, cleans, validates length
├──────────────────────────┤
│ Injection Detector (M3) │ ← Your Module 3 pipeline
├──────────────────────────┤
│ LLM Processing │ ← OpenAI API call
├──────────────────────────┤
│ Output Validator │ ← Pydantic schema enforcement
├──────────────────────────┤
│ Content Filter │ ← Toxicity, off-topic, PII
├──────────────────────────┤
│ Output Sanitizer │ ← HTML escape, encoding normalization
├──────────────────────────┤
│ Audit Logger │ ← Metrics, flags, alerts
└──────────────────────────┘
│
▼
Response
In Module 8 (capstone project), the Sanitization Pipeline integrates with the Injection Defense Pipeline (M3), the Secrets Management Setup (M5), and the PII Protection Layer (M6) to form the complete secured system.
Module 1: Threat Model Document (base)
Module 2: + OWASP Mapping Audit (detailed mapping)
Module 3: + Injection Defense Pipeline (defense against LLM01)
Module 4: + Sanitization Pipeline (input/output) ← YOU PRODUCE IT HERE
Module 5: + Secrets Management Setup (credentials)
Module 6: + PII Protection Layer (sensitive data)
Module 7: + Security Audit Report (validation)
Module 8: → Secured AI System (full integration)
LLM05: Improper Output Handling — the focus of this module
This module primarily mitigates LLM05: Improper Output Handling. Understanding this vulnerability is key to everything that follows.
What LLM05 is
LLM05 happens when the application takes an LLM's output and uses it directly — without validating, without sanitizing, without verifying — in a downstream system. The LLM's output is treated as "trusted" simply because it comes from the model.
Why it's dangerous
The LLM doesn't produce deterministic outputs. It can generate:
- JavaScript in a text response → If your frontend renders HTML without escaping, you have XSS
- SQL in an "analysis" response → If your backend executes generated queries, you have SQL injection via LLM
- Malicious URLs → If your system follows generated links, you have SSRF
- Data from other users → If the context gets contaminated, you have data leakage
- Toxic or illegal content → If you don't filter, you have a reputation and compliance problem
The attack pattern
# VULNERABLE: trusting the LLM's output without validating
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": user_input}],
)
output = response.choices[0].message.content
# The output is used directly in another system
database.execute(output) # SQL injection via LLM output
template.render(content=output) # XSS via LLM output
requests.get(output) # SSRF via LLM output
# SAFE: validate and sanitize before using
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": user_input}],
)
output = response.choices[0].message.content
validated = validate_output(output) # Schema check
filtered = filter_content(validated) # Content policy
sanitized = sanitize_output(filtered) # HTML escape, encoding
# Only after the three layers is the output used
return {"answer": sanitized}
Each capsule of this module builds one piece of that validation chain.
What makes this module different vs Production Best Practices (#13)
If you completed Production Best Practices (#13), you already have basic guardrails. This module doesn't repeat that content — it deepens it significantly:
| Concept | Production Best Practices (#13) | This module (M4) |
|---|---|---|
| Input validation | "Validate length and type" | Unicode normalization, encoding attacks, character whitelisting, complete InputSanitizer class |
| Output validation | "Use Pydantic" | Structured outputs with OpenAI, retry strategies, fallback chains, nested validation, custom validators |
| Content filtering | Basic mention | Moderation API, toxicity scoring, off-topic detection, custom filters, language-specific |
| Guardrails | "What a guardrail is" | guardrails-ai framework, NeMo Guardrails, custom guardrails, chaining, performance |
| Pipeline | General concept | Complete FastAPI middleware with error handling per stage, audit logging, metrics |
| Edge cases | Not covered | Streaming, multi-modal, batch, caching, versioning |
The rule is: if something sounds familiar from #13, here you'll see the deep version, with complete code and production considerations that #13 didn't cover.
What this module does NOT cover
To keep the focus and avoid duplicating content:
- Prompt injection defense: That was Module 3. Here you complement it with sanitization, you don't replace injection detection.
- In-depth PII protection: Here you detect PII as part of the content filter (basic flag). Module 6 implements complete protection with Presidio.
- Secrets management: The API keys you use for the moderation services are protected in Module 5.
- Security testing of the pipeline: Here you build the pipeline. Module 7 tests it with adversarial inputs and pen testing.
- Legal compliance: We mention GDPR as motivation for filtering PII in outputs, not as a compliance guide.
Common mistakes when approaching sanitization
"I already have input validation, I don't need sanitization"
Input validation (Pydantic in your FastAPI endpoint) verifies types and fields — that message is a string, that user_id has the correct format. Sanitization operates on the content of the string: encoding, hidden characters, embedded HTML, length. An input can pass Pydantic validation with a perfect score and still need sanitization.
"If the model is good, the output will be good"
GPT-4o is impressive, but it doesn't guarantee safe outputs. It can produce malformed JSON if it runs out of tokens, include PII it found in the context, generate toxic content in edge cases, or fabricate URLs that look legitimate. The model's quality doesn't eliminate the need for output validation.
"Sanitizing outputs is unnecessary — I only display text"
Even if your system only displays text to the user (doesn't execute the output as code), a toxic output, one with another user's PII, or one with incorrect information presented as factual can cause reputational damage, privacy violations, or legal liability. Output sanitization isn't only technical — it's business protection.
"Guardrails add too much complexity"
Without guardrails, each developer implements their own checks ad-hoc. With guardrails as a framework, the checks are consistent, configurable, and testable. The initial complexity pays off with long-term maintainability.
"I can trust the model to moderate itself"
Instructions in the system prompt like "never generate offensive content" are a weak defense. The model tries to follow them, but it can be convinced to ignore them with creative prompts, or it can produce problematic content unintentionally. The model's moderation is one layer, not the complete defense.
Types of sanitization: input vs output
This module covers both sides of the pipeline: inputs and outputs. It's important to understand that they're different problems:
Input sanitization (capsule 02)
Operations you apply to the user's input before it reaches the LLM:
User input: "Hello\u200b <b>world</b>"
│
┌────▼─────┐
│ Unicode │ → "Hello\u200b <b>world</b>"
│ NFKC │
├──────────┤
│ Zero- │ → "Hello <b>world</b>"
│ width │
├──────────┤
│ HTML │ → "Hello world"
│ strip │
├──────────┤
│ Length │ → "Hello world" (within the limit)
│ check │
└────┬─────┘
│
Clean input to the LLM
Output sanitization (capsules 03-04)
Operations you apply to the LLM's output before it reaches the user:
LLM output: "{'answer': 'Contact john@email.com for info on <script>...'}"
│
┌────▼─────┐
│ Schema │ → Validate JSON, types, ranges
│ validate │
├──────────┤
│ Content │ → Detect PII (john@email.com)
│ filter │ Detect code injection (<script>)
├──────────┤
│ Guard- │ → Verify business policies
│ rails │
├──────────┤
│ Sanitize │ → Escape HTML, normalize encoding
│ output │
└────┬─────┘
│
Clean output to the user
The separation is clear: input sanitization protects the LLM from malformed data; output sanitization protects the user (and downstream systems) from problematic outputs.
The analogy: quality inspection in a factory
Imagine a factory that produces electronic components:
Raw material → Entry inspection → Production → Exit inspection → Packaging → Customer
The security guard at the door (Module 3) verifies that no one enters with malicious intent. But the quality inspector on the production line (this module) verifies something different:
- Entry inspection (Input Sanitization): Does the raw material have the correct specifications? Is it uncontaminated? Does it have the expected dimensions?
- Process control (Guardrails): Does the production machine operate within safe parameters?
- Exit inspection (Output Validation): Does the produced component meet the quality schema? Does it have visible defects? Does it pass the functional tests?
- Final filter (Content Filtering): Is the component safe for the customer? Does it have no sharp edges (toxic content)? Is it correctly labeled (contains no PII)?
Factory security AI security
──────────────────── ────────────────────────
Guard at the door Injection Detector (M3)
Raw material inspector Input Sanitizer (M4)
Process control Guardrails (M4)
Finished-product inspector Output Validator (M4)
Product safety filter Content Filter (M4)
Quality log Audit Logger (M4)
The guard and the inspector don't replace each other — they complement each other. A component can pass the security check (it wasn't sabotaged) but fail the quality inspection (it's out of spec). Likewise, an input can pass the injection detector (it isn't an attack) but fail sanitization (it has inconsistent encoding).
The complete pipeline as architecture
Before diving into each component (capsules 02-07), you need to see the complete flow. This diagram is the reference for the whole module:
┌──────────────────────────────────────────────────────────────────┐
│ SANITIZATION PIPELINE │
│ │
│ INPUT PHASE │
│ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ │
│ │ 1. Normalize │→ │ 2. Sanitize │→ │ 3. Validate │ │
│ │ Unicode │ │ HTML/chars │ │ Length/type │ │
│ └────────────────┘ └────────────────┘ └────────────────┘ │
│ │ │ │ │
│ │ Input Sanitizer (Cap 02) │ │
│ ├───────────────────┴───────────────────┤ │
│ │ │ │
│ ▼ │ │
│ ┌────────────────┐ │ │
│ │ 4. Injection │ ← Module 3 Pipeline │ │
│ │ Detection │ │ │
│ └────────────────┘ │ │
│ │ │ │
│ ▼ │ │
│ ┌────────────────┐ │ │
│ │ 5. LLM Call │ ← Your model (GPT-4o, etc.) │ │
│ └────────────────┘ │ │
│ │ │ │
│ OUTPUT PHASE │ │
│ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ │
│ │ 6. Validate │→ │ 7. Filter │→ │ 8. Sanitize │ │
│ │ Schema │ │ Content │ │ Output │ │
│ └────────────────┘ └────────────────┘ └────────────────┘ │
│ Output Validator Content Filter Output Sanitizer │
│ (Cap 03) (Cap 04) (Cap 02) │
│ │ │ │
│ ├───────────────────────────────────────┤ │
│ │ │ │
│ ▼ │ │
│ ┌────────────────┐ │
│ │ 9. Audit Log │ ← Log of each step │
│ └────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────┘
Each capsule builds a block of this diagram. Capsule 06 integrates them into a FastAPI middleware. Capsule 08 is the project where you implement it completely.
How to use each capsule
Each technical capsule (02-07) follows this structure:
- Context — Why this piece exists in the pipeline and what problem it solves
- Concept — The necessary theory (40% of the content)
- Implementation — Complete, runnable Python code (60% of the content)
- Connection with the project — How it fits into the Sanitization Pipeline
- Troubleshooting — 3-5 common problems with solutions
- Exercises — 4-6 practical exercises with solutions in
<details> - Summary — Key points of the topic
- Resources — 6-8 references to go deeper
I recommend following the capsules in order (02 → 07) because each one builds on the previous. Capsule 02 is pure foundation (input sanitization). Capsules 03 and 04 cover the output side. Capsule 05 introduces guardrails as an orchestration layer. Capsule 06 integrates everything. Capsule 07 tackles what you only see in production.
Trade-offs: sanitization vs user experience
A theme that runs through the whole module is the trade-off between security and usability. More sanitization = more security, but also:
- ❌ More legitimate inputs rejected (false positives)
- ❌ More latency per request (each layer adds ~5-50ms)
- ❌ More complexity in debugging (which layer did it fail at?)
- ❌ More modified outputs that lose naturalness
The goal isn't to maximize defenses — it's to calibrate each layer for your context:
| Your system | Recommended sanitization |
|---|---|
| Public chatbot | Aggressive: strict length limits, high content filter, retry on failure |
| Internal tool | Moderate: normalization, schema validation, medium content filter |
| Batch pipeline | Minimal: encoding normalization, schema validation, logging |
| Healthcare system | Maximum: all of the above + PII filter + hallucination check + audit trail |
In each capsule, you'll see the specific trade-offs of each technique with concrete data on performance and false positive rates.
The importance of LLM05 in the industry
So you understand the weight of sanitization in the professional world, LLM05 (Improper Output Handling) isn't a theoretical vulnerability. There are concrete reasons why the industry prioritizes it:
Real incidents (common patterns)
Without revealing specific names for confidentiality reasons, these are patterns of incidents documented in the industry:
| Pattern | What happened | Impact |
|---|---|---|
| XSS via LLM | A chatbot generated HTML that the frontend rendered without escaping. The model included an <img onerror> tag in its response. | Session hijacking of users |
| SQL via LLM | A "natural language to SQL" system executed queries generated by the model without validation. A creative prompt generated a DROP TABLE. | Data loss |
| PII leakage | A model with a shared context window included a previous user's data in the response to the next user. | GDPR violation, fine |
| Toxic output | A customer-service chatbot, under pressure from an insistent user, generated insults. Screenshots went viral on social media. | Massive reputational damage |
| SSRF via LLM | A model generated URLs that the backend system followed automatically. An attacker made the model generate URLs pointing to internal services. | Access to internal infrastructure |
Each of these incidents would have been prevented with a sanitization pipeline like the one you build in this module.
Regulations that require output validation
| Regulation | Relevant requirement |
|---|---|
| EU AI Act (2024) | High-risk AI systems must implement "appropriate data governance" including output validation |
| GDPR | Personal data cannot be disclosed without consent — the pipeline must filter PII in outputs |
| CCPA | Similar to GDPR for California — requires control over personal data in outputs |
| SOC 2 | "Processing Integrity" requires that outputs be complete, accurate, and authorized |
| HIPAA | Medical information in outputs of healthcare systems must be protected |
You don't need to be a regulated company to benefit from these practices. But if you are, the Sanitization Pipeline isn't optional — it's a requirement.
The cost of not sanitizing: a thought exercise
Think about your current AI system and answer these questions:
- If your model generates JavaScript in a response, does your frontend execute it? If you're not sure, it probably does.
- If your model includes a user's email in its response, do you detect it before showing it? If not, you're exposing PII.
- If your model generates a 50,000-token response, does your system handle it? If not, your frontend could crash or your token bill could explode.
- If your model says something offensive, do you filter it before the user sees it? If not, a screenshot on Twitter can go viral.
- If your model generates malformed JSON, does your downstream integration handle it? If not, you have 500 errors in production.
If you answered "no" to any of these, this module solves those problems for you. They're not hypothetical — they're the most common production bugs in AI systems.
Your system: a pre-assessment exercise
Before starting with the technical capsules, take 5 minutes to assess your current system:
- Do you normalize the encoding of inputs? → If not, capsule 02 is a priority
- Do you validate the structure of LLM outputs with schemas? → If not, capsule 03 is a priority
- Do you filter toxic or inappropriate content in outputs? → If not, capsule 04 is a priority
- Do you have guardrails beyond basic validation? → If not, capsule 05 is a priority
- Is your sanitization pipeline integrated as middleware? → If not, capsule 06 is a priority
- Do you handle streaming responses with validation? → If not, capsule 07 is a priority
If you answered "no" to the first four questions, follow the module in full order. If you already have some resolved, you can focus on the specific capsules — but even so, read the others for the advanced techniques you're probably not using.
Summary
- This module builds the data hygiene layer that complements the anti-injection defenses from Module 3 — sanitization is different from attack detection
- The main focus is LLM05: Improper Output Handling, the vulnerability that happens when you blindly trust the LLM's output without validating
- The complete pipeline covers 9 stages: normalization → sanitization → input validation → injection detection → LLM → output validation → content filter → output sanitization → audit log
- Each capsule builds a block of the pipeline: input sanitizer (02), output validator (03), content filter (04), guardrails (05), integrated pipeline (06), edge cases (07)
- This module deepens Production Best Practices (#13) — it doesn't repeat. If something sounds familiar, here you see the production version with edge cases and performance
- The central trade-off is sanitization vs user experience: more defenses = more security but more false positives and more latency
- The Sanitization Pipeline is the guide's fourth artifact and integrates with the Injection Defense Pipeline (M3) to form the secure data flow
- In Module 8, this pipeline is combined with secrets management (M5) and PII protection (M6) for the complete secured system
Next capsule: In capsule 02 you'll build the Input Sanitizer — the first line of defense that normalizes, cleans, and validates everything that enters your system before it touches the LLM. You'll see Unicode encoding attacks, character injection, and you'll build a complete, reusable InputSanitizer class.
Additional resources
- OWASP LLM05: Improper Output Handling — Official documentation of the main vulnerability this module mitigates, with attack scenarios and mitigations
- OWASP Top 10 for LLM Applications 2025 — Complete framework with the 10 vulnerabilities, reference for the whole module
- Pydantic V2 Documentation — Validators — Official Pydantic reference for advanced output validation
- OpenAI Structured Outputs — Official guide to getting structured outputs from the model, a complement to Pydantic validation
- OpenAI Moderation API — Moderation endpoint for content filtering, covered in capsule 04
- Unicode Security Considerations (Unicode.org) — Technical report on Unicode-based attacks, the basis for capsule 02
- Guardrails AI Documentation — Guardrails framework for LLM output validation, covered in capsule 05
- OWASP Input Validation Cheat Sheet — Input validation guide with principles transferable to AI
Created: March 2026 Version: 1.0