spb/ultra-sharp-agent-skills Public
Ultra-Sharp Agent Skills — a research-first skill-authoring system + 72 production-ready skills for AI agents.
Python 100%
1---2name: validating-input3description: Validates and sanitizes incoming request data at the service boundary — schema validation, type/length/range/format checks, allowlists, unknown-field rejection, and structured 422 error responses. Use when the user asks to validate request bodies, query params, headers, or uploads, add a pydantic/zod/joi schema, prevent malformed or malicious payloads, or fix a path-traversal or oversized-input issue. Do not use for login and permission decisions (implementing-authentication, implementing-authorization) or for business rules deeper than the request boundary.4---56<!--7Author: Simon-Pierre Boucher8Contact: contact@spboucher.ai9-->1011# Validating Input1213## When to use / when NOT to use14- **Use for:** request-boundary validation of bodies, params, headers, and file/path inputs; schema definitions; validation error responses.15- **Do NOT use for:** authn/authz decisions, domain/business invariants (those live in the domain layer), or output encoding (XSS is an output concern — encode at render time).1617## Core rules18191. **Validate at the boundary with the stack's schema library** — pydantic (Python), zod (TS), joi (Node legacy). Hand-rolled `if` chains drift.202. **Every field gets type + length + range + format.** Unbounded strings and numbers are bugs.21 - ✅ `name: str, min_length=1, max_length=200`22 - ❌ `name: str` — a 10 MB name is now valid233. **Allowlist over blocklist.** Enumerate what is valid (enum, regex anchored `^...$`, closed set); never try to enumerate evil.244. **Reject unknown fields** (`extra="forbid"` / `.strict()`). Silent extras become mass-assignment holes.255. **Canonicalize before validating:** trim whitespace, NFC-normalize unicode, lowercase emails — then check. Validating pre-canonical data lets `admin ` ≠ `admin` bypasses through.266. **Client-side validation is UX only.** The server re-validates everything, always.277. **Fail with a structured 422** naming every invalid field and why — one pass, not first-error-only.288. **Path and file inputs:** resolve to an absolute path and require it start with the allowed base directory; validate content-type by sniffing magic bytes, not the filename; cap upload size before reading the body.2930## Workflow31321. Define one schema per endpoint request (body, query, path params) with rule-2 constraints on every field.332. Enable unknown-field rejection and canonicalization hooks (rules 4–5).343. Wire the validation-error handler to the structured 422 format (rule 7).354. Add path/upload guards where files are involved (rule 8).365. **Validate the validator:** send a malformed payload per field class (wrong type, over-length, out-of-range, unknown field, path `../../etc/passwd`) and confirm each yields a 422/400 naming the field — never a 500. Fix and repeat until all pass.3738## Edge cases & failure modes39- **Numbers as strings** (`"42"`) → decide once: coerce (default for query params) or reject (default for JSON bodies); stay consistent.40- **Empty vs missing vs null** → distinguish explicitly in the schema; PATCH semantics need "absent = unchanged".41- **Arrays** → cap length (e.g. ≤1000 items) and validate every element, not just the container.42- **Validation library throws on deeply nested payloads** → cap request size and nesting depth at the web-server layer first.4344## References45Copy-paste patterns and gotchas: see [references/patterns.md](references/patterns.md).46