Input validation and parsing
13 guides tagged Input validation and parsing, grouped by topic, with the SDLC phase and role each is written for.
- SDLC phases
Application security
13 guidesDesign a safer file-upload pipeline
Treat upload receipt, content processing, storage, and later delivery as separate security decisions.
Design, Development · Developers, AppSec engineers
Constrain server-side fetches to their intended destinations
Prevent untrusted URLs from turning a preview, import, or webhook feature into access to internal services.
Design, Development · Developers, AppSec engineers
Keep untrusted values out of executable syntax
Choose a safe interface for each interpreter and bound the work performed by parsers and converters.
Development · Developers
Run external programs without command or argument injection
Run programs from an argument list with no shell, end options before user values, and keep untrusted arguments away from Windows batch files.
Development · Developers
Convert untrusted office documents and PDFs in an isolated parser
DOCX, XLSX and ODF files are ZIP archives of XML, and PDFs can carry scripts; the converters that read them are large C and C++ programs with a long CVE history. Check the package before any parser reads it, convert each document in a container with no network, no writable root and hard limits, kill it at a deadline, and re-render to pixels when people will open the result.
Design, Development · Developers, AppSec engineers, Platform engineers and SREs
Fuzz a parser and turn crashes into lasting regressions
Build a narrow harness, observe memory and resource failures, minimize the input, and test the repaired parser.
Testing · Developers, AppSec engineers
Parse bounded JSON and XML into an explicit application schema
Separate parser capabilities from schema rules, reject ambiguous and coercible inputs, and implement the boundary in a complete Python project.
Development · Developers, AppSec engineers
Keep untrusted object keys out of prototype and authority paths
Trace an actual nested-merge mutation, replace it with a narrow schema, and make authorization independent of inherited properties.
Development · Developers, AppSec engineers
Prevent NoSQL, LDAP, XPath and expression-language injection
SQL is not the only query language that receives user input. Stop MongoDB operator injection with type checks and $eq, escape LDAP filter values, pass XPath values as variables, and never evaluate SpEL or OGNL built from request data.
Development · Developers, AppSec engineers
Redirect users only to destinations you control
Check every redirect target taken from a request, so attackers cannot borrow your domain for phishing, carry OAuth tokens off-site or steer a server-side fetcher through your redirects.
Design, Development · Developers
Validate input safely and prevent regex denial of service
Find and fix exponential and quadratic regex backtracking with measured examples, choose linear-time engines or timeouts, and build allowlist validation that decodes once and rejects type confusion and parameter pollution.
Development · Developers, AppSec engineers
Consume third-party APIs safely (OWASP API10:2023)
Treat every upstream and third-party API response as untrusted input: validate it against a schema, set connect and read timeouts, cap the response size, refuse to follow redirects blindly, keep TLS verification on, and scope the credentials you hold for each provider.
Design, Development · Developers, AppSec engineers
Secure design patterns: a catalogue for insecure-design (A06)
A catalogue of reusable secure-design patterns, grouped by concern, each with when to use it, a short example and the failure it prevents: choke-point authorization, capability tokens, parse-don't-validate, safe-by-default APIs, tenant scoping, fail-closed, idempotency, and more.
Design · AppSec engineers
Practice
SSRF lab: Guard an outbound fetch against SSRF
A webhook sender fetches whatever URL the user gives it, and follows redirects. An attacker can point it at the cloud metadata service or an internal admin page, directly or through a redirect. Repair the guard so it resolves each host and refuses private addresses, in literals, encodings and redirects alike.
SQL injection lab: Separate SQL structure from data with sqlite3
A product search builds its SQL by formatting the shopping category and search term straight into the query string, so a crafted term can read other tables or return every row. Repair it to use sqlite3 parameters, while keeping the legitimate search working.
Path traversal lab: Serve an uploaded file without path traversal
A download endpoint joins the requested name onto the upload directory and opens it, so ../ or an absolute path reads files anywhere on disk, and a symlink in the directory points outside it. Repair it to resolve the final path and refuse anything outside the upload directory.
SSRF validation lab: Validate a fetch URL with ipaddress
An image importer fetches any URL a user submits, so a crafted URL reaches the cloud metadata service or an internal host, directly or through an encoded IP literal. Repair the validator so it parses the URL, resolves the host and allows only public addresses.
Open redirect lab: Return users to this site only
After sign-in, the login page redirects to whatever its next parameter says, so a link to your own domain can end on a look-alike site. Return users only to a page on this site.
File upload lab: Accept avatars without publishing pages
A profile-picture upload trusts the client’s Content-Type and file name, stores files in the public folder and serves them with the client’s type, so an SVG with a script runs in the site’s origin. Repair the upload decision.
OS command injection lab: Run git without a shell
A repository browser pastes request values into a git command line for the shell, so a semicolon starts a second command and a leading dash becomes a git option. Run git directly, with each value as one argument.
SSTI lab: Render a welcome banner without template injection
A welcome banner is built by concatenating the user’s display name into a Jinja template string, so a crafted name is evaluated as a template: it runs expressions, bypasses autoescaping and reads the render context. Repair render_welcome so the name is data, not template source.
XXE lab: Parse an uploaded invoice without resolving external entities
An invoice importer parses uploaded XML with a parser that resolves external entities, so a crafted DOCTYPE reads a local file into the response (XXE). Repair parse_invoice so the parser never resolves external entities, loads no DTD and makes no network request.
Pickle deserialization lab: Load a session token without pickle
A session loader parses JSON but falls back to pickle for “legacy” tokens, so a crafted pickle runs code when it is loaded. Repair load_token to parse JSON only and validate it against a fixed schema, and leave no path that unpickles untrusted bytes.
Open redirect
An open redirect happens when a page sends the browser to a URL taken from the request without checking where it points.
XML external entity (XXE) processing
XXE happens when a server parses XML from a client with a parser that still processes the Document Type Definition (DTD).
CSV formula injection
CSV formula injection (also called CSV or formula injection) happens when user-supplied data is written to a CSV (or TSV) export and a spreadsheet later reads a cell beginning with =, +, -, @, tab or carriage return as a live formula -- which can exfiltrate data with HYPERLINK, call DDE, or mislead the reader.
Regular-expression denial of service (ReDoS)
A regular-expression denial of service happens when untrusted input is matched against a pattern whose worst-case running time is super-linear - usually from a nested quantifier such as (X+)+, an overlapping alternation such as (a|aa)+, or a quantified group followed by something that can fail.