GitHub Security Advisory: GHSA-6g2v-66ch-6xmh
Package: librenms/librenms (COMPOSER)
Severity: LOW (CVSS 3.8)
CWE: CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
Vulnerable versions: <= 25.8.0
Patched in: 25.10.0

Summary: LibreNMS alert-rules has a Cross-Site Scripting Vulnerability

Details:
## Executive Summary

**Product:** LibreNMS  
**Vendor:** LibreNMS  
**Vulnerability Type:** Cross-Site Scripting (XSS)  
**CVSS Score:** 4.3 (AV:N/AC:L/PR:H/UI:R/S:U/C:L/I:L/A:L)  
**Affected Version:** 25.8.0 (latest at time of discovery)  
**POC File:** [Download POC](https://trendmicro-my.sharepoint.com/:u:/p/kholoud_altookhy/EQYQOiGddUtOtz6739YUFU4B5FkNob_TvKBYEA8P6lSRQw?e=lDOR5W)
**Ticket:** ZDI-CAN-28105: LibreNMS Alert Rules Cross-Site Scripting Vulnerability

## Vulnerability Details

### Description
Trend Micro's Zero Day Initiative has identified a Cross-Site Scripting vulnerability in LibreNMS. The vulnerability exists in the Alert Rules functionality where the alert rule name is not properly sanitized, allowing injection of HTML code.

### Technical Details

**Version Tested:** 25.8.0  
**Installer File:** 25.8.0.tar.gz  
**Download Link:** https://github.com/librenms/librenms/archive/refs/tags/25.8.0.tar.gz  
**Platform:** N/A

### Attack Vector
When browsing to **Alerts > Alert Rules** page, a LibreNMS admin can add and manage alert rules. The alert rule name field is vulnerable to XSS attacks through improper sanitization.

## Root Cause Analysis

### Vulnerable Request
When creating or updating an alert rule, the following HTTP POST request is sent to `/ajax_form.php`:

 ```
POST /ajax_form.php HTTP/1.1
...

_token=9YjTntCuMIe2ujpumwqJQoENRXUhJzlDt33Xu7kx&device_id=-1&device_name=&rule_id=&type=alert-rules&template_id=&builder_json=%7B%22condition%22%3A%22AND%22%2C%22rules%22%3A%5B%7B%22id%22%3A%22access_points.accesspoint_id%22%2C%22field%22%3A%22access_points.accesspoint_id%22%2C%22type%22%3A%22string%22%2C%22input%22%3A%22text%22%2C%22operator%22%3A%22equal%22%2C%22value%22%3A%2242%22%7D%5D%2C%22valid%22%3Atrue%7D&name=%3Ci%3Efoo%3C%2Fi%3E&builder_rule_0_filter=access_points.accesspoint_id&builder_rule_0_operator=equal&builder_rule_0_value_0=42&severity=warning&count=1&delay=1m&interval=5m&recovery=on&acknowledgement=on&proc=&notes=&adv_query=
```

### Code Flow

1. **Request Processing:** PHP script `includes/html/forms/alert-rules.inc.php` processes the request
2. **Sanitization Attempt:** Calls `strip_tags()` to sanitize the `name` parameter
3. **Database Operation:** Calls `dbUpdate()` or `dbInsert()` to save the rule

### Bypass Technique
The sanitization can be bypassed using XML character references:

```html
&lt;script>alert(1)&lt;/script>
```

### Execution Path

1. **Page Load:** Victim browses to Alerts > Alert Rules page
2. **Script Execution:** `includes/html/print-alert/rules.php` is called
3. **Modal Inclusion:** Includes `includes/html/modal/alert_rule_list.inc.php` which returns HTML for modal window
4. **Table Rendering:** Modal contains HTML table with all rules and inline JavaScript calling `bootgrid()` function
5. **XSS Trigger:** The `bootgrid()` function (http://www.jquery-bootgrid.com/) rewrites table cells, decoding XML character references
6. **Code Execution:** Browser interprets the decoded payload