Input Validation

Input Validation for LLM Applications

Why Validate Inputs?
Prevent attacks, ensure quality, and maintain system stability.

Validation Types
| Type | Purpose | Example |
|------|---------|---------|
| Length limits | Prevent abuse | Max 10,000 chars |
| Content filtering | Block harmful | Regex patterns |
| Format validation | Ensure structure | JSON schema |
| Rate limiting | Prevent abuse | 60 req/min |
| Encoding | Prevent injection | Unicode normalization |

Implementation

Length and Format

from pydantic import BaseModel, validator

class LLMRequest(BaseModel):
    prompt: str
    max_tokens: int = 1000

    @validator("prompt")
    def validate_prompt(cls, v):
        if len(v) > 50000:
            raise ValueError("Prompt too long")
        if len(v) < 1:
            raise ValueError("Prompt cannot be empty")
        return v

    @validator("max_tokens")
    def validate_tokens(cls, v):
        if v < 1 or v > 4096:
            raise ValueError("Invalid max_tokens")
        return v

Content Filtering

class ContentFilter:
    def __init__(self):
        self.blocklist = load_blocklist()
        self.patterns = [
            r"\b(password|api.key|secret)\b",
            r"\b(hack|exploit|pwn)\b",
        ]

    def filter(self, text):
        # Check blocklist
        lower_text = text.lower()
        for word in self.blocklist:
            if word in lower_text:
                return False, f"Blocked word: {word}"

        # Check patterns
        for pattern in self.patterns:
            if re.search(pattern, text, re.IGNORECASE):
                return False, f"Matched pattern: {pattern}"

        return True, None

Unicode Normalization

import unicodedata

def normalize_input(text):
    # Normalize unicode
    normalized = unicodedata.normalize("NFKC", text)

    # Remove zero-width characters (can hide attacks)
    zero_width = ["\u200b", "\u200c", "\u200d", "\ufeff"]
    for char in zero_width:
        normalized = normalized.replace(char, "")

    return normalized

API Moderation

from openai import OpenAI

client = OpenAI()

def check_moderation(text):
    response = client.moderations.create(input=text)
    result = response.results[0]

    if result.flagged:
        categories = [k for k, v in result.categories.dict().items() if v]
        return False, categories

    return True, None

Validation Pipeline

class InputValidator:
    def validate(self, request):
        # 1. Normalize
        text = normalize_input(request.prompt)

        # 2. Length check
        if len(text) > MAX_LENGTH:
            raise ValidationError("Too long")

        # 3. Content filter
        is_safe, reason = self.content_filter.filter(text)
        if not is_safe:
            raise ValidationError(reason)

        # 4. Moderation API
        is_allowed, categories = check_moderation(text)
        if not is_allowed:
            raise ValidationError(f"Content policy: {categories}")

        return text

Best Practices
- Validate early in request pipeline
- Use allowlists when possible
- Log validation failures
- Return clear error messages
- Combine multiple validation methods

Take input validation further

Ask the copilot about this term, or have our engineers assess it against your process.