diff --git a/HISTORY.md b/HISTORY.md index 5b4983d4..6b573a40 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,7 @@ +# 4.1.7 / 2021-03-17 + +- Fix Potential DOM-based XSS via prototype pollution + # 4.1.6 / 2020-11-24 - Update `trim` package to address ReDoS vulnerability diff --git a/lib/analytics.ts b/lib/analytics.ts index 73080872..5427ea60 100644 --- a/lib/analytics.ts +++ b/lib/analytics.ts @@ -6,13 +6,14 @@ import { SegmentAnalytics, SegmentOpts, SegmentIntegration, - PageDefaults, Message + PageDefaults } from './types'; import { pageDefaults } from './pageDefaults'; import cloneDeep from 'lodash.clonedeep' import pick from 'lodash.pick' +import url from 'component-url' var _analytics = global.analytics; @@ -37,7 +38,6 @@ var extend = require('extend'); var cookie = require('./cookie'); var metrics = require('./metrics'); var debug = require('debug'); -var defaults = require('@ndhoule/defaults'); var group = require('./group'); var is = require('is'); var isMeta = require('@segment/is-meta'); @@ -46,7 +46,6 @@ var nextTick = require('next-tick'); var normalize = require('./normalize'); var on = require('component-event').bind; var prevent = require('@segment/prevent-default'); -var querystring = require('component-querystring'); var store = require('./store'); var user = require('./user'); var type = require('component-type'); @@ -69,7 +68,6 @@ function Analytics() { this.log = debug('analytics.js'); bindAll(this); - const self = this; this.on('initialize', function(_, options) { if (options.initialPageview) self.page(); @@ -960,9 +958,22 @@ Analytics.prototype.reset = function() { * @api private */ +interface QueryStringParams { + [key: string]: string | null; +} + Analytics.prototype._parseQuery = function(query: string): SegmentAnalytics { // Parse querystring to an object - var q = querystring.parse(query); + const parsed = url.parse(query); + + const q = parsed.query + .split('&') + .reduce((acc: QueryStringParams, str: string) => { + const [k, v] = str.split('='); + acc[k] = decodeURI(v).replace('+', ' '); + return acc; + }, {}); + // Create traits and properties objects, populate from querysting params var traits = pickPrefix('ajs_trait_', q); var props = pickPrefix('ajs_prop_', q); diff --git a/package.json b/package.json index 1087f28f..065a3e3e 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,6 @@ "bind-all": "^1.0.0", "component-emitter": "^1.2.1", "component-event": "^0.1.4", - "component-querystring": "^2.0.0", "component-type": "^1.2.1", "component-url": "^0.2.1", "debug": "^2.6.9", diff --git a/yarn.lock b/yarn.lock index 60c9da5e..5e50af65 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2526,21 +2526,10 @@ component-props@*: version "1.1.1" resolved "https://registry.yarnpkg.com/component-props/-/component-props-1.1.1.tgz#f9b7df9b9927b6e6d97c9bd272aa867670f34944" -component-querystring@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/component-querystring/-/component-querystring-2.0.0.tgz#84a95d18e471c8491b043df240f0d18d4db527ec" - dependencies: - component-type "1.1.0" - trim "0.0.1" - component-type@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/component-type/-/component-type-1.0.0.tgz#1ed8812e32dd65099d433570757f111ea3d3d871" -component-type@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/component-type/-/component-type-1.1.0.tgz#95b666aad53e5c8d1f2be135c45b5d499197c0c5" - component-type@^1.2.0, component-type@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/component-type/-/component-type-1.2.1.tgz#8a47901700238e4fc32269771230226f24b415a9"