CVE-2025-46646
Executive Summary
CVE-2025-46646 is a security vulnerability in Artifex Ghostscript, a widely used interpreter for the PostScript language and PDF files. The flaw resides in the decode_utf8 function within base/gp_utf8.c, where overlong UTF-8 encoding sequences are mishandled. This issue exists due to an incomplete fix for a previous vulnerability, CVE-2024-46954. An attacker could potentially exploit this to cause a denial of service, or in some scenarios, achieve limited information disclosure or data manipulation. The vulnerability has a CVSS score of 4.5 (Medium), indicating a moderate risk. No public proof-of-concept (PoC) exploits or active exploitation in the wild have been reported at this time.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Ghostscript is a critical component in many Linux distributions, document processing pipelines, and web applications (e.g., for PDF thumbnail generation). A vulnerability in Ghostscript can have cascading effects across the software supply chain. Systems that process untrusted PostScript or PDF files are particularly at risk. Administrators should verify the version of Ghostscript in their base images, containerized applications, and CI/CD pipelines.
CVSS Breakdown & Threat Level
- CVSS Score: 4.5 (Medium)
- Vector: CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:L
- Attack Vector (AV): Local (AV:L) – The attacker must have local access to the system or be able to deliver a malicious file to a user.
- Attack Complexity (AC): Low (AC:L) – No special conditions are required to exploit.
- Privileges Required (PR): None (PR:N) – No authentication is needed.
- User Interaction (UI): Required (UI:R) – The victim must open a malicious file or interact with the exploit.
- Scope (S): Unchanged (S:U) – The vulnerability does not affect resources beyond the vulnerable component.
- Confidentiality (C): Low (C:L) – Limited information disclosure is possible.
- Integrity (I): Low (I:L) – Limited data modification is possible.
- Availability (A): Low (A:L) – A denial of service condition may be achieved.
Threat Level: Medium. The requirement for user interaction and local access reduces the immediate risk, but the widespread use of Ghostscript in document processing makes this a significant concern for enterprise environments.
Deep Dive & Mechanics
The vulnerability is located in the decode_utf8 function in base/gp_utf8.c. UTF-8 encoding allows for multiple representations of the same character, known as overlong encodings. For example, the ASCII character 'A' (U+0041) can be encoded as a single byte 0x41 or as an overlong two-byte sequence 0xC1 0x81. The Ghostscript code, in its attempt to fix CVE-2024-46954, did not fully validate all overlong sequences.
The incomplete fix allowed certain overlong UTF-8 sequences to bypass validation. When processed, these sequences could cause the decoder to misinterpret the byte stream, potentially leading to buffer over-reads, out-of-bounds writes, or other memory corruption issues. The specific impact depends on how the decoded string is used downstream.
The root cause is a failure to check that the number of bytes in a UTF-8 sequence matches the expected length for the decoded code point. For instance, a two-byte sequence starting with 0xC0 or 0xC1 should be rejected because they would represent code points below 0x80, which should be encoded in a single byte.
Vulnerable vs. Patched Code
Vulnerable Code (Ghostscript < 10.05.0):
The vulnerable code in base/gp_utf8.c likely had a check that was insufficient. For example, it might have checked the leading byte but not the subsequent bytes for overlong patterns.
// Vulnerable pseudo-code
int decode_utf8(const unsigned char *s, int *p) {
if (s[0] < 0x80) {
*p = s[0];
return 1;
} else if ((s[0] & 0xE0) == 0xC0) {
// Missing check for overlong: if (s[0] == 0xC0 || s[0] == 0xC1) return -1;
*p = ((s[0] & 0x1F) << 6) | (s[1] & 0x3F);
return 2;
}
// ... other cases
}
Patched Code (Ghostscript >= 10.05.0): The patched code adds explicit checks for overlong sequences.
// Patched pseudo-code
int decode_utf8(const unsigned char *s, int *p) {
if (s[0] < 0x80) {
*p = s[0];
return 1;
} else if ((s[0] & 0xE0) == 0xC0) {
// Reject overlong 2-byte sequences
if (s[0] == 0xC0 || s[0] == 0xC1) return -1;
*p = ((s[0] & 0x1F) << 6) | (s[1] & 0x3F);
return 2;
} else if ((s[0] & 0xF0) == 0xE0) {
// Reject overlong 3-byte sequences
if (s[0] == 0xE0 && (s[1] & 0xE0) == 0x80) return -1;
*p = ((s[0] & 0x0F) << 12) | ((s[1] & 0x3F) << 6) | (s[2] & 0x3F);
return 3;
} else if ((s[0] & 0xF8) == 0xF0) {
// Reject overlong 4-byte sequences
if (s[0] == 0xF0 && (s[1] & 0xF0) == 0x80) return -1;
if (s[0] == 0xF4 && s[1] > 0x8F) return -1; // Also reject beyond U+10FFFF
*p = ((s[0] & 0x07) << 18) | ((s[1] & 0x3F) << 12) | ((s[2] & 0x3F) << 6) | (s[3] & 0x3F);
return 4;
}
return -1;
}
Exploitation & Lab Setup
Red Team
Objective: Demonstrate the vulnerability by crafting a malicious PostScript file that triggers the overlong UTF-8 decoding flaw.
Lab Setup:
- Environment: A Linux virtual machine with Ghostscript version 10.04.0 (vulnerable) installed.
- Tools: Python3, a text editor, and the vulnerable Ghostscript binary.
Exploit Steps:
Create a Python script to generate a malicious PostScript file containing an overlong UTF-8 sequence.
# exploit_gen.py # Generate a PostScript file with an overlong UTF-8 sequence # Overlong encoding for 'A' (U+0041): 0xC1 0x81 overlong_a = b'\xc1\x81' ps_content = b'%!PS\n(' + overlong_a + b') ==\nquit\n' with open('malicious.ps', 'wb') as f: f.write(ps_content) print("Generated malicious.ps")Execute the exploit against the vulnerable Ghostscript.
python3 exploit_gen.py gs -q -dNOPAUSE -dBATCH malicious.psExpected Outcome: The vulnerable Ghostscript may crash (segmentation fault) or produce unexpected output, demonstrating the memory corruption. A patched version will either reject the file or safely handle the overlong sequence.
Note: This is a simplified demonstration. A real-world exploit would require more sophisticated payload engineering to achieve code execution.
Blue Team
Objective: Detect and block attempts to exploit CVE-2025-46646.
Detection Strategy:
- Monitor Ghostscript Processes: Look for crashes or abnormal terminations of
gsprocesses. - File Scanning: Scan incoming PostScript and PDF files for overlong UTF-8 sequences.
- System Logs: Review system logs for Ghostscript error messages related to UTF-8 decoding.
Hunting Queries:
- Linux Auditd: Monitor for
gsprocess crashes.ausearch -m ANOM_ABEND -x gs - Syslog: Search for Ghostscript error messages.
grep -i "utf-8\|decode_utf8\|overlong" /var/log/syslog
Indicators of Compromise (IOCs)
- File Hashes (SHA256):
malicious.ps(from the Red Team lab):e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855(placeholder, actual hash will vary)
- Network Signatures:
- PostScript files containing the byte sequence
0xC1 0x81or other overlong UTF-8 patterns.
- PostScript files containing the byte sequence
- Process Anomalies:
- Ghostscript process (
gs) crashing with a segmentation fault (SIGSEGV).
- Ghostscript process (
- Log Entries:
- Ghostscript error:
Error: /undefined in --decode_utf8--or similar.
- Ghostscript error:
Detection Engineering
YARA Rule
rule CVE_2025_46646_Overlong_UTF8 {
meta:
description = "Detects overlong UTF-8 sequences in PostScript files targeting CVE-2025-46646"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-46646"
hash = "N/A"
strings:
$overlong_2byte = { C0 [0-1] | C1 [0-1] }
$overlong_3byte = { E0 80 [0-1] }
$overlong_4byte = { F0 80 [0-1] [0-1] }
condition:
any of them
}
Sigma Rule
title: Ghostscript Overlong UTF-8 Exploitation Attempt
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects attempts to exploit CVE-2025-46646 by scanning for overlong UTF-8 sequences in PostScript files.
author: Valters IT
date: 2025/04/10
references:
- https://nvd.nist.gov/vuln/detail/CVE-2025-46646
logsource:
category: file_event
product: windows
definition: 'File creation events for .ps and .eps files'
detection:
selection:
TargetFilename|endswith:
- '.ps'
- '.eps'
# Look for overlong UTF-8 patterns in the file content (requires additional processing)
condition: selection
falsepositives:
- Legitimate files with unusual encoding (rare)
level: medium
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-46646 Ghostscript Overlong UTF-8 Exploit Attempt"; flow:to_server; content:"%!PS"; nocase; content:"|c1 81|"; distance:0; within:100; classtype:attempted-admin; sid:1000001; rev:1;)
Remediation & Mitigation
- Immediate Action: Upgrade Ghostscript to version 10.05.0 or later. This is the only complete fix.
- Debian/Ubuntu:
sudo apt update && sudo apt install ghostscript - RHEL/CentOS:
sudo yum update ghostscript - Windows: Download the latest installer from the Artifex website.
- Debian/Ubuntu:
- Workaround: If an immediate upgrade is not possible, restrict Ghostscript's access to untrusted files. Use a dedicated, sandboxed environment (e.g., Docker container with minimal privileges) for processing PostScript/PDF files.
- Network Segmentation: Ensure that systems running Ghostscript are not directly accessible from untrusted networks.
- File Validation: Implement a file validation gateway that scans for overlong UTF-8 sequences in PostScript and PDF files before they reach the Ghostscript interpreter.
- Monitoring: Deploy the YARA, Sigma, and Suricata rules provided in this report to detect exploitation attempts.
- Vendor Communication: Monitor the Artifex website and security mailing lists for further updates.
Valters IT - Securing Your Digital Frontier