CVE-2026-40179 Overview
CVE-2026-40179 is a stored cross-site scripting (XSS) vulnerability affecting Prometheus, an open-source monitoring system and time series database. The vulnerability exists in multiple components of the Prometheus web UI where metric names and label values are injected into innerHTML without proper escaping. Both the Mantine UI and old React UI are affected, with chart tooltips on the Graph page rendering metric names containing HTML/JavaScript without sanitization.
Critical Impact
An attacker who can inject malicious metrics via a compromised scrape target, remote write, or OTLP receiver endpoint can execute arbitrary JavaScript in the browser of any Prometheus user viewing the metric in the Graph UI. This can lead to configuration exfiltration, data deletion, or Prometheus shutdown depending on enabled flags.
Affected Products
- Prometheus versions 3.0 through 3.5.1
- Prometheus versions 3.6.0 through 3.11.1
- Prometheus Mantine UI and React UI components
Discovery Timeline
- 2026-04-15 - CVE-2026-40179 published to NVD
- 2026-04-15 - Last updated in NVD database
Technical Details for CVE-2026-40179
Vulnerability Analysis
The vulnerability stems from improper output encoding in the Prometheus web UI. With Prometheus v3.x defaulting to UTF-8 metric and label name validation, characters like <, >, and " are now valid in metric names and labels. This expanded character set, combined with insufficient sanitization in the UI components, creates multiple stored XSS attack surfaces.
In the old React UI, the Metric Explorer fuzzy search results use dangerouslySetInnerHTML without escaping, and heatmap cell tooltips interpolate le label values without sanitization. The Mantine UI similarly fails to escape metric names and label values in chart tooltip rendering.
Root Cause
The root cause is insufficient input sanitization when rendering user-controlled data (metric names and label values) in HTML contexts. The UI components directly interpolate these values into innerHTML without applying the escapeHTML() function consistently. The relaxation of metric and label name validation in Prometheus v3.x to support UTF-8 characters exacerbated this issue by allowing HTML metacharacters in metric names.
Attack Vector
The attack requires network access to a Prometheus instance with one of the following features enabled: remote write receiver (--web.enable-remote-write-receiver), OTLP receiver (--web.enable-otlp-receiver), or a compromised scrape target. An attacker can inject metrics containing malicious JavaScript in metric names or label values. When a legitimate Prometheus user views these metrics in the Graph UI, the JavaScript executes in their browser context.
The following patches demonstrate the fix by applying the escapeHTML() function to metric names and label values:
Mantine UI Fix (web/ui/mantine-ui/src/pages/query/uPlotChartHelpers.ts):
.filter((k) => k !== "__name__")
.map(
(k) =>
- `<div><strong>${escapeHTML(k)}</strong>: ${escapeHTML(labels[k])}</div>`
+ `<div><strong>${escapeHTML(k)}</strong>: ${escapeHTML(labels[k])}</div>`,
)
.join("")}
</div>`;
Source: GitHub Commit Details
React UI Fix (web/ui/react-app/src/pages/graph/GraphHelpers.ts):
const formatLabels = (labels: { [key: string]: string }): string => `
<div class="labels">
${Object.keys(labels).length === 0 ? '<div class="mb-1 font-italic">no labels</div>' : ''}
- ${labels['__name__'] ? `<div class="mb-1"><strong>${labels['__name__']}</strong></div>` : ''}
+ ${labels['__name__'] ? `<div class="mb-1"><strong>${escapeHTML(labels['__name__'])}</strong></div>` : ''}
${Object.keys(labels)
.filter((k) => k !== '__name__')
- .map((k) => `<div class="mb-1"><strong>${k}</strong>: ${escapeHTML(labels[k])}</div>`)
+ .map((k) => `<div class="mb-1"><strong>${escapeHTML(k)}</strong>: ${escapeHTML(labels[k])}</div>`)
.join('')}
</div>`;
return `
<div class="date">${dateTime.format('YYYY-MM-DD HH:mm:ss Z')}</div>
<div>
<span class="detail-swatch" style="background-color: ${color}"></span>
- <span>${labels.__name__ || 'value'}: <strong>${yval}</strong></span>
+ <span>${labels.__name__ ? escapeHTML(labels.__name__) : 'value'}: <strong>${yval}</strong></span>
</div>
<div class="mt-2 mb-1 font-weight-bold">${'seriesLabels' in both ? 'Trace exemplar:' : 'Series:'}</div>
${formatLabels(labels)}
Source: GitHub Commit Details
Detection Methods for CVE-2026-40179
Indicators of Compromise
- Metric names or label values containing HTML tags or JavaScript code (e.g., <script>, <img onerror=, javascript:)
- Unusual metric names with URL-encoded or UTF-8 special characters like <, >, ", or '
- Unexpected outbound connections from user browsers when accessing the Prometheus Graph UI
- User reports of strange behavior or pop-ups when viewing specific metrics
Detection Strategies
- Implement Content Security Policy (CSP) headers to detect and block inline script execution
- Monitor Prometheus ingestion logs for metrics containing HTML metacharacters
- Use browser developer tools to inspect tooltip content for unexpected script tags or event handlers
- Review remote write and OTLP receiver access logs for suspicious sources
Monitoring Recommendations
- Enable detailed access logging on remote write receiver and OTLP receiver endpoints
- Deploy web application firewalls to inspect and alert on HTML/JavaScript patterns in metric data
- Implement regular audits of scrape target configurations to ensure all targets are trusted
- Use SentinelOne Singularity to monitor for browser-based exploitation attempts on endpoints accessing Prometheus
How to Mitigate CVE-2026-40179
Immediate Actions Required
- Upgrade Prometheus to version 3.5.2 or 3.11.2 immediately
- Audit current scrape targets and remote write sources for trustworthiness
- Review enabled Prometheus flags and disable unnecessary features like --web.enable-admin-api and --web.enable-lifecycle
- Restrict network access to remote write receiver and OTLP receiver endpoints
Patch Information
The Prometheus team has released fixed versions 3.5.2 and 3.11.2 that properly escape metric names and label values before rendering in the UI. The fix applies the escapeHTML() function consistently across all affected components. For detailed patch information, see the GitHub Pull Request and GitHub Security Advisory.
Workarounds
- Ensure the remote write receiver (--web.enable-remote-write-receiver) is not exposed to untrusted sources
- Ensure the OTLP receiver (--web.enable-otlp-receiver) is not exposed to untrusted sources
- Verify that all scrape targets are trusted and not under attacker control
- Avoid enabling admin or mutating API endpoints (--web.enable-admin-api or --web.enable-lifecycle) in environments where untrusted data may be ingested
- Refrain from clicking untrusted links, particularly those containing functions such as label_replace, as they may generate poisoned label names and values
# Configuration example - Disable vulnerable features if not required
prometheus --config.file=/etc/prometheus/prometheus.yml \
--web.enable-remote-write-receiver=false \
--web.enable-otlp-receiver=false \
--web.enable-admin-api=false \
--web.enable-lifecycle=false
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

