CVE-2026-85061 Google Chronicle · YARA-L

Detect MapLibre GL JS DOM.sanitize() XSS Sanitizer Bypass (CVE-2026-85061) in Google Chronicle

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

YARA-L Detection Query

Google Chronicle (YARA-L)
yaral
rule maplibre_xss_sanitizer_bypass_cve_2026_85061 {
  meta:
    author = "argus"
    description = "MapLibre GL JS DOM.sanitize() XSS bypass exploitation (CVE-2026-85061)"
    severity = "CRITICAL"
    cve = "CVE-2026-85061"
  events:
    $e.metadata.event_type = "NETWORK_HTTP"
    (
      re.regex($e.network.http.parsed_user_agent.raw, `.*`) or
      $e.target.url = /maplibre/ nocase
    )
    (
      $e.network.http.parsed_user_agent.raw = /placeholder/ or
      re.regex($e.target.url, `(?i)(on(error|load|mouseover|click)\s*=|javascript:|<svg|formaction=)`) or
      re.regex($e.network.http.response.request_body, `(?i)(on(error|load)\s*=|javascript:|<svg onload)`)
    )
  condition:
    $e
}
critical severity medium confidence

YARA-L rule flagging Chronicle NETWORK_HTTP events to maplibre endpoints containing XSS event-handler or javascript: vectors consistent with the sanitizer bypass.

Data Sources

Chronicle NETWORK_HTTPWeb proxy UDM events

Required Tables

network_http

False Positives & Tuning

  • Scanner XSS fuzzing traffic
  • Legitimate map content with embedded HTML tokens
  • Security validation testing

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.

  1. Test 1Detect vulnerable maplibre-gl version in lockfile

    Expected signal: File read of lockfile; process execution of grep referencing maplibre-gl.

  2. 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'.

  3. 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.


Response Playbook

Triage

  1. 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.
  2. 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.
  3. 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.
  4. Check browser CSP violation reports and any client-side error telemetry for inline-script executions attributed to maplibre bundles around the alert time.

Containment

  1. Upgrade maplibre-gl to >= 6.4.1 across all applications and redeploy; this is the authoritative fix (PR #8189 / commit 1da69f3).
  2. 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.
  3. 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

  1. Preserve full WAF/proxy request logs (URL, headers, body) for the matched events and export the served maplibre-gl bundle hash and version string.
  2. 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.

Hunting — KQL
kql
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
Hunting — SPL
spl
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

Test 1 Detect vulnerable maplibre-gl version in lockfile
linux

Greps the project lockfile for a maplibre-gl version <= 6.4.0 to confirm exposure.

Command

bash
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

bash
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.

Test 2 Simulate XSS payload delivery via GeoJSON property
linux

Sends an HTTP request carrying an onerror event-handler XSS vector to a maplibre popup rendering endpoint in a lab.

Command

bash
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

bash
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.

Test 3 Simulate javascript: URI sanitizer bypass in popup HTML
linux

Sends map popup HTML containing a javascript: href and a live-NamedNodeMap-skip-style multi-attribute element to emulate the DOM.sanitize() bypass.

Command

bash
curl -s 'http://localhost:8080/map/render?html=%3Ca%20id%3Dx%20href%3Djavascript%3Aalert(1)%20onclick%3Dalert(2)%3Eclick%3C%2Fa%3E'

Cleanup

bash
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.

Related Detections