Detect MapLibre GL JS DOM.sanitize() XSS Sanitizer Bypass (CVE-2026-85061) in Microsoft Sentinel
Detects exploitation and presence of CVE-2026-85061, a critical (CVSS 10.0) cross-site scripting (CWE-79) sanitizer bypass in the maplibre-gl npm package (<= 6.4.0). MapLibre's DOM.sanitize() iterates over an element's live NamedNodeMap while removing attributes; because removal mutates the live collection during iteration, indices shift and dangerous attributes such as onload/onerror/href=javascript: are skipped and survive sanitization. Untrusted map content (GeoJSON feature properties, popup HTML, marker/legend content) rendered through the sanitizer can therefore inject executable script into the DOM. This detection surfaces vulnerable maplibre-gl versions in build/deploy telemetry and runtime indicators of XSS payloads delivered via map popups (event-handler attributes, javascript: URIs, and CSP violation reports referencing maplibre bundles).
MITRE ATT&CK
- Tactic
- Initial Access Execution
KQL Detection Query
// Detect XSS payloads delivered via MapLibre popup/GeoJSON content and CSP violations referencing maplibre bundles
let suspiciousAttrs = dynamic(["onload=", "onerror=", "onmouseover=", "onfocus=", "onclick=", "javascript:", "<img", "<svg", "formaction="]);
union
(
CommonSecurityLog
| where DeviceVendor has "CEF" or RequestURL has "maplibre"
| extend Payload = tostring(RequestContext)
| where Payload has_any (suspiciousAttrs)
| project TimeGenerated, SourceIP, DestinationIP, RequestURL, Payload, Signal="waf-xss-maplibre"
),
(
// CSP violation reports (ingested as custom log) naming maplibre-gl bundles
CSPViolation_CL
| where blocked_uri_s has_any ("onload", "javascript", "inline") or source_file_s has "maplibre"
| project TimeGenerated, SourceIP=client_ip_s, DestinationIP="", RequestURL=document_uri_s, Payload=blocked_uri_s, Signal="csp-violation-maplibre"
)
| order by TimeGenerated desc Surfaces WAF/proxy requests carrying MapLibre popup XSS payloads (event-handler attributes and javascript: URIs) and CSP violation reports attributed to maplibre-gl bundles, indicating a sanitizer-bypass exploit attempt against CVE-2026-85061.
Data Sources
Required Tables
False Positives & Tuning
- Security scanners (Burp, ZAP, Nuclei) probing the application with XSS test strings
- Legitimate GeoJSON feature properties that contain the literal substring 'javascript:' or 'onload' in prose descriptions
- Penetration testers validating the patch after upgrading to 6.4.1
Other platforms for CVE-2026-85061
Testing Methodology
Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1Detect vulnerable maplibre-gl version in lockfile
Expected signal: File read of lockfile; process execution of grep referencing maplibre-gl.
- Test 2Simulate XSS payload delivery via GeoJSON property
Expected signal: Outbound HTTP POST to a maplibre endpoint with a request body containing 'onerror=' and '<img'.
- Test 3Simulate javascript: URI sanitizer bypass in popup HTML
Expected signal: HTTP GET to a maplibre render endpoint whose query contains 'javascript:' and multiple event-handler attributes.
References (6)
- https://github.com/maplibre/maplibre-gl-js/security/advisories/GHSA-jrc7-96c5-q579
- https://nvd.nist.gov/vuln/detail/CVE-2026-85061
- https://github.com/maplibre/maplibre-gl-js/pull/8189
- https://github.com/maplibre/maplibre-gl-js/commit/1da69f3cd913a39fa948708e01478663bf48bc27
- https://github.com/maplibre/maplibre-gl-js/releases/tag/v6.4.1
- https://github.com/advisories/GHSA-jrc7-96c5-q579
Response Playbook
Triage
- Confirm the deployed maplibre-gl version by inspecting package-lock.json / yarn.lock and the served JS bundle; any version <= 6.4.0 is vulnerable and must be treated as exploitable.
- Determine whether the application renders untrusted content (GeoJSON feature properties, user-supplied popup/marker HTML, third-party legend content) through MapLibre popups — this is the required exploitation path.
- Review the matched request payloads for genuine XSS vectors (onload=, onerror=, javascript:, <svg onload>) versus benign strings, and correlate source IP/user against expected traffic and known scanners.
- Check browser CSP violation reports and any client-side error telemetry for inline-script executions attributed to maplibre bundles around the alert time.
Containment
- Upgrade maplibre-gl to >= 6.4.1 across all applications and redeploy; this is the authoritative fix (PR #8189 / commit 1da69f3).
- As an interim mitigation, enforce a strict Content-Security-Policy (no unsafe-inline, no inline event handlers) and server-side sanitize/escape all untrusted properties before they reach MapLibre popup/marker HTML.
- Block or rate-limit source IPs delivering confirmed XSS payloads at the WAF and disable rendering of user-controlled HTML in map popups until patched.
Evidence Collection
- Preserve full WAF/proxy request logs (URL, headers, body) for the matched events and export the served maplibre-gl bundle hash and version string.
- Capture CSP violation reports, browser console/error telemetry, and any session recordings showing script execution originating from map content.
Escalation Criteria
- !Escalate to incident response if payloads show session-token exfiltration, credential harvesting, or successful script execution (confirmed via CSP report or user report), not just probing.
- !Escalate if the vulnerable version is confirmed on an internet-facing production application that renders untrusted map content and cannot be patched within the SLA window.
Investigation Guide
Related Techniques
Forensic Artifacts
- >
Served maplibre-gl bundle version string and file hash from CDN/web root - >
package-lock.json / yarn.lock entries pinning maplibre-gl <= 6.4.0 - >
WAF/proxy request bodies containing XSS vectors and browser CSP violation report payloads
Tuning Guidance
Baseline the set of user agents and source IPs belonging to authorized DAST scanners and penetration testers and exclude them, or route their alerts to a separate low-priority queue. Constrain the URL/path filter to endpoints that actually embed maplibre-gl and render untrusted content to reduce prose-string false positives. Once all applications are confirmed on >= 6.4.1, downgrade severity to informational and retain the rule for regression detection.
Hunting Queries
Hunt for HTTP requests to maplibre-serving endpoints carrying XSS event-handler or javascript: vectors that indicate sanitizer-bypass attempts.
CommonSecurityLog | where RequestURL has "maplibre" | extend p=tostring(RequestContext) | where p matches regex @"(?i)on(load|error|mouseover)\s*=|javascript:|<svg" | project TimeGenerated, SourceIP, RequestURL, p index=web sourcetype="waf:log" uri_path="*maplibre*" | regex _raw="(?i)on(load|error|mouseover)\s*=|javascript:|<svg" | table _time src_ip uri_path _raw Atomic Red Team Tests
Greps the project lockfile for a maplibre-gl version <= 6.4.0 to confirm exposure.
Command
grep -E 'maplibre-gl@?[^0-9]*([0-5]\.[0-9]+\.[0-9]+|6\.[0-4]\.0)' package-lock.json yarn.lock 2>/dev/null || echo 'no vulnerable pin found' Cleanup
true Expected Telemetry
File read of lockfile; process execution of grep referencing maplibre-gl.
Expected Detection
Build/SCA scan flags maplibre-gl <= 6.4.0 as vulnerable to CVE-2026-85061.
Sends an HTTP request carrying an onerror event-handler XSS vector to a maplibre popup rendering endpoint in a lab.
Command
curl -s -X POST 'http://localhost:8080/map/popup' --data-urlencode 'props={"name":"<img src=x onerror=alert(document.domain)>"}' -H 'Content-Type: application/x-www-form-urlencoded' Cleanup
true Expected Telemetry
Outbound HTTP POST to a maplibre endpoint with a request body containing 'onerror=' and '<img'.
Expected Detection
WAF/proxy detection rule matches the onerror event-handler XSS vector against a maplibre-serving path.
Sends map popup HTML containing a javascript: href and a live-NamedNodeMap-skip-style multi-attribute element to emulate the DOM.sanitize() bypass.
Command
curl -s 'http://localhost:8080/map/render?html=%3Ca%20id%3Dx%20href%3Djavascript%3Aalert(1)%20onclick%3Dalert(2)%3Eclick%3C%2Fa%3E' Cleanup
true Expected Telemetry
HTTP GET to a maplibre render endpoint whose query contains 'javascript:' and multiple event-handler attributes.
Expected Detection
Detection rule matches javascript: URI and event-handler vectors in the maplibre request query.