CVE-2026-55847
Allure: Stored XSS via unescaped ANSI helper in Allure report status message/trace rendering
Allure 2 is the version 2.x branch of Allure Report, a multi-language test reporting tool. Prior to 2.39.0, the ansi.js helper at allure-generator/src/main/javascript/helpers/ansi.js passes attacker-influenced statusMessage and statusTrace values through AnsiToHtml without HTML escaping and wraps the result in Handlebars SafeString, disabling template auto-escaping in allure-generator/src/main/javascript/blocks/status-details/status-details.hbs. JunitXmlPlugin.java can populate these fields directly from crafted JUnit XML failure messages and traces, and equivalent input flows exist in the TRX, xUnit XML, xctest, and Allure1 and Allure2 plugins. When a user views the affected status details, unescaped markup executes arbitrary JavaScript in the report origin, which can expose report data and compromise sessions associated with that origin. This is an incomplete-fix case because PR 3271 escaped link helpers but did not address the ANSI helper. This issue is fixed in version 2.39.0.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- Required
What an attacker can affect
- Confidentiality
- Low
- Integrity
- Low
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
6.1
Allure: Stored XSS via unescaped ANSI helper in Allure report status message/trace rendering
Allure 2 is the version 2.x branch of Allure Report, a multi-language test reporting tool. Prior to 2.39.0, the ansi.js helper at allure-generator/src/main/javascript/helpers/ansi.js passes attacker-influenced statusMessage and statusTrace values through AnsiToHtml without HTML escaping and wraps the result in Handlebars SafeString, disabling template auto-escaping in allure-generator/src/main/javascript/blocks/status-details/status-details.hbs. JunitXmlPlugin.java can populate these fields directly from crafted JUnit XML failure messages and traces, and equivalent input flows exist in the TRX, xUnit XML, xctest, and Allure1 and Allure2 plugins. When a user views the affected status details, unescaped markup executes arbitrary JavaScript in the report origin, which can expose report data and compromise sessions associated with that origin. This is an incomplete-fix case because PR 3271 escaped link helpers but did not address the ANSI helper. This issue is fixed in version 2.39.0.
- Record
CVE-2026-55847- CVSS 3.1
- 6.1 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N - Weakness
- CWE-79
- Updated
- 2026-11-02
EUVDEUVD-2026-77688
6.1
Allure 2 is the version 2.x branch of Allure Report, a multi-language test reporting tool. Prior to 2.39.0, the ansi.js helper at allure-generator/src/main/javascript/helpers/ansi.js passes attacker-influenced statusMessage and statusTrace values through AnsiToHtml without HTML escaping and wraps the result in Handlebars SafeString, disabling template auto-escaping in allure-generator/src/main/javascript/blocks/status-details/status-details.hbs. JunitXmlPlugin.java can populate these fields directly from crafted JUnit XML failure messages and traces, and equivalent input flows exist in the TRX, xUnit XML, xctest, and Allure1 and Allure2 plugins. When a user views the affected status details, unescaped markup executes arbitrary JavaScript in the report origin, which can expose report data and compromise sessions associated with that origin. This is an incomplete-fix case because PR 3271 escaped link helpers but did not address the ANSI helper. This issue is fixed in version 2.39.0.
- Record
EUVD-2026-77688- CVSS 3.1
- 6.1 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-gx93-m64w-5m6h
6.1
Allure Report: Stored XSS via unescaped ANSI helper in status message/trace rendering
Summary
The ansi.js Handlebars helper in allure-generator passes user-controlled statusMessage and statusTrace values from test result files through the ansi-to-html library and wraps the output in Handlebars SafeString without HTML escaping. Since ansi-to-html does not escape HTML entities by default, an attacker who can influence test result content (e.g., via crafted JUnit XML failure messages) can inject arbitrary JavaScript that executes when anyone views the generated Allure report.
Details
The vulnerability is an incomplete fix — commit 4c64b19 (PR #3271) fixed XSS in linky.js and text-with-links.js by adding escapeExpression(), but the same pattern in ansi.js was not addressed.
Vulnerable sink — allure-generator/src/main/javascript/helpers/ansi.js:10-11:
export default function (input) {
return new SafeString(ansiConverter.toHtml(input));
};
The AnsiToHtml constructor at line 4 does not set escapeForHtml: true:
const ansiConverter = new AnsiToHtml({
fg: "black",
bg: "black",
newline: true,
});
The ansi-to-html library (v0.7.2) defaults escapeForHtml to false, meaning HTML entities in the input pass through unchanged. Wrapping the result in SafeString tells Handlebars to skip its auto-escaping, so the raw HTML reaches the browser.
Template usage — allure-generator/src/main/javascript/blocks/status-details/status-details.hbs:7,10:
<pre class="status-details__message"><code>{{ansi statusMessage}}</code></pre>
...
<pre class="{{b 'status-details' 'trace'}}"><code>{{ansi statusTrace}}</code></pre>
Source — plugins/junit-xml-plugin/src/main/java/io/qameta/allure/junitxml/JunitXmlPlugin.java:307-308:
result.setStatusMessage(element.getAttribute(MESSAGE_ATTRIBUTE_NAME));
result.setStatusTrace(element.getValue());
These values are read directly from XML attributes with no sanitization. The same pattern exists in TRX, xUnit XML, xctest, and Allure1/2 plugins.
Contrast with the fixed helper — linky.js (post-fix) correctly escapes before wrapping in SafeString:
const safeText = escapeExpression(text);
return new SafeString(`<a href="${safeText}" ...>${safeText}</a>`);
PoC
- Create a malicious JUnit XML test result file:
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="XSSTest" tests="1" failures="1">
<testcase name="xssPayload" classname="com.example.Test">
<failure message="<img src=x onerror=alert(document.cookie)>">
Stack trace: <img src=x onerror=alert('statusTrace_XSS')>
</failure>
</testcase>
</testsuite>
- Generate an Allure report:
allure generate /path/to/results-with-malicious-xml -o /tmp/allure-report
- Open the report and navigate to the failed test case:
allure open /tmp/allure-report
- When viewing the test's status details, the
<img onerror>payloads execute JavaScript in the viewer's browser.
Impact
- Arbitrary JavaScript execution in the browser of anyone viewing the generated Allure report
- Cookie theft, session hijacking if the report is served from a domain with active sessions (e.g., CI dashboards)
- Data exfiltration — the injected script can read the full report content and send it to an attacker-controlled server
- Attack vectors: A malicious dependency that throws crafted exception messages, a CI pipeline processing test results from untrusted pull requests, or a contributor submitting test files containing XSS payloads
- Allure reports are commonly hosted on CI/CD platforms (Jenkins, GitLab, GitHub Actions artifacts) where session cookies may be present
Recommended Fix
Configure AnsiToHtml with escapeForHtml: true to escape HTML entities while preserving ANSI-to-HTML conversion:
import AnsiToHtml from "ansi-to-html";
import {SafeString} from "handlebars/runtime";
const ansiConverter =…
- Record
GHSA-gx93-m64w-5m6h- CVSS 3.1
- 6.1 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N - Weakness
- CWE-79
- Updated
- 2026-11-02
NVD
6.1
Allure 2 is the version 2.x branch of Allure Report, a multi-language test reporting tool. Prior to 2.39.0, the ansi.js helper at allure-generator/src/main/javascript/helpers/ansi.js passes attacker-influenced statusMessage and statusTrace values through AnsiToHtml without HTML escaping and wraps the result in Handlebars SafeString, disabling template auto-escaping in allure-generator/src/main/javascript/blocks/status-details/status-details.hbs. JunitXmlPlugin.java can populate these fields directly from crafted JUnit XML failure messages and traces, and equivalent input flows exist in the TRX, xUnit XML, xctest, and Allure1 and Allure2 plugins. When a user views the affected status details, unescaped markup executes arbitrary JavaScript in the report origin, which can expose report data and compromise sessions associated with that origin. This is an incomplete-fix case because PR 3271 escaped link helpers but did not address the ANSI helper. This issue is fixed in version 2.39.0.
- Record
CVE-2026-55847- CVSS 3.1
- 6.1 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N - Weakness
- CWE-79
- Updated
- 2026-11-02
OSV
6.1
Allure: Stored XSS via unescaped ANSI helper in Allure report status message/trace rendering
Allure 2 is the version 2.x branch of Allure Report, a multi-language test reporting tool. Prior to 2.39.0, the ansi.js helper at allure-generator/src/main/javascript/helpers/ansi.js passes attacker-influenced statusMessage and statusTrace values through AnsiToHtml without HTML escaping and wraps the result in Handlebars SafeString, disabling template auto-escaping in allure-generator/src/main/javascript/blocks/status-details/status-details.hbs. JunitXmlPlugin.java can populate these fields directly from crafted JUnit XML failure messages and traces, and equivalent input flows exist in the TRX, xUnit XML, xctest, and Allure1 and Allure2 plugins. When a user views the affected status details, unescaped markup executes arbitrary JavaScript in the report origin, which can expose report data and compromise sessions associated with that origin. This is an incomplete-fix case because PR 3271 escaped link helpers but did not address the ANSI helper. This issue is fixed in version 2.39.0.
- Record
CVE-2026-55847- CVSS 3.1
- 6.1 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N - Weakness
- CWE-79
- Updated
- 2026-11-02
OSVGHSA-gx93-m64w-5m6h
6.1
Allure Report: Stored XSS via unescaped ANSI helper in status message/trace rendering
Summary
The ansi.js Handlebars helper in allure-generator passes user-controlled statusMessage and statusTrace values from test result files through the ansi-to-html library and wraps the output in Handlebars SafeString without HTML escaping. Since ansi-to-html does not escape HTML entities by default, an attacker who can influence test result content (e.g., via crafted JUnit XML failure messages) can inject arbitrary JavaScript that executes when anyone views the generated Allure report.
Details
The vulnerability is an incomplete fix — commit 4c64b19 (PR #3271) fixed XSS in linky.js and text-with-links.js by adding escapeExpression(), but the same pattern in ansi.js was not addressed.
Vulnerable sink — allure-generator/src/main/javascript/helpers/ansi.js:10-11:
export default function (input) {
return new SafeString(ansiConverter.toHtml(input));
};
The AnsiToHtml constructor at line 4 does not set escapeForHtml: true:
const ansiConverter = new AnsiToHtml({
fg: "black",
bg: "black",
newline: true,
});
The ansi-to-html library (v0.7.2) defaults escapeForHtml to false, meaning HTML entities in the input pass through unchanged. Wrapping the result in SafeString tells Handlebars to skip its auto-escaping, so the raw HTML reaches the browser.
Template usage — allure-generator/src/main/javascript/blocks/status-details/status-details.hbs:7,10:
<pre class="status-details__message"><code>{{ansi statusMessage}}</code></pre>
...
<pre class="{{b 'status-details' 'trace'}}"><code>{{ansi statusTrace}}</code></pre>
Source — plugins/junit-xml-plugin/src/main/java/io/qameta/allure/junitxml/JunitXmlPlugin.java:307-308:
result.setStatusMessage(element.getAttribute(MESSAGE_ATTRIBUTE_NAME));
result.setStatusTrace(element.getValue());
These values are read directly from XML attributes with no sanitization. The same pattern exists in TRX, xUnit XML, xctest, and Allure1/2 plugins.
Contrast with the fixed helper — linky.js (post-fix) correctly escapes before wrapping in SafeString:
const safeText = escapeExpression(text);
return new SafeString(`<a href="${safeText}" ...>${safeText}</a>`);
PoC
- Create a malicious JUnit XML test result file:
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="XSSTest" tests="1" failures="1">
<testcase name="xssPayload" classname="com.example.Test">
<failure message="<img src=x onerror=alert(document.cookie)>">
Stack trace: <img src=x onerror=alert('statusTrace_XSS')>
</failure>
</testcase>
</testsuite>
- Generate an Allure report:
allure generate /path/to/results-with-malicious-xml -o /tmp/allure-report
- Open the report and navigate to the failed test case:
allure open /tmp/allure-report
- When viewing the test's status details, the
<img onerror>payloads execute JavaScript in the viewer's browser.
Impact
- Arbitrary JavaScript execution in the browser of anyone viewing the generated Allure report
- Cookie theft, session hijacking if the report is served from a domain with active sessions (e.g., CI dashboards)
- Data exfiltration — the injected script can read the full report content and send it to an attacker-controlled server
- Attack vectors: A malicious dependency that throws crafted exception messages, a CI pipeline processing test results from untrusted pull requests, or a contributor submitting test files containing XSS payloads
- Allure reports are commonly hosted on CI/CD platforms (Jenkins, GitLab, GitHub Actions artifacts) where session cookies may be present
Recommended Fix
Configure AnsiToHtml with escapeForHtml: true to escape HTML entities while preserving ANSI-to-HTML conversion:
import AnsiToHtml from "ansi-to-html";
import {SafeString} from "handlebars/runtime";
const ansiConverter =…
- Record
GHSA-gx93-m64w-5m6h- CVSS 3.1
- 6.1 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N - Weakness
- CWE-79
- Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-55847
6.1
Allure 2 is the version 2.x branch of Allure Report, a multi-language test reporting tool. Prior to 2.39.0, the ansi.js helper at allure-generator/src/main/javascript/helpers/ansi.js passes attacker-influenced statusMessage and statusTrace values through AnsiToHtml without HTML escaping and wraps the result in Handlebars SafeString, disabling template auto-escaping in allure-generator/src/main/javascript/blocks/status-details/status-details.hbs. JunitXmlPlugin.java can populate these fields directly from crafted JUnit XML failure messages and traces, and equivalent input flows exist in the TRX, xUnit XML, xctest, and Allure1 and Allure2 plugins. When a user views the affected status details, unescaped markup executes arbitrary JavaScript in the report origin, which can expose report data and compromise sessions associated with that origin. This is an incomplete-fix case because PR 3271 escaped link helpers but did not address the ANSI helper. This issue is fixed in version 2.39.0.
- Record
UBUNTU-CVE-2026-55847- CVSS 3.1
- 6.1 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N - Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
io.qameta.allure:allure-generatorMaven |
through 2.38.1 | 2.39.0 |
io.qameta.allure:allure-generatorMaven |
before 2.39.0, plus listed versions 2.0-BETA82.0.02.0.12.1.12.10.0 Show 45 moreShow less2.11.02.12.02.12.12.13.02.13.12.13.102.13.22.13.32.13.42.13.52.13.62.13.72.13.82.13.92.14.02.15.02.16.02.16.12.17.02.17.12.17.22.17.32.18.02.18.12.19.02.2.02.20.02.20.12.21.02.22.02.22.12.22.22.22.32.22.42.23.02.23.12.24.02.24.12.25.02.26.02.27.02.28.02.29.02.32.3.1 |
2.39.0 |
allureUbuntu:18.04:LTS |
All versions, plus listed versions 0.5.0.0-1 |
None known |
allureUbuntu:20.04:LTS |
All versions, plus listed versions 0.8.3.0-3build10.8.3.0-3build20.8.3.0-3build3 |
None known |
allureUbuntu:22.04:LTS |
All versions, plus listed versions 0.9.5.0-2build1 |
None known |
allureUbuntu:24.04:LTS |
All versions, plus listed versions 0.11.0.0-1 |
None known |
allureUbuntu:26.10 |
All versions, plus listed versions 0.11.0.0-2 |
None known |
allureUbuntu:26.04:LTS |
All versions, plus listed versions 0.11.0.0-10.11.0.0-1build10.11.0.0-2 |
None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-55847 is a medium vulnerability (CVSS 6.1) in Allure-framework Allure2, published June 19, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.34%, the 27th percentile. Fixed in io.qameta.allure:allure-generator 2.39.0.
References
github.com/allure-framework/allure2/security/advisories/GHSA-gx93-m64w-5m6h
github.com/allure-framework/allure2/pull/3296
github.com/allure-framework/allure2/commit/1c5693933f519e64379f1a14eb3c7beeba7bc7cd
github.com/allure-framework/allure2/releases/tag/2.39.0
github.com/advisories/GHSA-gx93-m64w-5m6h
github.com/CVEProject/cvelistV5/tree/main/cves/2026/55xxx/CVE-2026-55847.json
Left out here: 20 versions and the rest of 2 source descriptions. The JSON record has them.