From 34d37814c96abb24546c6d81ca4a16d9a9ca2860 Mon Sep 17 00:00:00 2001 From: Pablo Carranza Velez Date: Mon, 25 Sep 2017 06:39:46 -0700 Subject: [PATCH 1/3] Tunnel all mixpanel events through the resin API Change-Type: patch Signed-off-by: Pablo Carranza Velez --- src/config.coffee | 4 +++- src/utils.coffee | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/config.coffee b/src/config.coffee index 44998fe4..f9d1bd53 100644 --- a/src/config.coffee +++ b/src/config.coffee @@ -1,10 +1,11 @@ { checkInt, checkString } = require './lib/validation' dockerRoot = checkString(process.env.DOCKER_ROOT) ? '/mnt/root/var/lib/rce' +apiEndpoint = checkString(process.env.API_ENDPOINT) # Defaults needed for both gosuper and node supervisor are declared in entry.sh module.exports = - apiEndpoint: checkString(process.env.API_ENDPOINT) + apiEndpoint: apiEndpoint apiTimeout: checkInt(process.env.API_TIMEOUT, positive: true) ? 15 * 60 * 1000 listenPort: checkInt(process.env.LISTEN_PORT, positive: true) ? 80 gosuperAddress: "http://unix:#{process.env.GOSUPER_SOCKET}:" @@ -15,6 +16,7 @@ module.exports = publish_key: checkString(process.env.PUBNUB_PUBLISH_KEY) ? process.env.DEFAULT_PUBNUB_PUBLISH_KEY ssl: true mixpanelToken: checkString(process.env.MIXPANEL_TOKEN) ? process.env.DEFAULT_MIXPANEL_TOKEN + mixpanelHost: "#{apiEndpoint}/mixpanel" dockerSocket: process.env.DOCKER_SOCKET supervisorImage: checkString(process.env.SUPERVISOR_IMAGE) ? 'resin/rpi-supervisor' configMountPoint: checkString(process.env.CONFIG_MOUNT_POINT) ? '/mnt/mmcblk0p1/config.json' diff --git a/src/utils.coffee b/src/utils.coffee index bebdf5b1..efeb7691 100644 --- a/src/utils.coffee +++ b/src/utils.coffee @@ -19,7 +19,7 @@ exports.supervisorVersion = require('./lib/supervisor-version') configJson = JSON.parse(fs.readFileSync('/boot/config.json')) if Boolean(config.apiEndpoint) and !Boolean(configJson.supervisorOfflineMode) - mixpanelClient = mixpanel.init(config.mixpanelToken) + mixpanelClient = mixpanel.init(config.mixpanelToken, { host: config.mixpanelHost }) else mixpanelClient = { track: _.noop } From 20d95ff024815da2fe27c1ccc348eaf70a14d252 Mon Sep 17 00:00:00 2001 From: Pablo Carranza Velez Date: Mon, 25 Sep 2017 08:22:30 -0700 Subject: [PATCH 2/3] Add whitelist-based filtering to mixpanel events When sending events to mixpanel, we now use an explicit whitelist for the properties sent with the event, to avoid accidental leakage of any sensitive information. Change-Type: patch Signed-off-by: Pablo Carranza Velez --- package.json | 3 ++- src/utils.coffee | 22 ++++++++++++---------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index a4955daa..c9527860 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "docker-toolbelt": "^3.0.3", "event-stream": "^3.0.20", "express": "^4.0.0", + "json-mask": "^0.3.8", "knex": "~0.12.3", "lockfile": "^1.0.1", "lodash": "^4.16.3", @@ -58,4 +59,4 @@ "versionist": "^2.8.0", "webpack": "^3.0.0" } -} \ No newline at end of file +} diff --git a/src/utils.coffee b/src/utils.coffee index efeb7691..332199f8 100644 --- a/src/utils.coffee +++ b/src/utils.coffee @@ -14,6 +14,7 @@ TypedError = require 'typed-error' execAsync = Promise.promisify(require('child_process').exec) device = require './device' { checkTruthy } = require './lib/validation' +mask = require 'json-mask' exports.supervisorVersion = require('./lib/supervisor-version') @@ -26,6 +27,15 @@ else exports.mixpanelProperties = mixpanelProperties = username: configJson.username +mixpanelMask = [ + 'appId' + 'delay' + 'error' + 'interval' + 'app(appId,imageId,commit,name)' + 'stateDiff(status,download_progress,commit,os_version,superisor_version,ip_address)' +].join(',') + exports.mixpanelTrack = (event, properties = {}) -> # Allow passing in an error directly and having it assigned to the error property. if properties instanceof Error @@ -40,16 +50,8 @@ exports.mixpanelTrack = (event, properties = {}) -> properties = _.cloneDeep(properties) - # Don't log private env vars (e.g. api keys) - if properties?.app?.env? - try - { env } = properties.app - env = JSON.parse(env) if _.isString(env) - safeEnv = _.omit(env, config.privateAppEnvVars) - properties.app.env = JSON.stringify(safeEnv) - catch - properties.app.env = 'Fully hidden due to error in selective hiding' - + # Filter properties to only send the whitelisted keys and values + properties = mask(properties, mixpanelMask) console.log('Event:', event, JSON.stringify(properties)) # Mutation is bad, and it should feel bad properties = _.assign(properties, mixpanelProperties) From 087e3354677de37034f7b09b3b37389141b65288 Mon Sep 17 00:00:00 2001 From: "resin-io-versionbot[bot]" Date: Wed, 1 Nov 2017 09:33:20 +0000 Subject: [PATCH 3/3] v6.3.11 --- CHANGELOG.md | 5 +++++ package.json | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eba5a82b..b1d553ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file automatically by Versionist. DO NOT EDIT THIS FILE MANUALLY! This project adheres to [Semantic Versioning](http://semver.org/). +## v6.3.11 - 2017-11-01 + +* Add whitelist-based filtering to mixpanel events #500 [Pablo Carranza Velez] +* Tunnel all mixpanel events through the resin API #500 [Pablo Carranza Velez] + ## v6.3.10 - 2017-10-31 * Use a custom webpack loader to avoid uncaught exceptions from JSONStream #517 [Pablo Carranza Velez] diff --git a/package.json b/package.json index c9527860..0c4bc8c5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "resin-supervisor", "description": "This is resin.io's Supervisor, a program that runs on IoT devices and has the task of running user Apps (which are Docker containers), and updating them as Resin's API informs it to.", - "version": "6.3.10", + "version": "6.3.11", "license": "Apache-2.0", "repository": { "type": "git", @@ -59,4 +59,4 @@ "versionist": "^2.8.0", "webpack": "^3.0.0" } -} +} \ No newline at end of file