input validation Shipped
What this lens looks for
Never trust client input — client-side validation is a UX feature, not a security control, and all validation must be duplicated server-side. Prefer allowlists over denylists: validation should define what is valid, not what is invalid, since denylists have gaps. Apply validate, sanitize, escape in that order — validation rejects, sanitization cleans, and escaping is context-specific output encoding for HTML, URL, SQL, and JS. Parameterized queries must be used as the only reliable defense against SQL injection; user input must never be concatenated into queries. Output encoding is context-dependent (HTML-encode for HTML, URL-encode for URLs); lean on framework auto-escaping (React JSX, Django templates) but recognize where it does not apply, such as raw HTML insertion APIs, and always sanitize those first with a library like DOMPurify. For file uploads, validate MIME type server-side (not just the extension), limit size, store outside the web root, and never serve files with their original filename or from the same origin. At the server-render / server-action deserialization boundary, where client-controlled input is reconstructed and executed in a trusted context: schema-validate and type-check untrusted input crossing that boundary (RSC Server Action arguments, the RSC Flight payload, or any equivalent serialized request body) before use, because the serialization layer is not a validation layer; server-rendered output must not embed secrets, credentials, or internal-only data, since the payload is sent to the client; render and server-action endpoints should be rate-limited to bound the cost of crafted or repeated requests; and the rendering framework must be pinned to a version carrying current security patches for its serialization boundary.
What its verifier checks
Server-side validation exists independently of any client-side checks; validation uses allowlists rather than denylists; the validate-then-sanitize-then-escape order is followed; database access uses parameterized queries with no user input concatenated into query strings; output encoding is context-specific, framework auto-escaping is relied on where it applies, and raw HTML insertion is sanitized (e.g., DOMPurify) first; file uploads validate MIME type server-side, limit size, store outside the web root, and are not served under the original filename or same origin; input crossing a server-side deserialization boundary (Server Action arguments, Flight payload, or serialized body) is schema-validated and type-checked before use; server-rendered output embeds no secrets, credentials, or internal-only data; render and server-action endpoints are rate-limited; the rendering framework is pinned to a security-patched version.