Page MenuHomePhabricator

Security Readiness Review For maplibre-gl-js
Closed, ResolvedPublic

Description

Project Information

Description of the tool/project:
MapLibre GL is a community-led fork derived from mapbox-gl-js prior to their switch to a non-OSS license. This library provides multiple features for cient-side maps display, including a WebGL rendering for vector-tile rendering, which we intend to do for dynamic maps in the Maps (Kartographer) extension.

Description of how the tool will be used at WMF:
The tool will be used alongside Leaflet, which we already use as Map client-side framework for dynamic maps display. The intention is move the tile rendering to the client and simplify the server-side architecture as part of the following epic T263854: [Maps] Modernize Vector Tile Infrastructure. This library will be packaged and deployed in the Kartographer extension as part of its assets.

Dependencies

List dependencies, or upstream projects that this project relies on.

  • "@mapbox/geojson-rewind": "^0.5.0"
  • "@mapbox/geojson-types": "^1.0.2"
  • "@mapbox/jsonlint-lines-primitives": "^2.0.2"
  • "@mapbox/mapbox-gl-supported": "^1.5.0"
  • "@mapbox/point-geometry": "^0.1.0"
  • "@mapbox/tiny-sdf": "^1.1.1"
  • "@mapbox/unitbezier": "^0.0.0"
  • "@mapbox/vector-tile": "^1.3.1"
  • "@mapbox/whoots-js": "^3.1.0"
  • "csscolorparser": "~1.0.3"
  • "earcut": "^2.2.2"
  • "geojson-vt": "^3.2.1"
  • "gl-matrix": "^3.2.1"
  • "grid-index": "^1.1.0"
  • "minimist": "^1.2.5"
  • "murmurhash-js": "^1.0.0"
  • "pbf": "^3.2.1"
  • "potpack": "^1.0.1"
  • "quickselect": "^2.0.0"
  • "rw": "^1.3.3"
  • "supercluster": "^7.1.0"
  • "tinyqueue": "^2.0.3"
  • "vt-pbf": "^3.1.1"

Has this project been reviewed before?
No

Working test environment

Please link or describe setup process for setting up a test environment.

Post-deployment

Name of team responsible for tool/project after deployment and primary contact.

#product-infrastructure-team-backlog is the official maintainer of the extension and will continue it afterwards.

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald Transcript
sbassett triaged this task as Medium priority.Feb 11 2021, 4:39 PM
sbassett changed the task status from Open to Stalled.Feb 17 2021, 3:58 PM
sbassett lowered the priority of this task from Medium to Low.
sbassett subscribed.

Added to Q4 planning column for Q4 review.

Hey @MSantos - we're looking at having an external vendor complete this review. Whether or not that happens, or we perform the review internally, we'll plan to have an update for you within two weeks (2021-04-28).

Thanks @sbassett, that sounds great! I have one question for you, is there still time to squeeze in a plugin that will use this library for RTL text rendering? Should I create another task?

The plugin in question is https://github.com/mapbox/mapbox-gl-rtl-text will need to be forked because it wasn't yet forked by Maplibre but the only dependency is the WebGL renderer described in this ticket.

Here is the reasoning behind the need of this plugin T280040: Solution for right-to-left labels

Thanks @sbassett, that sounds great! I have one question for you, is there still time to squeeze in a plugin that will use this library for RTL text rendering? Should I create another task?

Yes, let's create a separate task for now, as these reviews will likely need to be performed separately, at separate times. Thanks.

@MSantos - We had one of our vendors (ROS) perform a security audit of mapbox-gl-js. Their findings are as follows:

Vulnerability ID: WKM-003
Vulnerability type:
Input Validation Threat level: low

Description

An XSS vulnerability can be introduced if an attacker can control the contents of a map's style.

Technical description

The contents of a map is displayed by parsing the map's style property. This value can either be a URL to a JSON object or a directly specified JSON object. The XSS vulnerability can be exploited if the style is loaded from an untrusted third party or if the JSON object can be controlled by a malicious user.

var map = new maplibregl.Map({
container: 'map',
style: '<input>'
});

Among other things, the style specification contains information about sources of the map. Depending on the type of source, the field attribution is supported. By specifying this value an attribution text is displayed in the lower right corner of the map. The attribution text is allowed to contain unsanitized HTML, which can be exploited by an attacker to trigger a XSS. The following sample source contains an attribution field with injected JavaScript:

[...]
"sources": {
"maplibre": {
"url": "https://demotiles.maplibre.org/tiles/tiles.json",
"type": "vector",
"attribution":"<img src=x onerror=alert(document.location)>"
}
[...]

Impact

If the map's style is loaded from a URL, the resource owner of that style can exploit a XSS vulnerability.

Recommendation

  1. Validate the style object before processing.
  2. Do not load a style from an untrusted third party.

Non-findings

It was found that the JavaScript library maplibre-gl-js supports various functionalities that allow rendering HTML into the webpage DOM. If these functionalities are not properly used, this could lead to XSS vulnerabilities. Such a vulnerability can be introduced if unsanitized user input reaches one of the sinks listed below.

Possible XSS via Popup

The Popup component allows inserting HTML into the displayed popup windows with the function setHTML . Therefore, this function should not be used with unsanitized user input.

var popup = new maplibregl.Popup({offset: popupOffsets, className: 'my-class'})
.setLngLat({lng: 10, lat: 10})
.setHTML("\x3cimg src=x onerror=alert(document.location)\x3e")
.setMaxWidth("300px")

Possible XSS via AtrributionControl

MapLibre GL JS supports displaying attribution text in the lower right corner of the map. This attribution text can also contain HTML and should therefore not be used with unsanitized user input.

new maplibregl.AttributionControl({
  compact: true,
  customAttribution:'\x3cimg src=x onerror=alert(document.location)\x3e'
  })

Possible XSS via the locale option

The text of the ScaleControl in the lower left corner of the map can be overwritten using the locale property of the Map component. An XSS vulnerability might be introduced if this property can be controlled by a user.

var map = new maplibregl.Map({
     container: 'map',
     style: '<style_url>',
     center: [0, 0],
     locale: {'ScaleControl.Miles':'\x3cimg src=y onerror=alert(2)\x3e'},
     zoom: 1.28
});

It should be noted that the library is not vulnerable by default. Exploitation of a XSS vulnerability in the above components depends on how the library is used. If user input is handled by these components, it is recommended to sanitize the input before rendering.

Note: since these are all low-risk issues or non-issues, the risk for this library is automatically accepted.

sbassett claimed this task.
sbassett moved this task from Vendor Confirmed to Our Part Is Done on the secscrum board.

@sbassett thank you so much! I'll create follow-up patches for the recommendations listed here.