ExifTool for photo and video 5.0.1 - Local OS command injection through filenames during CSV export

8,4

High

Discovered by

Miguel Gómez

Offensive Team, Fluid Attacks

Summary

Full name

ExifTool for photo and video 5.0.1 - Local OS command injection through filenames during CSV export

Code name

State

Public

Release date

Affected product

ExifTool for photo and video

Vendor

CellHubs

Affected version(s)

5.0.1-gms

Vulnerability name

OS Command Injection

Vulnerability type

Remotely exploitable

Yes

CVSS v4.0 vector string

CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:A/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N

CVSS v4.0 base score

8.4

Exploit available

Yes

Description

ExifTool for photo and video 5.0.1-gms by CellHubs constructs shell command strings from file paths and invokes /system/bin/sh -c. In the CSV-export path, the selected media path is merely surrounded with single quotes; embedded single quotes are not escaped. A crafted filename can therefore terminate the intended shell argument and inject arbitrary shell syntax.

An attacker who can place a crafted media file in shared storage, or otherwise persuade the user to select it, can cause commands to execute as the com.exiftool.free application UID when the user exports its metadata to CSV.

Vulnerability

Root Cause

The affected code is obfuscated in classes.dex as defpackage.iz1. Its g(Application application, String str, File file) method builds this shell command:

Process processStart = d(application).command(lp0.a0(
    "/system/bin/sh", "-c",
    on0.O0(lp0.a0(
        n(application), e(application).concat("/exiftool"), "-csv",
        "'" + str + "' > '" + file.getAbsolutePath() + "'"
    ), " ", null, null, 0, new ny1(6), 30)
)).start();
Process processStart = d(application).command(lp0.a0(
    "/system/bin/sh", "-c",
    on0.O0(lp0.a0(
        n(application), e(application).concat("/exiftool"), "-csv",
        "'" + str + "' > '" + file.getAbsolutePath() + "'"
    ), " ", null, null, 0, new ny1(6), 30)
)).start();
Process processStart = d(application).command(lp0.a0(
    "/system/bin/sh", "-c",
    on0.O0(lp0.a0(
        n(application), e(application).concat("/exiftool"), "-csv",
        "'" + str + "' > '" + file.getAbsolutePath() + "'"
    ), " ", null, null, 0, new ny1(6), 30)
)).start();
Process processStart = d(application).command(lp0.a0(
    "/system/bin/sh", "-c",
    on0.O0(lp0.a0(
        n(application), e(application).concat("/exiftool"), "-csv",
        "'" + str + "' > '" + file.getAbsolutePath() + "'"
    ), " ", null, null, 0, new ny1(6), 30)
)).start();

str is the selected input media path. Wrapping it in ' is not quoting-safe: an apostrophe in the filename ends the quote, and subsequent shell metacharacters are parsed by sh -c. Neither shell escaping nor an argument-vector invocation is used for this path.

Source-to-sink path

  1. Source — attacker-controlled filename: A local attacker creates a media file in shared storage whose filename contains an apostrophe and shell syntax. Android/Linux filenames permit these characters.

  2. Application input: The user selects or imports that file through the normal application interface. The manifest also exposes ExifEditorActivity for ACTION_SEND and ACTION_SEND_MULTIPLE, which can make delivery of selected media easier, though the demonstrated CSV flow uses normal UI interaction.

  3. Unsafe command construction: iz1.g concatenates the selected path into a string for /system/bin/sh -c and does not escape apostrophes.

  4. Sink: ProcessBuilder.command("/system/bin/sh", "-c", command).start() invokes the Android shell, which parses the injected command separators and expansions.

  5. Impact: The injected command runs with the UID and granted permissions of com.exiftool.free, not as root. It may read or modify data accessible to that app and, because the build declares network access, can potentially exfiltrate accessible data.

Impact

An attacker-controlled filename can execute arbitrary shell commands with the privileges of com.exiftool.free after a user selects that file and exports metadata to CSV. Dynamic validation confirmed this by creating the benign /sdcard/osexec.txt marker through the application's normal export flow.

The command inherits the application's Android UID and its effective permissions. In the analyzed build, this can include broad shared-storage access when the user grants MANAGE_EXTERNAL_STORAGE, access to media granted by the user, and network access (INTERNET). Consequently, a successful exploit can read, modify, create, or delete files accessible to the application and may transmit accessible data over the network. It can also interfere with the CSV-export operation itself.

PoC

Preconditions

The following payload and reproduction method were supplied by the researcher. The crafted file must be placed in a shared-storage directory accessible to the application. In the submitted validation, this was done from an ADB shell:

touch "cmd_injection.jpg';cd${IFS}$EXTERNAL_STORAGE;touch${IFS}osexec.txt;#.jpg"
touch "cmd_injection.jpg';cd${IFS}$EXTERNAL_STORAGE;touch${IFS}osexec.txt;#.jpg"
touch "cmd_injection.jpg';cd${IFS}$EXTERNAL_STORAGE;touch${IFS}osexec.txt;#.jpg"
touch "cmd_injection.jpg';cd${IFS}$EXTERNAL_STORAGE;touch${IFS}osexec.txt;#.jpg"

The victim must be able to select or import the file in ExifTool for photo and video and have a writable destination directory available for the CSV export.

Step-by-step

  1. Open ExifTool for photo and video.

  2. Select or import the crafted file.

  3. Select a destination directory.

  4. Export the metadata as a CSV file.

  5. Verify that /storage/emulated/0/osexec.txt was created.

Evidence of exploitation

  • Video of exploitation:

  • Static evidence:

Our security policy

We have reserved the ID CVE-2026-101947 to refer to this issue from now on.

Disclosure policy

System Information

  • Product: ExifTool for photo and video

  • Vendor: CellHubs

  • Package: com.exiftool.free

  • Affected version: 5.0.1-gms (versionCode 82)

References

Mitigation

There is currently no patch available for this vulnerability.

Credits

The vulnerability was discovered by Andrés Ramos from Fluid Attacks' Offensive Team.

Timeline

Vulnerability discovered

Vendor contacted

Public disclosure

Does your application use this vulnerable software?

During our free trial, our tools assess your application, identify vulnerabilities, and provide recommendations for their remediation.