Closed ghost closed 10 months ago
I've tried to do some XSS on our own website (not maplibre) now to learn about this and it's not as trivial as it initially seemed. I'm unable to even send a message when creating the target window via JS (not sure why yet). It also seems to be impossible (?) to get the window object of another tab (without opening it from JS), so this would "only" affect iframes (not an issue for our website, but probably an issue for maplibre, but not in the cases I mentioned)
I might try again in the future.
I've opened a PR to address this, although I'm not sure there is an attack vector here, and you can bypass it with setting a the relevant origin in the message itself... IDK, better than nothing I guess. The only way to attack I think is sending a message to the worker to process some data in a different way, this might cause a map refresh and in some cases you might be able to show something different than expected on the map due to the data you sent to the worker, maybe, but I'm not sure you can really cause something to execute or send data to an attacker...
Fixed by #3329 which was merged as part of #3233
This is a theoretical situation only - there's no PoC and the described attack might not work in practice on maplibre. maplibre is not less secure than many other npm packages / libs - these (targeted) attacks are unlikely, but they'll gain significance as maplibre is being used in more products.
User Story
A user opens multiple tabs.
One of them is using maplibre in a context where security should be expected:
Another tab contains a hostile website which aims to extract as much data as possible from the other tab that use maplibre (including potential credentials, personal information or similar).
That data gets stolen (and potentially abused).
Rationale
The (probably) affected code is (among other locations) here:
https://github.com/maplibre/maplibre-gl-js/blob/fbdb32dc439f41c37d1a6dc2d695f10446b72016/src/util/actor.ts#L88 https://github.com/maplibre/maplibre-gl-js/blob/fbdb32dc439f41c37d1a6dc2d695f10446b72016/src/util/actor.ts#L232
There are many XSS attacks on
postMessage
/onMessage
which is used in the maplibreActor
to communicate with the web-workers.Examples of attacks and words of caution:
It's fairly easy to add additional security measures. Recently, a similar PR for mapbox has taken steps to secure their
Actor
implementation.Impact
There are many attacks and even if there's no practical PoC, the fact that this might be exploitable should be taken seriously until proven otherwise. With maplibre being widely used (including large companies like Meta, Microsoft and others), someone will eventually try to attack it and if there is a vulnerability, it will be found and exploited.
Notes
On OSM Slack ( https://osmus.slack.com/archives/C01G3D28DAB/p1697724774588149 ), I proposed to generate random UUID when maplibre is loaded, which is then attached to each message from/to the webworkers, so they know it's from the map (initial communication of the UUID could happen in the worker source). Thereby there'd be a trusted channel as no code in another window/tab could know the UUID to communicate with the worker.
I'm unable to find any thoughts on this UUID technique. Most documentation seems to only check the origin (which I consider to be flawed, especially as the origin might not be known ahead of time or there might be multiple pages on the same origin). So, my proposal with the UUID for the trusted channel might also have flaws.
I also noticed that the
throttled_invoker
uses https://developer.mozilla.org/en-US/docs/Web/API/Channel_Messaging_API which might be intended for this case (I'm not sure). However, even the standard for that uses an untrustedpostMessage
: https://html.spec.whatwg.org/multipage/web-messaging.html#introduction-13 (which needs to be protected somehow to build a chain of trust).Someone with a better understanding of
postMessage
andonmessage
/ XSS attacks and web standards in this area is probably needed to assess the situation and propose a proven method to secure maplibre.