exiftool-vendored.js Argument Injection via Newline-Delimited Tag Names (CVE-2026-43893)
by Dobby153 · 2026-07-05
- Severity
- High
- CVE
- CVE-2026-43893 / GHSA-cw26-7653-2rp5
- Category
- misc
- Affected product
- exiftool-vendored (npm package, Node.js wrapper around Phil Harvey's ExifTool)
- Affected versions
- <= 35.18.0 (fixed in 35.19.0)
- Disclosed
- 2026-07-05
- Patch status
- patched
Tags
References
Archive entry
intelseclab/poc-archiveMetadata
| Field | Value |
|---|---|
| Date Added | 2026-07-05 |
| Last Updated | 2026-06 |
| Author / Researcher | Dobby153 |
| CVE / Advisory | CVE-2026-43893 / GHSA-cw26-7653-2rp5 |
| Category | misc |
| Severity | High |
| CVSS Score | 8.2 (per GHSA-cw26-7653-2rp5) |
| Status | PoC |
| Tags | exiftool, exiftool-vendored, argument-injection, arbitrary-file-write, arbitrary-file-read, nodejs, cli-wrapper, newline-injection |
| Related | N/A |
Affected Target
| Field | Value |
|---|---|
| Software / System | exiftool-vendored (npm package, Node.js wrapper around Phil Harvey’s ExifTool) |
| Versions Affected | <= 35.18.0 (fixed in 35.19.0) |
| Language / Platform | JavaScript / Node.js |
| Authentication Required | No (depends on how the application exposes tag-writing to users) |
| Network Access Required | No — local library API misuse; becomes remotely triggerable if an application passes untrusted input (e.g. uploaded file metadata fields) into exiftool.write() |
Summary
exiftool-vendored sends caller-supplied strings (tag names in the object passed to exiftool.write(), filenames, and other options) to the underlying ExifTool process via stdin, one argument per line, without filtering embedded newline/carriage-return/NUL characters. Because ExifTool treats each line of -@/stdin argument input as a separate CLI argument, an attacker-controlled tag name containing \n can inject entirely new ExifTool arguments — including -o <path> to redirect output to an arbitrary file, or -execute/-w! sequences to read an arbitrary file and write its contents into a new file. The two included PoC scripts demonstrate arbitrary file write to a path outside the intended working directory, and arbitrary local file read followed by write-out of that content, respectively.
Vulnerability Details
Root Cause
The library passes tag names and other user-controlled values into ExifTool’s -@/stdin “argfile” input format without validating for embedded \r, \n, or \0 characters. Since ExifTool reads that stream as one argument per line, a single JS-level string like "XMP-dc:Title\n-o\n../exploit\n-XMP-dc:Title" used as an object key is split by ExifTool into five distinct arguments (XMP-dc:Title, -o, ../exploit, -XMP-dc:Title), effectively smuggling a new -o <path> (output redirection) flag into the invocation. Fixed in 35.19.0 via per-site input validation against ExifTool’s tag-name grammar plus a defense-in-depth filter that rejects any argument containing \r/\n/\0.
Attack Vector
- An application built on
exiftool-vendoredaccepts user-controlled metadata field names/values (e.g. via an upload/tagging feature) and passes them intoexiftool.write(file, tags). - Attacker crafts a tag-name key containing embedded newlines that encode extra ExifTool CLI flags, e.g.
-o ../exploitto redirect ExifTool’s output file to an arbitrary relative/absolute path, or-execute -p /etc/passwd -w! leak.txtto make ExifTool read an arbitrary file via a-pprint-format template and write the result to a new file (leak.txt) in the working directory. exiftool.write()forwards this string as-is to the ExifTool process’s stdin argfile.- ExifTool parses the injected lines as legitimate additional arguments and performs the attacker-chosen file write (or file read + write-out).
Impact
Arbitrary file write to attacker-controlled paths (e.g. overwriting or creating files outside the intended output directory) and arbitrary local file read (e.g. reading /etc/passwd or other sensitive files and exfiltrating their contents into an attacker-readable output file). Depending on how the host application exposes tag-writing and what paths are reachable, this can lead to configuration tampering, information disclosure, or a foothold for further compromise (e.g. overwriting an application file that is later executed/included).
Environment / Lab Setup
Target: exiftool-vendored (npm) <= 35.18.0, Node.js runtime
Attacker: Local Node.js script invoking exiftool.write() with a crafted tag name,
or a web app that forwards user-supplied metadata fields into exiftool-vendored
Proof of Concept
PoC Script
See
poc1.jsandpoc2.jsin this folder (both operate on the sample imageintput.jpg).
| |
poc1.js sets a malicious tag-name key "XMP-dc:Title\n-o\n../exploit\n-XMP-dc:Title" when calling exiftool.write("input.jpg", tags1), causing ExifTool to write its output to ../exploit instead of the intended location. poc2.js sets a tag-name key "execute\n-p\n/etc/passwd\n-w!\nleak.txt\ninput.jpg\n-execute\n-Comment", causing ExifTool to read /etc/passwd via a print-format directive and write its contents into leak.txt alongside the image — demonstrating arbitrary local file read exfiltrated through the metadata-writing API.
Detection & Indicators of Compromise
Signs of compromise:
- New or modified files appearing outside the expected working/output directory right after a metadata-tagging feature is used.
- Application logs showing tag names containing control characters (
\n,\r,\0) or ExifTool CLI flag syntax (-o,-execute,-w!,-p). - Sensitive files (e.g.
/etc/passwd) unexpectedly readable/copied into an application’s upload or output directory.
Remediation
| Action | Detail |
|---|---|
| Primary fix | Upgrade to exiftool-vendored 35.19.0 or later, which validates tag names against ExifTool’s grammar and strips/rejects arguments containing \r, \n, or \0 |
| Interim mitigation | Never pass raw user-controlled strings as tag-name keys or filenames to exiftool.write()/related APIs without allow-listing to a known-safe character set; run ExifTool operations in a sandboxed/isolated filesystem with least-privilege file access |
References
Notes
Mirrored from https://github.com/Dobby153/CVE-2026-43893 on 2026-07-05.
| |