Skip to content

fix: pin maplibre-gl to 5.24.0 to restore basemap rendering - #16

Open
iblh wants to merge 1 commit into
mainfrom
fix/map-pin-maplibre-5
Open

iblh wants to merge 1 commit into
mainfrom
fix/map-pin-maplibre-5

Conversation

@iblh

@iblh iblh commented Sep 15, 2026

Copy link
Copy Markdown
Owner

What was broken

The landing preview, the demo and the authed dashboard were all drawing their frame, route, markers and attribution over an empty basemap — no tiles, no labels.

Root cause

Bisecting the dependency history points at #4 (maplibre-gl 4.7.1 → 6.4.1), not at #13.

react-map-gl v8 (@vis.gl/react-maplibre) cannot drive maplibre-gl 6.x. The map object constructs and the style JSON parses into 114 layers, but the style never reaches loaded, so its source caches are never built and not a single vector tile is ever requested. No error is emitted, which is why this failed silently — the canvas, WebGL context and attribution control all look healthy.

Control: a bare MapLibre map on the same page, with the same style URL and the same maplibre build, loads fine. The wrapper is the difference.

Verified matrix (all checked in a real browser)

react-map-gl maplibre-gl result
7.1.9 4.7.1 ✅ renders — the pre-#4 pairing
8.1.3 4.7.1 ✅ renders
8.1.3 5.24.0 renders — this PR
8.1.3 6.4.1 ❌ blank
8.1.3 6.9.0 ❌ blank
8.0.4 6.4.1 ❌ blank
7.1.9 6.4.1 ❌ throws 'clone', no map at all
7.2.0-beta.1 6.4.1 ❌ throws 'clone', no map at all

The wrapper is not broken in general — the break starts at maplibre 6.0, which moved to an ESM-only distribution and reworked the event classes.

Going back to react-map-gl v7 is not an option: v7 declares maplibre-gl >=1.13.0 <5.0.0, and against maplibre 6 it throws before the map exists.

The security trade-off

CVE-2026-85061 / GHSA-jrc7-96c5-q579 (critical) covers maplibre-gl <= 6.4.0, so 5.24.0 carries it and there is no 4.x/5.x backport. Every version that renders is affected; the only patched version is the one that cannot render.

Both CI gates are told to allow this one advisory:

  • pnpm-workspace.yamlauditConfig.ignoreCves
  • ci.ymlallow-ghsas on dependency-review-action

Why it is not reachable here: the advisory is an XSS sanitizer bypass in DOM.sanitize(), which requires untrusted HTML to pass through maplibre's sanitizer. This app has no Popup, setHTML, setDOMContent or dangerouslySetInnerHTML anywhere, and the only HTML surface on the map is the built-in attribution control with static strings.

The exemption is scoped to this single advisory and documented with its removal condition in pnpm-workspace.yaml: drop it as soon as react-map-gl renders with maplibre-gl >= 6.4.1.

Test plan

  • pnpm lint / typecheck / test / build all pass
  • pnpm audit --prod --audit-level=high passes (1 critical, 1 ignored)
  • Landing preview renders the basemap — styleLoaded: true, omt: true
  • Reviewer: confirm /demo and the authed dashboard also render
  • Follow-up: file an upstream issue with visgl/react-map-gl (no issue exists yet)

🤖 Generated with Claude Code

The landing preview, the demo and the authed dashboard have all been
rendering their frame, route, markers and attribution over an empty
basemap: no tiles, no labels.

Bisecting the dependency history points at #4 (maplibre-gl 4.7.1 -> 6.4.1),
not at #13. react-map-gl v8 cannot drive maplibre-gl 6.x: the map object
constructs and the style JSON parses into 114 layers, but the style never
reaches `loaded`, so its source caches are never built and not a single
vector tile is ever requested. No error is emitted, which is why this was
silent.

Verified in the browser across the matrix:

  react-map-gl  maplibre-gl  result
  7.1.9         4.7.1        renders   (the pre-#4 pairing)
  8.1.3         4.7.1        renders
  8.1.3         5.24.0       renders   <- this commit
  8.1.3         6.4.1        blank
  8.1.3         6.9.0        blank
  8.0.4         6.4.1        blank
  7.1.9         6.4.1        throws 'clone', no map at all
  7.2.0-beta.1  6.4.1        throws 'clone', no map at all

So the wrapper is not broken in general; the break starts at maplibre 6.0,
which rewrote the distribution to ESM-only and reworked the event classes.

CVE-2026-85061 (GHSA-jrc7-96c5-q579) covers maplibre-gl <= 6.4.0, so 5.24.0
carries it and both CI gates are told to allow it. The advisory is an XSS
sanitizer bypass in DOM.sanitize(); reaching it requires untrusted HTML to
pass through maplibre's sanitizer. This app has no Popup, setHTML,
setDOMContent or dangerouslySetInnerHTML anywhere, and the only HTML
surface on the map is the built-in attribution control with static strings.
The exemption is scoped to this one advisory and is documented, with the
removal condition, in pnpm-workspace.yaml.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Sep 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
uplotr Ready Ready Preview Sep 15, 2026 6:10am UTC

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bb129cb600

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread package.json
"lucide-react": "^0.562.0",
"mapbox-gl": "^3.2.0",
"maplibre-gl": "^6.4.1",
"maplibre-gl": "5.24.0",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Remove the vulnerable attribution path before pinning MapLibre

When OpenFreeMap is selected, including on the public landing page and authenticated dashboard, MapContainer loads style JSON from tiles.openfreemap.org (lines 229–231) while enabling MapLibre's built-in attributionControl (line 287). That control obtains attribution HTML from the remotely supplied style/source metadata and sanitizes it through the affected DOM.sanitize() path, so the attribution strings are not actually static: a malicious or compromised provider response can reach the known XSS sink. Downgrading to this affected version while suppressing both audit gates therefore exposes every MapLibre view; disable the built-in control and render hardcoded attribution safely, or use a patched rendering solution instead.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant