4.2 Server-Side Input Boundaries: Injection, Paths, and File Handling
Injection occurs when an interpreter cannot distinguish between "syntax written by the application" and "data provided externally." SQL is just one example; shell commands, templates, LDAP, log queries, and expression languages all share this same structural vulnerability.
Parameterized Queries Separate Values from Syntax
Dangerous code:
"SELECT * FROM users WHERE email = '" + email + "'"The correct approach is to use database driver bind parameters:
SELECT id, password_hash
FROM users
WHERE email = ?Parameters represent only values and cannot alter query structure. Parameterized queries typically cannot bind table names, column names, or sort directions, these structural options should be handled by server-side enum mappings:
sort=recent → ORDER BY created_at DESC
sort=name → ORDER BY display_name ASCNever perform "escaping and concatenation" on user-supplied column names. Stored procedures are only safe if they do not dynamically construct SQL internally; ORMs may reintroduce injection risks through raw queries, string filtering, or insecure escape mechanisms.
Database accounts should follow the principle of least privilege: read-only interfaces should not use schema owners, reporting tasks should not have write permissions, and applications should not be able to access other tenants' schemas. WAFs can block some known payloads, but they cannot replace proper separation of code and data.
Shell Commands Should Not Go Through the Shell
Danger:
shell("convert " + uploadedPath + " output.png")Instead, prefer using library APIs. When process execution is unavoidable, use a parameter array and disable shell parsing:
execve("/usr/bin/convert", ["convert", validatedInput, outputPath], cleanEnv)A parameter array reduces the risk of command separator injection, but does not automatically ensure the safety of arguments passed to the target program. Filenames starting with - may be interpreted as options; some tools support reading additional input from URLs, configuration files, or response files. To mitigate this, use -- to delimit options, generate paths on the server side, enforce a strict allowlist, and run the process in a low-privilege sandbox.
Templates Must Distinguish Between Presentation and Code Templates
Treating user input as template data can usually be safely escaped. However, allowing users to control the template source code introduces the risk of Server-Side Template Injection, which could allow reading of process objects, environment variables, or even execution of arbitrary commands.
render(trustedTemplate, { displayName: untrustedValue }) ✓
render(untrustedTemplateSource, model) ⚠️ High riskWhen user-controlled templates are absolutely necessary, use a restricted template language designed for untrusted input, a fixed set of safe functions, resource limits, and process isolation. Simply removing a few dangerous keywords is insufficient to establish a secure sandbox.
Path normalization cannot rely on string prefixes
Common issues with download interfaces:
/download?file=../../etc/passwdSecurity design should prioritize having clients submit opaque object IDs that are then mapped to storage objects by the server database, rather than accepting filesystem paths directly. If relative paths must be processed, the following steps should be taken:
- Perform a clear decoding of the input and reject null bytes and invalid formats;
- Resolve the canonical path under a fixed root directory;
- Verify that the resulting path remains within the root directory, paying attention to path separators and case sensitivity rules;
- Prevent symlink traversal and mitigate TOCTOU (Time-of-Check to Time-of-Use) vulnerabilities through checks and replacements;
- Leverage platform capabilities such as directory file descriptors and secure open flags to reduce race conditions.
A simple string concatenation startsWith(root) will incorrectly treat /srv/uploads-evil as part of the internal path /srv/uploads.
File Upload is a Content Processing Pipeline
File extensions and browser Content-Type are controlled by the client. The upload service must enforce:
- Limits on file size, quantity, compression ratio, and processing duration;
- Checks for allowed MIME types via magic bytes and full parsing;
- Server-generated object names stored outside the web root or in a separate object store;
- Secure
Content-Type,Content-Disposition, andnosniffsettings when serving files for download; - Encoding and transcoding of images, documents, and media in isolated, low-privilege sandboxes with constrained resources;
- Malware scanning as an additional safeguard, not as the sole security boundary;
- Use of a separate origin for public content to prevent uploaded HTML from gaining access to the main site’s privileges.
Zip slip, zip bombs, and parser vulnerabilities demonstrate that "storing files without executing them" is not equivalent to security.
Untrusted Deserialization Can Restore Behavior
Some object serialization formats can specify types, constructors, or gadget chains. Do not deserialize untrusted native object graphs from sources such as cookies, queues, caches, or uploaded files. Prefer schema-based formats that explicitly represent data, restrict field and type definitions, and enforce limits on depth, length, and nested structures.
A signature only proves that data originated from a party holding the key; if multiple low-trust services share the same signing key, any one of them could construct a dangerous object. Secure formats and minimal parsing capabilities cannot be substituted by signatures alone.
Exceptional Paths Must Also Maintain Boundaries
When parsing fails, do not fall back to a "compatibility mode" that re-executes the original string. Never return database errors, command stderr, absolute paths, or stack traces to external users. Log an internal correlation ID, provide the client with a consistent error model, and monitor for abnormal exception rates.
OWASP Top 10:2025 lists "Mishandling of Exceptional Conditions" as its standalone A10 entry, emphasizing that security design must not rely solely on handling successful paths.
References
- OWASP, SQL Injection Prevention Cheat Sheet
- OWASP, OS Command Injection Defense
- OWASP, File Upload Cheat Sheet
- OWASP, Top 10:2025