VYPR
Moderate severityNVD Advisory· Published Nov 29, 2025· Updated Dec 1, 2025

fontTools is Vulnerable to Arbitrary File Write and XML injection in fontTools.varLib

CVE-2025-66034

Description

fontTools is a library for manipulating fonts, written in Python. In versions from 4.33.0 to before 4.60.2, the fonttools varLib (or python3 -m fontTools.varLib) script has an arbitrary file write vulnerability that leads to remote code execution when a malicious .designspace file is processed. The vulnerability affects the main() code path of fontTools.varLib, used by the fonttools varLib CLI and any code that invokes fontTools.varLib.main(). This issue has been patched in version 4.60.2.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

An arbitrary file write vulnerability in fontTools varLib allows remote code execution via a malicious .designspace file, patched in version 4.60.2.

Vulnerability in fontTools varLib (CVE-2025-66034) is an arbitrary file write vulnerability that leads to remote code execution when a malicious .designspace file is processed. The root cause is unsanitised filename handling in the main() code path of code path of fontTools/varLib/__init__.py file, where the vf.filename attribute is used directly in os.path.join() without validation, allowing path traversal sequences to write files to arbitrary locations [1][2][3]. Additionally, XML injection in labelname` elements enables content injection into the output files [3]. The vulnerability affects versions from 4.33.0 to before 4.60.2 [2][3].

Exploitation

An attacker can craft a malicious .designspace file containing path traversal sequences (e.g., ../../malicious.php) in the filename attribute of a variable-font element, combined with injected content (e.g., PHP code) in labelname elements [3]. When the victim processes this file using the fonttools varLib CLI or any code that calls fontTools.varLib.main(), the library writes the attacker-controlled content to an arbitrary filesystem location [2][3]. No elevated privileges are required; the attack only requires the victim to open the malicious .designspace file [3].

Impact

Successful exploitation allows an attacker to write font files, overwrite configuration files, corrupt application files and dependencies, and achieve remote code execution [3]. If the written file is placed in a web-accessible directory and executed (e.g., as a PHP script), the attacker gains RCE [3]. From there, further privilege escalation is possible, such as overwriting /etc/passwd [3]. The attacker controls the file location, extension, and contents, enabling both RCE and denial of service through file corruption [3].

Mitigation

The vulnerability has been patched in fontTools version 4.60.2 [2][3]. The fix ensures that only the basename of vf.filename is used, preventing path traversal attacks [4]. Users should upgrade to version 4.60.2 or later immediately [2][3]. No workarounds are mentioned in the advisories.

AI Insight generated on May 19, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
fonttoolsPyPI
>= 4.33.0, < 4.60.24.60.2

Affected products

2
  • Formtools.org/Fonttoolsllm-fuzzy2 versions
    >=4.33.0, <4.60.2+ 1 more
    • (no CPE)range: >=4.33.0, <4.60.2
    • (no CPE)range: >= 4.33.0, < 4.60.2

Patches

1
a696d5ba9327

varLib: only use the basename(vf.filename)

https://github.com/fonttools/fonttoolsCosimo LupoNov 21, 2025via ghsa
3 files changed · +15 1
  • Doc/source/designspaceLib/xml.rst+5 0 modified
    @@ -752,6 +752,11 @@ The ``<variable-fonts>`` element contains one or more ``<variable-font>`` elemen
       `.ttf`) and the build tools can replace that extension with another (e.g.
       `.otf` or `.woff2`) as needed.
     
    +  .. note::
    +     This is intended to be a simple filename (basename or stem) only, not
    +     an absolute or relative path. Build tools will only use the basename
    +     component and ignore any directory separators for security reasons.
    +
     .. rubric:: Example
     
     .. code:: xml
    
  • Lib/fontTools/designspaceLib/__init__.py+5 0 modified
    @@ -1323,6 +1323,11 @@ def __init__(self, *, name, filename=None, axisSubsets=None, lib=None):
             in the document**. The file may or may not exist.
     
             If not specified, the :attr:`name` will be used as a basename for the file.
    +
    +        .. note::
    +            This is intended to be a simple filename (basename or stem) only.
    +            Build tools will only use the basename component and ignore any
    +            directory separators for security reasons.
             """
             self.axisSubsets: List[
                 Union[RangeAxisSubsetDescriptor, ValueAxisSubsetDescriptor]
    
  • Lib/fontTools/varLib/__init__.py+5 1 modified
    @@ -1562,7 +1562,11 @@ def main(args=None):
             vf_name_to_output_path[vfs_to_build[0].name] = options.outfile
         else:
             for vf in vfs_to_build:
    -            filename = vf.filename if vf.filename is not None else vf.name + ".{ext}"
    +            if vf.filename is not None:
    +                # Only use basename to prevent path traversal attacks
    +                filename = os.path.basename(vf.filename)
    +            else:
    +                filename = vf.name + ".{ext}"
                 vf_name_to_output_path[vf.name] = os.path.join(output_dir, filename)
     
         finder = MasterFinder(options.master_finder)
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.