From fd3f854a9c944a5c141bfa8d3ef6752caf2d8513 Mon Sep 17 00:00:00 2001 From: David Larlet Date: Fri, 19 May 2023 14:49:02 -0400 Subject: [PATCH] Use DOMPurify to escape malicious input from user --- Makefile | 1 + package-lock.json | 11 +++++++++++ package.json | 1 + umap/static/umap/js/umap.core.js | 23 ++++++++++++++++++++--- umap/templates/umap/js.html | 1 + 5 files changed, 34 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index a0a2679c..8b4fcc3d 100644 --- a/Makefile +++ b/Makefile @@ -42,6 +42,7 @@ vendors: mkdir -p umap/static/umap/vendors/togpx/ && cp -r node_modules/togpx/togpx.js umap/static/umap/vendors/togpx/ mkdir -p umap/static/umap/vendors/tokml && cp -r node_modules/tokml/tokml.js umap/static/umap/vendors/tokml mkdir -p umap/static/umap/vendors/locatecontrol/ && cp -r node_modules/leaflet.locatecontrol/{dist/L.Control.Locate.css,src/L.Control.Locate.js} umap/static/umap/vendors/locatecontrol/ + mkdir -p umap/static/umap/vendors/dompurify/ && cp -r node_modules/dompurify/dist/purify.js umap/static/umap/vendors/dompurify/ installjs: npm install testjsfx: diff --git a/package-lock.json b/package-lock.json index 36a5c82e..aca700db 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "license": "WTFPL", "dependencies": { "csv2geojson": "5.1.1", + "dompurify": "^3.0.3", "georsstogeojson": "^0.1.0", "leaflet": "1.3.4", "leaflet-contextmenu": "^1.4.0", @@ -676,6 +677,11 @@ "domelementtype": "1" } }, + "node_modules/dompurify": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.3.tgz", + "integrity": "sha512-axQ9zieHLnAnHh0sfAamKYiqXMJAVwu+LM/alQ7WDagoWessyWvMSFyW65CqF3owufNu8HBcE4cM2Vflu7YWcQ==" + }, "node_modules/domutils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.3.0.tgz", @@ -3719,6 +3725,11 @@ "domelementtype": "1" } }, + "dompurify": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.3.tgz", + "integrity": "sha512-axQ9zieHLnAnHh0sfAamKYiqXMJAVwu+LM/alQ7WDagoWessyWvMSFyW65CqF3owufNu8HBcE4cM2Vflu7YWcQ==" + }, "domutils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.3.0.tgz", diff --git a/package.json b/package.json index 1b9883be..5254e0e5 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "homepage": "http://wiki.openstreetmap.org/wiki/UMap", "dependencies": { "csv2geojson": "5.1.1", + "dompurify": "^3.0.3", "georsstogeojson": "^0.1.0", "leaflet": "1.3.4", "leaflet-contextmenu": "^1.4.0", diff --git a/umap/static/umap/js/umap.core.js b/umap/static/umap/js/umap.core.js index 483db35e..a7554350 100644 --- a/umap/static/umap/js/umap.core.js +++ b/umap/static/umap/js/umap.core.js @@ -53,9 +53,6 @@ L.Util.toHTML = (r) => { // detect newline format const newline = r.indexOf('\r\n') != -1 ? '\r\n' : r.indexOf('\n') != -1 ? '\n' : '' - // Escape tags - r = r.replace(/$1') r = r.replace(/^## (.*)/gm, '

$1

') @@ -109,6 +106,26 @@ L.Util.toHTML = (r) => { // Preserver line breaks if (newline) r = r.replace(new RegExp(newline + '(?=[^]+)', 'g'), '
' + newline) + r = DOMPurify.sanitize(r, { + USE_PROFILES: { html: true }, + ALLOWED_TAGS: [ + 'h3', + 'h4', + 'h5', + 'hr', + 'strong', + 'em', + 'ul', + 'li', + 'a', + 'div', + 'iframe', + 'img', + 'br', + ], + ALLOWED_ATTR: ['target', 'href', 'frameborder', 'src', 'width', 'height'], + }) + return r } L.Util.isObject = (what) => typeof what === 'object' && what !== null diff --git a/umap/templates/umap/js.html b/umap/templates/umap/js.html index 4866140d..e8c1e8e6 100644 --- a/umap/templates/umap/js.html +++ b/umap/templates/umap/js.html @@ -23,6 +23,7 @@ + {% endcompress %} {% if locale %}