Input validation and sanitization patterns. Use when validating user input, preventing injection attacks, implementing allowlists, or sanitizing HTML/SQL/command inputs.
View on GitHubyonatangross/skillforge-claude-plugin
ork-security
January 25, 2026
Select agents to install to:
npx add-skill https://github.com/yonatangross/skillforge-claude-plugin/blob/main/plugins/ork-security/skills/input-validation/SKILL.md -a claude-code --skill input-validationInstallation paths:
.claude/skills/input-validation/# Input Validation
Validate and sanitize all untrusted input using Zod v4 and Pydantic.
## Overview
- Processing user input
- Query parameters
- Form submissions
- API request bodies
- File uploads
- URL validation
## Core Principles
1. **Never trust user input**
2. **Validate on server-side** (client-side is UX only)
3. **Use allowlists** (not blocklists)
4. **Validate type, length, format, range**
## Quick Reference
### Zod v4 Schema
```typescript
import { z } from 'zod';
const UserSchema = z.object({
email: z.string().email(),
name: z.string().min(2).max(100),
age: z.coerce.number().int().min(0).max(150),
role: z.enum(['user', 'admin']).default('user'),
});
const result = UserSchema.safeParse(req.body);
if (!result.success) {
return res.status(400).json({ errors: result.error.flatten() });
}
```
### Type Coercion (v4)
```typescript
// Query params come as strings - coerce to proper types
z.coerce.number() // "123" → 123
z.coerce.boolean() // "true" → true
z.coerce.date() // "2024-01-01" → Date
```
### Discriminated Unions
```typescript
const ShapeSchema = z.discriminatedUnion('type', [
z.object({ type: z.literal('circle'), radius: z.number() }),
z.object({ type: z.literal('rectangle'), width: z.number(), height: z.number() }),
]);
```
### Pydantic (Python)
```python
from pydantic import BaseModel, EmailStr, Field
class User(BaseModel):
email: EmailStr
name: str = Field(min_length=2, max_length=100)
age: int = Field(ge=0, le=150)
```
## Anti-Patterns (FORBIDDEN)
```typescript
// ❌ NEVER rely on client-side validation only
if (formIsValid) submit(); // No server validation
// ❌ NEVER use blocklists
const blocked = ['password', 'secret']; // Easy to miss fields
// ❌ NEVER trust Content-Type header
if (file.type === 'image/png') {...} // Can be spoofed
// ❌ NEVER build queries with string concat
"SELECT * FROM users WHERE name = '" + name + "'" // SQL injection
// ✅ ALWAYS validate server-side
const result = sc