Mar 20, 2026·6 min read·3 visits
A critical supply chain vulnerability in skia-python Linux wheels packages an outdated libfreetype binary. This exposes consumers to CVE-2025-27363, a weaponized out-of-bounds write flaw triggered by parsing malicious font files, leading to remote code execution.
The skia-python package implicitly vendors a vulnerable version of libfreetype in its Linux wheel distributions, exposing applications to CVE-2025-27363. This underlying out-of-bounds write vulnerability allows for unauthenticated remote code execution via specially crafted font files.
The vulnerability tracked as GHSA-2mhw-8qcg-gr96 affects the skia-python package, a Python binding for the Skia Graphics Engine. The package implicitly vendors a vulnerable version of the libfreetype library in its compiled Linux wheel distributions. This vendored dependency introduces CVE-2025-27363, a high-severity out-of-bounds write vulnerability within the FreeType font parsing engine.
Attackers exploit this flaw by supplying specially crafted font files to applications utilizing skia-python for image rendering or PDF generation. Successful exploitation results in arbitrary code execution within the context of the vulnerable Python application. The vulnerability requires no user interaction and operates across the network if the application processes remote user-supplied fonts.
The inclusion of this vulnerable component transforms a C/C++ memory corruption issue into an exploitable attack vector within the Python ecosystem. Security teams must analyze their dependency trees to identify instances where skia-python introduces this risk to web applications, rendering services, or data processing pipelines.
The root cause of this supply chain vulnerability lies in the build pipeline configuration for skia-python Linux wheels. The build process utilizes a pinned version of cibuildwheel (version 2.21.3), which relies on specific manylinux container images. These base images preinstall an outdated version of the RedHat freetype package, specifically version 2.9.1-9.el8.
During the execution of the build_Linux.sh script, the build system dynamically links and vendors libfreetype from the system environment directly into the resulting Python wheel. This process creates an embedded copy of the library, typically named skia-python.libs/libfreetype-29a7443c.so.6.16.1. The explicit vendoring ensures the package remains functional across different Linux distributions but inadvertently freezes the vulnerability into the release artifact.
Because freetype exists as a transitive system dependency rather than an explicitly managed Python dependency, standard software composition analysis (SCA) tools often fail to detect the vulnerable binary inside the wheel. The build environment requires explicit updates to the freetype-devel package to ensure subsequent builds compile against a patched version.
The underlying vulnerability, CVE-2025-27363, exists in the TrueType font loading component of FreeType (src/truetype/ttgload.c). The flaw manifests during the parsing of font subglyph structures associated with TrueType GX and variable font files. The parsing logic contains a fundamental type conversion error that leads to an integer wrap-around.
The vulnerability triggers when the code assigns a signed short value to an unsigned long variable and subsequently adds a static integer value. This conversion mishandles negative values or large positive bounds, causing an arithmetic wrap-around. The resulting unsigned long value is significantly smaller than the actual required memory size for the subglyph structures.
FreeType utilizes this undersized value to allocate a heap buffer. Following the allocation, the parsing function continues to process the font file and writes up to six signed long integers into the buffer. Because the allocated buffer is too small, these writes exceed the buffer boundaries, resulting in an out-of-bounds write condition (CWE-787).
This exact mechanism enables an attacker to perform precise heap memory corruption. By manipulating the parameters within the crafted font file, the attacker controls both the size of the allocated chunk and the data written past its bounds, facilitating the overwrite of adjacent heap metadata or function pointers.
The vulnerability fundamentally relies on improper integer handling leading to an undersized memory allocation. The vulnerable code assigns a value directly from the font structure, interpreted as a signed 16-bit integer, to an unsigned memory allocation parameter without adequate bounds checking.
// Vulnerable logic pattern in ttgload.c
unsigned long buffer_size;
short subglyph_count;
// Implicit sign extension and integer wrap-around occurs here
buffer_size = (unsigned long)subglyph_count * sizeof(struct SubGlyph);
buffer = malloc(buffer_size + static_offset);The upstream patch for CVE-2025-27363, implemented in commit ef636696524b081f1b8819eb0c6a0b932d35757d, addresses the root cause by rectifying the variable types and enforcing strict upper bounds. The data types processing the subglyph counts are cast or declared strictly as unsigned types to prevent negative value wrap-around.
// Patched logic pattern in ttgload.c
unsigned long buffer_size;
unsigned short subglyph_count; // Type corrected
// Validation added to prevent overflow before allocation
if ( subglyph_count > MAX_SUBGLYPHS ) {
return FT_THROW( Invalid_Argument );
}
buffer_size = (unsigned long)subglyph_count * sizeof(struct SubGlyph);
buffer = malloc(buffer_size + static_offset);This fix successfully breaks the exploit chain by ensuring the memory allocation strictly accommodates the maximum possible subglyph structures defined in the TrueType specification. The patch applies universally across all FreeType processing pipelines, neutralizing the out-of-bounds write entirely.
Exploitation of CVE-2025-27363 requires the target application to parse a maliciously crafted font file using the vulnerable FreeType library. In the context of skia-python, this occurs when the application renders text or processes images containing embedded fonts. The attack vector is strictly data-driven and requires no prior authentication.
Public proof-of-concept exploits demonstrate the reliability of this vulnerability for achieving arbitrary code execution. Exploits target the out-of-bounds write to overwrite critical heap structures. Advanced exploit variants have successfully bypassed modern heap mitigation mechanisms, including Chrome's PartitionAlloc, highlighting the deterministic nature of the memory corruption.
The attacker typically leverages the out-of-bounds write of the six signed long integers to alter the size fields of adjacent free chunks or overwrite virtual method tables (vtable) of C++ objects residing on the heap. Once the memory corruption occurs, the exploit hijacks the execution flow during subsequent memory allocation or object destruction operations.
Organizations tracking this threat observe active weaponization in the wild, resulting in its inclusion in the CISA Known Exploited Vulnerabilities (KEV) catalog. The exploit operates silently, often crashing the underlying rendering thread if unsuccessful, which serves as an indicator of compromise for defenders analyzing application logs.
Remediation requires updating the skia-python package to version 144.0.post1 or later. This version updates the build environment to ensure the vendored libfreetype library incorporates the upstream patch for CVE-2025-27363. Administrators can verify the presence of the vulnerable library by calculating the SHA-256 hash of skia_python.libs/libfreetype*.so within their site-packages directory.
For engineering teams building skia-python from source, the build environment must contain freetype-devel version 2.9.1-10 or higher before executing the wheel compilation. Failure to update the underlying system dependencies will result in the generation of new, vulnerable artifacts despite using the latest skia-python source code.
If immediate patching is technically infeasible, organizations must implement strict input validation on all user-supplied files. Applications must reject untrusted TrueType, TrueType GX, and variable font files before they reach the skia-python processing logic. However, this workaround remains fragile and does not protect against vulnerabilities embedded within complex file formats like PDF or SVG.
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
skia-python (Linux Wheels) PyPI | < 144.0.post1 | 144.0.post1 |
freetype FreeType Project | <= 2.13.0 | 2.13.1 |
| Attribute | Detail |
|---|---|
| Vulnerability Type | Out-of-bounds Write (CWE-787) |
| CVSS v3.1 Score | 8.1 (High) |
| EPSS Probability | 76.15% |
| Attack Vector | Network (Malicious Font Parsing) |
| Exploit Status | Weaponized / Active |
| CISA KEV Status | Listed (via CVE-2025-27363) |
The software writes data past the end, or before the beginning, of the intended buffer.