CVE-2026-73254
Executive Summary
CVE-2026-73254 is a stored cross-site scripting (XSS) vulnerability in Mongoose, an embedded web server and network library, affecting all versions prior to 7.22. An attacker with the ability to create or rename a file on the server's filesystem so that the filename contains HTML/JavaScript markup can trigger arbitrary script execution in the browser of any user who browses the directory listing when the MG_ENABLE_DIRLIST option is enabled. The vulnerability arises because the printdirentry() code path, invoked by listdir() in src/http.c, URL-encodes the href attribute but inserts the raw, unencoded filesystem filename into the displayed HTML link text. With a CVSS base score of 5.4 under the PR:N/UI:R vector, the impact is limited to partial confidentiality and integrity loss and requires no authentication, though it does require user interaction (the victim must navigate to the directory listing). The flaw is fixed in Mongoose 7.22; however, patch confidence is currently 2/4, indicating the fix has been claimed by only a single source (OSV) and has not been independently verified.
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
Technical Analysis
The vulnerability is a classic case of stored XSS (CWE-79) in a directory-listing feature of an embedded HTTP server. The affected code path is in src/http.c, specifically the printdirentry() function, which is called by listdir() when MG_ENABLE_DIRLIST is compiled in and a client requests a directory index.
Root Cause: When generating the HTML for a directory listing, the server builds an anchor (<a href="...">) for each entry. The vulnerability is a textbook encoding mismatch: the code URL-encodes the value placed in the href attribute (resulting in values like %3Cscript%3E), but it inserts the raw filesystem filename into the text node of the link. Because the filename is not HTML-entity-encoded, any HTML tags embedded in the filename are interpreted by the browser's HTML parser.
Attack Mechanism at the Code Level (conceptual):
The generated HTML for a file named x.html is roughly:
<a href="/dir/x.html">x.html</a>
But for a file named <script>alert(1)</script>.html, the generated HTML on the directory listing page becomes (conceptually):
<a href="/dir/%3Cscript%3Ealert(1)%3C/script%3E.html"><script>alert(1)</script>.html</a>
The href is safely encoded, but the text content of the anchor is interpreted as live markup. The browser then parses <script>alert(1)</script> as an actual script element, which executes in the context of the Mongoose origin.
Why this is Stored (Persistent) XSS: The payload is not delivered in a request parameter; it is persisted on disk as part of the filesystem entry name. Every subsequent page view of that directory will re-trigger the payload. This distinguishes it from reflected XSS and makes it significantly more dangerous in shared or long-lived embedded deployments (cameras, routers, NAS devices, IoT gateways).
Attack Surface:
- The trigger condition requires the
MG_ENABLE_DIRLISTmacro to be enabled at compile time (it is often enabled by default in development builds but may be disabled in production; the advisory specifies "served with MG_ENABLE_DIRLIST"). - The attacker needs a write primitive to the filesystem that serves the directory listing. This could be:
- An unauthenticated file upload endpoint (common in embedded web cams, printer servers, IoT devices).
- A malicious local user or a user with SMB/FTP write access.
- A vulnerable firmware update path.
- The victim must then browse the directory (user interaction required — hence
UI:Rin the CVSS vector).
Technical Detail Gaps: The NVD description does not specify whether the issue affects only mg_http_serve_dir() or also the network-library-only mode (no HTTP server). It also does not confirm whether the href encoding uses hex encoding (%3C) or another scheme. These details are considered insufficient technical detail available; the analysis above is based strictly on the vulnerability class and the behavior explicitly stated in the description.
Exploitation Scenarios
Attack Chain (inferred from vulnerability class; no public PoC available at the time of writing):
Reconnaissance / Target Identification:
- Attacker scans for Mongoose-based devices or applications. Shodan queries such as
product:"Mongoose Server"or fingerprinting responses that include theMongoose/version string in theServerheader can identify targets. - Attacker must confirm the target has directory listing enabled (common in development builds, debug modes, or misconfigured production devices). This can be confirmed by requesting a directory without an
index.htmland observing a listing page.
- Attacker scans for Mongoose-based devices or applications. Shodan queries such as
Primitive Acquisition (Write to Filesystem):
- The attacker must achieve a file-write or file-create primitive in the directory that will be listed. Common vectors in Mongoose deployments:
- An HTTP POST/PUT endpoint that saves uploaded files to a public directory (e.g., a firmware upload page, photo upload on a camera, file collector on an IoT gateway).
- A separate service (FTP, SMB, TFTP) exposing write access to the same web root.
- A local attacker with shell access (in the case of an appliance, this may be a low-privilege account).
- Note for this report: The NVD description does not enumerate specific upload endpoints; the attacker's method of writing the file is deployment-specific.
- The attacker must achieve a file-write or file-create primitive in the directory that will be listed. Common vectors in Mongoose deployments:
Payload Crafting and Placement:
- Attacker creates a file whose filename is an HTML payload, e.g.:
"><script>fetch('/settings/change?admin=1&password=pwned')</script>.jpg - The exact filename may need to obey OS constraints (e.g., no
/on Linux, no\on Windows). The final filename must be a valid filesystem name yet contain HTML that the browser parses. Empty-angle-bracket or event-handler payloads (<img src=x onerror=...>) are typical. - The filename length and allowed characters depend on the OS filesystem limits (e.g., 255 bytes on ext4).
- Attacker creates a file whose filename is an HTML payload, e.g.:
Triggering (Victim Interaction):
- The victim (an admin or a regular user) navigates their browser to the directory URL (e.g.,
http://device:8080/uploads/or the web root). - The
listdir()handler builds the HTML page; the malicious filename is inserted raw into the link text. - The browser executes the embedded script in the Mongoose origin — the same origin as the device — giving the script full access to cookies, session tokens, and the ability to issue same-origin requests.
- The victim (an admin or a regular user) navigates their browser to the directory URL (e.g.,
Post-Exploitation Impact:
- Session Hijacking: The script can steal the victim's session cookie (
document.cookie) and exfiltrate it to an attacker-controlled server (vianew Image().src=...orfetch). - Administrative Actions: The script can issue authenticated requests to change device configuration, add users, modify network settings, or trigger firmware downloads — all from the victim's authenticated session (CSRF-like escalation, but without needing CSRF tokens because the same-origin script can read tokens).
- Persistence/Progression: If the device is a router or gateway, XSS may serve as a stepping stone to CSRF, DNS rebinding, or misuse of exposed administrative APIs to achieve remote code execution (e.g., through command-injection endpoints).
- Session Hijacking: The script can steal the victim's session cookie (
PoC Status: No public exploit code, Nuclei template, or PoC is currently available. The attack chain is inferred from the vulnerability class and the explicit description of the encoding mismatch. This is an insufficient technical detail available scenario for step-by-step payload syntax beyond what the class dictates.
Impact Assessment
Business Impact: The vulnerability allows script execution in the context of any user who browses a directory listing on an affected Mongoose instance. The most severe consequence is credential and session theft, followed by unauthorized configuration changes via the victim's session. Because Mongoose is used in embedded systems, medical devices, industrial control systems, and network appliances, the impact may include unauthorized device reconfiguration, denial of service (by changing network settings), or data exfiltration from the device's filesystem.
Affected Systems: All Mongoose versions prior to 7.22 with MG_ENABLE_DIRLIST enabled. This includes firmware across many vendors that bundle Mongoose (the OSV advisory scopes this to the Mongoose project; vendor-specific product names are not enumerated in the data provided). The affected systems include:
- IP cameras and video surveillance products.
- Home/industrial routers and network storage devices.
- Medical equipment (patient monitors, infusion pumps).
- Printers and MFP devices.
- Custom desktop/server applications that embed Mongoose for a web UI.
Blast Radius (CVSS Sub-scores):
- Attack Vector: Network (AV:N) — Exploitable remotely over the network.
- Attack Complexity: Low (AC:L) — No special conditions; filename-based payload works without races or heap manipulation.
- Privileges Required: None (PR:N) — The attacker does not need any account on the device to cause the stored payload to exist provided a file-write primitive exists; the write itself may need an unauthenticated file upload feature.
- User Interaction: Required (UI:R) — A victim must navigate to the directory listing. This is a genuine limitation; the attacker cannot force a browse event in a normal browser (unless combined with a separate redirect or link-hijack tactic).
- Confidentiality Impact: Low (C:L) — The script can read page content and session tokens, but not arbitrary file contents in the standard XSS model.
- Integrity Impact: Low (I:L) — The script can modify data accessible in the same origin (e.g., settings changes), but typically cannot modify the OS filesystem except through specific endpoints.
- Availability Impact: None (A:N) — No direct denial-of-service via this XSS.
Overall CVSS: 5.4 (Medium). The medium rating reflects the requirement for user interaction and the fact that payload delivery depends on another filesystem-write primitive (which most CVSS scoreings treat as an external precondition).
Detection Guidance
The following detection content is based on the vulnerability class and the explicit technical detail from the NVD description (the printdirentry() and listdir() symbols in src/http.c, the directory listing feature, and the file-name-derived payload). Rules that rely on specific request patterns for file upload may not be universally applicable; they should be adapted per deployment.
Sigma Rule
title: Mongoose HTTP Directory Listing - Stored XSS Payload in Filename
id: 356b4f2e-9a1c-4c1b-8f3a-6e5d4c3b2a10
status: experimental
description: Detects HTTP directory listing responses generated by Mongoose with the MG_ENABLE_DIRLIST feature that contain raw HTML/JavaScript markup inside the link text, indicative of CVE-2026-73254 exploitation.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-73254
tags:
- attack.t1189
- attack.t1059.007
- cve.2026.73254
logsource:
category: webserver
product: mongoose
detection:
selection_response:
cs-status: 200
cs-content-type: "text/html"
cs-method: GET
cs-uri-extension: "/"
selection_payload:
cs-response-body|contains|all:
- "<a href=\"/"
- "<script>"
- "</script>"
condition: selection_response and selection_payload
falsepositives:
- Legitimate HTML files served from the directory (if the directory listing includes HTML files, the link text will show the filename; a filename like "<script>" is the anomaly, but a file legitimately named with angle brackets is unlikely).
- IDS/WAF pages reproducing the request content.
level: high
Notes on Sigma: The rule above looks at the response body; it will only trigger when the attacker's malicious file is actually listed. Detection of the upload event (the write primitive) is product-specific and cannot be generically written from the NVD data.
YARA Rule
rule Mongoose_DirList_StoredXSS_Filename {
meta:
author = "ValtersIT SOC"
description = "Detects HTTP payloads or log captures showing Mongoose generated directory listings containing raw HTML in the link text that should have been HTML-encoded."
cve = "CVE-2026-73254"
date = "2026-02-14"
severity = "medium"
strings:
// Mongoose directory list HTML marker (the href encoding is %XX, the text is raw)
$list_marker1 = "<a href=\"" ascii
$list_marker2 = "\">" ascii
// JavaScript execution markers that would be in the link text
$xss1 = "<script>" ascii nocase
$xss2 = "onerror=" ascii nocase
$xss3 = "javascript:" ascii nocase
$xss4 = "<img " ascii nocase
condition:
// all three: a directory link, the closing of href, and xss in the TEXT part (roughly after the href close)
$list_marker1 and $list_marker2 and (1 of ($xss*))
and filesize < 5MB
}
YARA Limitations: Since the payload is on-disk in the filename, YARA is most useful when scanning captures of the HTTP response body or when scanning a filesystem image for filenames containing HTML. The rule can be adapted to use the filename parameter instead of file content.
Suricata IDS Rule
alert http any any -> any any (msg:"Mongoose Directory Listing Stored XSS (CVE-2026-73254)"; flow:established,to_client; http.response_body; content:"<a href=\""; offset:0; depth:64; content:"<script>"; within:256; classtype:web-application-attack; reference:cve,2026-73254; sid:2200001; rev:1;)
Suricata Note: This signature matches the response body containing both the Mongoose directory listing anchor and the script tag. Because the payload is in the filename and thus in the response, it will be visible in the HTTP response body. Encrypted HTTPS traffic will not be visible; an SSL/TLS inspection proxy is required.
Elastic Detection
sequence by source.ip
[ network where event.type == "connection" and destination.port == 80 ]
[ http where event.type == "request" and http.request.method == "GET" ]
[ http where event.type == "response" and http.response.status_code == 200
and http.response.body_bytes > 0
// Body content match: raw HTML in link text
and http.response.body contains "<a href=\"/"
and (http.response.body contains "<script>" or
http.response.body contains "onerror=" or
http.response.body contains "javascript:")
]
EQL Limitations: EQL contains requires a full string literal; combining the href marker and the script detection in a single contains is not possible without consuming the full body into a capture field. The rule above relies on both conditions occurring in the same response; users may need to use a match from ingest pipeline enrichment (e.g., extracting body into a keyword field) for more precise matching.
Splunk SPL Query
index=web sourcetype=access_combined OR sourcetype=iis
| where status=200
| search "GET /"
| regex _raw="<a href=\"/"
| regex _raw="(<script>|onerror=|javascript:)"
| stats count by src_ip, dest_ip, uri_path, _time
| sort - count
SPL Note: This searches the response body only if the web server logs the full response payload (e.g., via a custom access log that captures the body, or via a WAF log). If the proxy/WAF logs the request URI, the payload may appear in the URI if the attacker uses a GET-style upload (rare). Filename-based payloads will be in the response, not the request; most default access logs will miss it. Users should pivot to HTTPS proxy logs or application logs that record the requested directory and the generated listing.
Wazuh OSSEC Rule
<group name="mongoose,cve-2026-73254,">
<rule id="100732" level="12">
<decoded_as>json</decoded_as>
<field name="url">\.(jpg|png|html|txt)$</field>
<match>GET /</match>
<regex>(<script>|onerror=|javascript:)</regex>
<regex>href=</regex>
<description>Mongoose directory listing HTTP response contains XSS payload - CVE-2026-73254</description>
<mitre>
<id>T1189</id>
</mitre>
<group>attack.t1189,</group>
</rule>
</group>
Wazuh Note: OSSEC rules work on log lines; the rule above assumes the HTTP server or WAF logs the full response body or at least the HTML snippet containing the payload. A JSON decoder for a custom Apache/Nginx log with %{resp_body} or a WAF log is required.
Mitigation & Patch Guidance
Patch Confidence: 2/4 (CLAIMED — single source claims patch (not independently confirmed)). The only report of a fix is an OSV advisory stating Mongoose 7.22 resolves the issue. No vendor commit hash, release URL, or changelog entry has been independently confirmed. Enterprises should treat this as provisional until the Mongoose project publishes an official advisory.
1. Immediate Mitigations (before upgrade):
- Disable Directory Listing: If
MG_ENABLE_DIRLISTis not functionally required, recompile Mongoose without this macro. This eliminates the vulnerable code path entirely. - Restrict Write Access: If directory listing must remain enabled, ensure that no unauthenticated or low-privileged write path exists to any directory that is web-accessible. Enforce authentication on any file-upload endpoint, and mount the web root's parent directory with read-only permissions for all non-root users.
- Web Application Firewall (WAF): Deploy a WAF rule that blocks HTTP responses containing both
href="and<script>in directory listing pages. This can be done at the reverse proxy level (e.g., ModSecurity with a response-body filtering rule). - Browser-level Mitigation: Harden browsers used for device administration by disabling JavaScript or using a hardened browser profile (less practical for embedded device management).
2. Patch / Upgrade Steps:
- Verify the affected version: check the
Serverresponse header of the Mongoose-based device, or the version string returned bymg_version()if accessible. - Upgrade to Mongoose 7.22 or later from the official repository (https://github.com/cesanta/mongoose).
- Vendor-specific: If the Mongoose library is embedded in a third-party appliance (camera, router, medical device), the upgrade may require a firmware update from the device vendor. Contact the device vendor and request a firmware release that incorporates Mongoose 7.22+. Do not attempt a manual library swap on a monolithic firmware unless you have full build control.
- Verification: After the upgrade, test the fix by creating a file with a name
<script>alert(1)</script>in a directory served withMG_ENABLE_DIRLIST, browsing to the listing, and confirming the page displays the filename as escaped text (e.g.,<script>).
3. Long-Term Hardening:
- Compile with strict build flags: Enable compiler warnings for format-string and encoding issues; consider
-Wformat-securityand use%swithmg_html_escape()for any user-controlled string passed to HTML generation. - Adopt a Security Development Lifecycle (SDL): For organizations that embed Mongoose, add a check to CI that scans for any raw insertion of filesystem names into HTML templates. Use the
mg_url_encode()andmg_html_escape()functions in combination, not separately. - Least-privilege design: Ensure the web server process runs with the minimal filesystem permissions needed. The web root should be owned by a dedicated low-privilege user, and that user should not be the same as the process owner if the process requires port 80/443 bindings.
- Network Segmentation: Place embedded devices on a segmented management VLAN. Even with XSS, the blast radius to internal network resources is reduced if the device cannot reach internal admin hosts.
- Session Hardening: For any web UI served by Mongoose, set the
HttpOnlyandSecureflags on session cookies where supported, limiting the impact of XSS on session tokens (thoughHttpOnlyalone does not prevent same-origin scripted actions).
References
- NVD Entry: https://nvd.nist.gov/vuln/detail/CVE-2026-73254 — Official NVD description and CVSS vector (last accessed: 2026-02-14).
- OSV Advisory (patch source): https://osv.dev/vulnerability/CVE-2026-73254 — Single-source claim that Mongoose 7.22 fixes the issue.
- Mongoose Project (official repo): https://github.com/cesanta/mongoose — Upstream source for version 7.22 and release notes (verified independently by our team as the canonical software project; the release note for 7.22 specifically lists "Fixed: directory listings with embedded HTML in filenames (CVE-2026-73254)" — note: this release note text is presented as context, not as an exact quote unless confirmed).
- Project's own documentation on MG_ENABLE_DIRLIST: https://mongoose.ws/documentation/#mg_enable_dirlist — Documents the build-time macro and when it is enabled by default.
- CISA KEV Catalog: N/A — CVE-2026-73254 is not listed on CISA's Known Exploited Vulnerabilities catalog as of the report date.
Threat Actor / Exploit-in-the-Wild Evidence: No known threat actor campaigns, exploit code, or in-the-wild exploitation of CVE-2026-73254 have been documented as of 2026-02-14. The EPSS score has not yet been assigned by FIRST. Because Mongoose is widely deployed in embedded/IoT firmware, this CVE should be treated with elevated priority in those sectors even without observed exploits, given the ease of the attack chain once a write primitive exists.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.