From 47aaec0db6e73f56d4bb14447155de1b4abd400b Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Sat, 14 Mar 2020 10:30:46 -0400 Subject: [PATCH] Sanitize personal tokens from custom background imagery (closes #6801) --- modules/renderer/background_source.js | 23 ++++++++++++++++++++-- test/spec/renderer/background_source.js | 26 +++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/modules/renderer/background_source.js b/modules/renderer/background_source.js index 236f05060..6e886c305 100644 --- a/modules/renderer/background_source.js +++ b/modules/renderer/background_source.js @@ -3,7 +3,7 @@ import { json as d3_json } from 'd3-fetch'; import { t } from '../util/locale'; import { geoExtent, geoSphericalDistance } from '../geo'; -import { utilDetect } from '../util/detect'; +import { utilDetect, utilQsString, utilStringQs } from '../util'; function localeDateString(s) { @@ -540,7 +540,26 @@ rendererBackgroundSource.Custom = function(template) { source.imageryUsed = function() { - return 'Custom (' + source.template() + ' )'; + // sanitize personal connection tokens - #6801 + var cleaned = source.template(); + + // from query string parameters + if (cleaned.indexOf('?') !== -1) { + var parts = cleaned.split('?', 2); + var qs = utilStringQs(parts[1]); + + ['access_token', 'connectId', 'token'].forEach(function(param) { + if (qs[param]) { + qs[param] = '{apikey}'; + } + }); + cleaned = parts[0] + '?' + utilQsString(qs, true); // true = soft encode + } + + // from wms/wmts api path parameters + cleaned = cleaned.replace(/token\/(\w+)/, 'token/{apikey}'); + + return 'Custom (' + cleaned + ' )'; }; diff --git a/test/spec/renderer/background_source.js b/test/spec/renderer/background_source.js index 7d265bdac..ca4865ce9 100644 --- a/test/spec/renderer/background_source.js +++ b/test/spec/renderer/background_source.js @@ -70,3 +70,29 @@ describe('iD.rendererBackgroundSource', function() { expect(source.validZoom(17)).to.be.false; }); }); + +describe('iD.rendererBackgroundSource.Custom', function() { + describe('#imageryUsed', function() { + it('returns an imagery_used string', function() { + var source = iD.rendererBackgroundSource.Custom('http://example.com'); + expect(source.imageryUsed()).to.eql('Custom (http://example.com )'); // note ' )' space + }); + it('sanitizes `access_token`', function() { + var source = iD.rendererBackgroundSource.Custom('http://example.com?access_token=MYTOKEN'); + expect(source.imageryUsed()).to.eql('Custom (http://example.com?access_token={apikey} )'); + }); + it('sanitizes `connectId`', function() { + var source = iD.rendererBackgroundSource.Custom('http://example.com?connectId=MYTOKEN'); + expect(source.imageryUsed()).to.eql('Custom (http://example.com?connectId={apikey} )'); + }); + it('sanitizes `token`', function() { + var source = iD.rendererBackgroundSource.Custom('http://example.com?token=MYTOKEN'); + expect(source.imageryUsed()).to.eql('Custom (http://example.com?token={apikey} )'); + }); + it('sanitizes wms path `token`', function() { + var source = iD.rendererBackgroundSource.Custom('http://example.com/wms/v1/token/MYTOKEN/1.0.0/layer'); + expect(source.imageryUsed()).to.eql('Custom (http://example.com/wms/v1/token/{apikey}/1.0.0/layer )'); + }); + }); + +});