Input Validation & Output Encoding
Principles
Section titled “Principles”- Treat all input from outside your trust boundary as untrusted: request bodies, query params, headers, cookies, file uploads, webhook payloads, and data from third-party APIs.
- Validate at the boundary (as early as possible), and encode/escape at the point of use (as close to the sink as possible). Validation and encoding solve different problems and neither substitutes for the other.
- Prefer allow-lists (accept known-good patterns) over deny-lists (block known-bad patterns).
Injection
Section titled “Injection”- SQL — use parameterized queries or an ORM’s query builder. Never build SQL via string concatenation with user input.
- Command execution — avoid shelling out with user-controlled input. If unavoidable, use an API that takes arguments as an array rather than a single interpolated string, and validate strictly.
- NoSQL / query languages — the same rule applies: use the driver’s parameterized/query-builder API, don’t interpolate.
Cross-site scripting (XSS)
Section titled “Cross-site scripting (XSS)”- Use your framework’s default templating/escaping (React, Vue, and most modern frameworks escape by default) — don’t disable it (
dangerouslySetInnerHTML,v-html,|safe) unless the content is trusted and sanitized. - If you must render user-supplied HTML, sanitize it with a maintained library (e.g. DOMPurify) using an allow-list of tags/attributes.
- Set a
Content-Security-Policyheader as defense in depth.
File uploads
Section titled “File uploads”- Validate file type by content (magic bytes), not just the extension or the client-supplied MIME type.
- Store uploads outside the web root or in object storage, and serve them from a separate domain/subdomain if they can contain user-controlled HTML/JS.
- Enforce a maximum file size and scan for malware where feasible.
Deserialization
Section titled “Deserialization”- Avoid deserializing untrusted data with formats/libraries that support arbitrary object instantiation or code execution (e.g. Python
pickle, PHPunserialize, Java native serialization) unless the source is fully trusted. - Prefer plain data formats (JSON, protobuf with a fixed schema) for untrusted input.