In early 2022, a potentially dangerous vulnerability was found in ExifTool, a popular Perl library used for reading, writing, and editing image metadata. Cataloged as CVE-2022-23935, this bug made it possible for an attacker to execute arbitrary system commands, simply by tricking ExifTool into reading a specially crafted file name.
If you've ever used photo management tools (especially on Linux), chances are you're using ExifTool—either directly or as part of other software. So how did a tiny mistake in the code lead to such a powerful exploit? Let’s break it down in simple terms, show the vulnerable code, and explain how attackers could leverage this CVE.
What Went Wrong? The Vulnerability Explained
ExifTool processes hundreds of image formats. Sometimes, it needs to open files differently if they’re “pipes” (for example, reading compressed files through gzip). The Perl code tried to distinguish normal files from these “pipe” files by checking if the file name ended with a '|'.
Here’s the vulnerable code snippet (originally found in lib/Image/ExifTool.pm)
# Vulnerable check in ExifTool before 12.38:
if ($file =~ /\|$/) {
open($fh, $file);
}
The idea was: if the file name has a | character at the end, Perl will open it as a command, not a direct file. For example, 'gzip -dc file.gz |' would open the uncompressed file for reading. But the check wasn’t strict enough! If you provided a file name like somefile.jpg | SOME_COMMAND, this would pass the regex, and Perl would happily treat everything before | as a file and everything after as a shell command to execute.
Let’s say an attacker uploads or tricks the target into processing a file named like
innocent.jpg | id
Here, id is a harmless Linux command that shows current user info, but an attacker could use any system command.
If ExifTool tries to read metadata from this file, the open statement runs
open($fh, "innocent.jpg | id");
Perl interprets everything after the | as a command to execute, so instead of only opening the file, it runs the attacker's command.
3. Command Injection Achieved
Just by making ExifTool handle this specially-named file, you get command execution with the same privilege level as the ExifTool process. If ExifTool is run by a web application or automated script, the attacker could potentially take over the server.
How to Exploit: A Real Example
Here’s a simple demonstration for educational purposes.
Suppose you have a system running ExifTool 12.37 or earlier. You create a file with this name
"test.jpg | touch exploited.txt"
Then, you run
exiftool "test.jpg | touch exploited.txt"
If the system is vulnerable, you won’t get any metadata, but you *will* find a new file named exploited.txt in your directory, created by the injected touch command. Now imagine replacing touch exploited.txt with any harmful command you want.
The Patch: How It Was Fixed
ExifTool 12.38 fixed this bug by improving the regex logic:
# Fixed in 12.38:
if ($file =~ /^\|/ or $file =~ /\|$/ and $file !~ /\s\|$/) {
# Now, only really intended pipe commands are allowed
open($fh, $file);
}
The patch doesn’t just check for a single | anymore—now, it makes sure there’s no whitespace before the pipe, and that pipes are being used as actual command pipes, not as part of a file name.
If you use ExifTool:Update immediately to at least version 12.38.
How Serious Is This? Real-World Impact
- Any web server or application that accepts files from users and calls ExifTool with unsanitized file names could be vulnerable.
- This bug is especially dangerous if ExifTool is run with elevated privileges (for example, as root).
References and More Information
- Original CVE report
- Mitre CVE entry
- ExifTool Release Notes
- Human-readable summary on GitHub
Final Thoughts and Recommendations
CVE-2022-23935 is a textbook example of how a small, common error—like improper input validation—can lead to big security holes, especially in popular libraries. If you’re a developer, always validate file names, avoid passing user input to system commands, and keep your dependencies up to date.
Timeline
Published on: 01/25/2022 06:15:00 UTC
Last modified on: 05/19/2022 21:20:00 UTC