Files
atelier/domains/security/input-validation.md
T
2026-08-05 00:30:31 +00:00

2.6 KiB

Input Validation — Derived Rules

Derives from domains/security/first-principles.md P4 (Input Validation), P5 (Output Safety).

The Rule

All input is untrusted until validated. Validation happens at the boundary, against a schema, with explicit failure modes.

Validate at the Boundary (P4 Locality)

  • The API endpoint, the controller, the message handler — the entry point validates.
  • Internal code trusts validated input. Unvalidated input never reaches the database.
  • Defense in depth: the database also has constraints (P3 Defense in Depth).

Schema Validation

  • Use a schema library (zod, joi, pydantic, json-schema). Never hand-write validation.
  • The schema is the contract. The schema is versioned. The schema is tested.
  • Reject unknown fields (additionalProperties: false by default). Be explicit.

Validation Types

Type Validation

  • id is a UUID, not a string. age is an integer ≥ 0. email matches a regex (or better, is parsed).
  • Never accept any. Never accept string for a typed value.

Range Validation

  • limit ≤ 100. page ≥ 1. quantity ≥ 1 and ≤ stock.
  • Bounds are explicit. No "unbounded" inputs.

Format Validation

  • email is parsed (not just regex). url is parsed. date is parsed.
  • A regex for email is wrong (RFC 5322 is not a regular language). Use a parser.

Semantic Validation

  • start_date < end_date. user_id exists. product_id is in stock.
  • Semantic validation may require a database lookup. That's fine.

Presence Validation

  • Required fields are present. Optional fields are absent or null.
  • Empty string "" is not the same as null. Be explicit about which you accept.

Failure Modes (P8 Fail Securely)

  • Validation failure → 400 Bad Request with a structured error (domains/api/error-responses.md).
  • Never coerce: "5" + 3 is not validation. Reject, don't guess.
  • Never default: a missing required field is an error, not a default value.

Output Safety (P5 Output Safety)

  • Validation is for input. Encoding is for output.
  • Output to HTML: HTML-encode. Output to SQL: parameterize. Output to URL: URL-encode.
  • Never trust validated input for output. Validate on the way in, encode on the way out.

What Violates Input Validation

Violation Principle
JSON.parse(req.body) with no schema P4 Input Validation
parseInt(req.query.id) with no range check P4
additionalProperties: true by default P1 Contract Fidelity
Coercing "5" to 5 silently P8 Fail Securely
SQL string interpolation (even of "validated" input) P5 Output Safety
Regex for email validation P4 (use a parser)