fontTools is Vulnerable to Arbitrary File Write and XML injection in fontTools.varLib
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.
| Package | Affected versions | Patched versions |
|---|---|---|
fonttoolsPyPI | >= 4.33.0, < 4.60.2 | 4.60.2 |
Affected products
2>=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
1a696d5ba9327varLib: only use the basename(vf.filename)
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- github.com/advisories/GHSA-768j-98cg-p3fvghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-66034ghsaADVISORY
- github.com/fonttools/fonttools/commit/a696d5ba93270d5954f98e7cab5ddca8a02c1e32ghsax_refsource_MISCWEB
- github.com/fonttools/fonttools/security/advisories/GHSA-768j-98cg-p3fvghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.