Skip to content
atlas

Input validation

Checking every piece of data a program receives against strict rules before using it, and turning away anything that does not fit.

Draft - this entry has not been reviewed yet.

Formal

A control in which a program checks all data from outside - form fields, uploaded files, API calls - for expected type, length, format and range on the server side, preferring a list of what is allowed over a list of what is forbidden.

In plain English

Like a post office that only accepts parcels of set sizes with a proper address on them, and hands everything else straight back across the counter.

In practice

A municipality's online form for parking permits accepts a postal code only if it is exactly four digits; a request with letters or symbols in that field is turned away before it reaches the database.

Why it matters

Most attacks on software start with input the developer did not expect; checking it at the door stops many of them early, though it must be backed by safe handling further in.

How to put it into practice

The usual steps, in order. Adapt them to your organisation.

  1. Map every trust boundary where data enters the application, including form fields, query parameters, headers, cookies, API bodies, files, queue messages and replies from other services or language models.
  2. Write down the allowed type, length, format and range for each field, and keep the rules in shared validators or a JSON Schema or OpenAPI description rather than scattered through the code.
  3. Decode and normalise input, for example URL decoding and Unicode normalisation, before you validate it, so encoded variants cannot slip past the check.
  4. Validate on the server at the boundary, first the syntax and then the business meaning, and reject input that does not fit instead of trying to repair it.
  5. Bind structured input to explicit objects that reject unknown properties, and configure XML parsers with DTDs and external entities turned off.
  6. For file uploads, check the size, an allowlist of extensions and the real file signature, give each file a server-generated name and store it outside the web root.
  7. Keep the defences at the point of use as well, with parameterised queries, contextual output encoding and safe APIs.
  8. Log rejected input safely, without echoing it back unescaped, and add unit tests and fuzz tests for the validators to the build pipeline.

Common pitfalls

  • Validating only in the browser, which any HTTP client can bypass.
  • Relying on denylists of known bad strings, which alternative encodings and case tricks get around.
  • Treating validation as the fix for SQL injection or XSS instead of parameterised queries and output encoding.
  • Writing regular expressions with nested quantifiers and no length limit, which opens the door to ReDoS.

Good guides

Technical deep dive

The OWASP Input Validation Cheat Sheet distinguishes syntactic validation, which enforces the correct form of a value (a Danish CPR number is ten digits, a date parses as ISO 8601, a quantity is an integer), from semantic validation, which enforces correctness in the business context (a start date precedes the end date, a quantity is between 1 and 99, the referenced account belongs to the caller). Both should run on the server at the trust boundary, as early as possible, before the data reaches business logic or storage. Client-side checks improve usability but provide no security, because any HTTP client can bypass them. NIST SP 800-53 Rev. 5 captures the same control as SI-10 Information Input Validation, and the corresponding weakness is CWE-20 Improper Input Validation.

Allowlisting defines what is acceptable, through a type, an enumeration, a length bound, a numeric range or an anchored regular expression, and rejects everything else. Denylisting known-bad strings such as script tags or SQL keywords is brittle: attackers bypass it with alternative encodings, case changes, comments and Unicode look-alikes. Input should be decoded and canonicalised (URL decoding, Unicode normalisation such as NFC or NFKC, path resolution) before it is validated, otherwise a check on "../" can be bypassed with %2e%2e%2f or overlong encodings. Regular expressions themselves can become a denial-of-service vector: patterns with nested quantifiers can backtrack catastrophically on crafted input (ReDoS), so length limits should be applied first.

Structured inputs are best validated against a schema: JSON Schema or OpenAPI for API bodies, XSD for XML with DTDs and external entities disabled to prevent XXE, and strict binding to explicit data-transfer objects so extra properties are rejected, which also prevents mass assignment. File uploads need a size limit, an allowlist of extensions checked together with the actual content signature rather than the client-supplied Content-Type, server-generated file names and storage outside the web root.

The most important limitation is that validation is not a substitute for context-specific output handling. A string can be perfectly valid, such as the surname O'Neil or a free-text comment containing angle brackets, and still be dangerous in a SQL statement or an HTML page. Injection is prevented at the point of use through parameterised queries, contextual output encoding and safe APIs; validation reduces the attack surface and catches malformed data early. The same applies to data from internal services, databases and LLM outputs, which should be treated as untrusted when they originate outside the component's own control.

Relationships

Sources & further reading

Standards & official texts

  • NIST SP 800-53 Rev. 5 - SI-10 Information Input Validation · NIST

Where this data comes from

This entry was drafted by an AI from the sources above and has not yet been checked by a person. Treat it as a starting point, and check anything important against the sources.

See the review queueSuggest a correction on GitHubThis term as JSON

Mentioned in

Check yourself

Loading…

Atlas is in beta.