mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 01:47:00 +01:00
feature: integrate gaba/PhishingController
This commit is contained in:
parent
094e4cf555
commit
77d3bc252d
@ -1,136 +0,0 @@
|
||||
const ObservableStore = require('obs-store')
|
||||
const extend = require('xtend')
|
||||
const PhishingDetector = require('eth-phishing-detect/src/detector')
|
||||
const log = require('loglevel')
|
||||
|
||||
// compute phishing lists
|
||||
const PHISHING_DETECTION_CONFIG = require('eth-phishing-detect/src/config.json')
|
||||
// every four minutes
|
||||
const POLLING_INTERVAL = 4 * 60 * 1000
|
||||
|
||||
class BlacklistController {
|
||||
|
||||
/**
|
||||
* Responsible for polling for and storing an up to date 'eth-phishing-detect' config.json file, while
|
||||
* exposing a method that can check whether a given url is a phishing attempt. The 'eth-phishing-detect'
|
||||
* config.json file contains a fuzzylist, whitelist and blacklist.
|
||||
*
|
||||
*
|
||||
* @typedef {Object} BlacklistController
|
||||
* @param {object} opts Overrides the defaults for the initial state of this.store
|
||||
* @property {object} store The the store of the current phishing config
|
||||
* @property {object} store.phishing Contains fuzzylist, whitelist and blacklist arrays. @see
|
||||
* {@link https://github.com/MetaMask/eth-phishing-detect/blob/master/src/config.json}
|
||||
* @property {object} _phishingDetector The PhishingDetector instantiated by passing store.phishing to
|
||||
* PhishingDetector.
|
||||
* @property {object} _phishingUpdateIntervalRef Id of the interval created to periodically update the blacklist
|
||||
*
|
||||
*/
|
||||
constructor (opts = {}) {
|
||||
const initState = extend({
|
||||
phishing: PHISHING_DETECTION_CONFIG,
|
||||
whitelist: [],
|
||||
}, opts.initState)
|
||||
this.store = new ObservableStore(initState)
|
||||
// phishing detector
|
||||
this._phishingDetector = null
|
||||
this._setupPhishingDetector(initState.phishing)
|
||||
// polling references
|
||||
this._phishingUpdateIntervalRef = null
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given hostname to the runtime whitelist
|
||||
* @param {string} hostname the hostname to whitelist
|
||||
*/
|
||||
whitelistDomain (hostname) {
|
||||
if (!hostname) {
|
||||
return
|
||||
}
|
||||
|
||||
const { whitelist } = this.store.getState()
|
||||
this.store.updateState({
|
||||
whitelist: [...new Set([hostname, ...whitelist])],
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a url, returns the result of checking if that url is in the store.phishing blacklist
|
||||
*
|
||||
* @param {string} hostname The hostname portion of a url; the one that will be checked against the white and
|
||||
* blacklists of store.phishing
|
||||
* @returns {boolean} Whether or not the passed hostname is on our phishing blacklist
|
||||
*
|
||||
*/
|
||||
checkForPhishing (hostname) {
|
||||
if (!hostname) return false
|
||||
|
||||
const { whitelist } = this.store.getState()
|
||||
if (whitelist.some((e) => e === hostname)) {
|
||||
return false
|
||||
}
|
||||
|
||||
const { result } = this._phishingDetector.check(hostname)
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries `https://api.infura.io/v2/blacklist` for an updated blacklist config. This is passed to this._phishingDetector
|
||||
* to update our phishing detector instance, and is updated in the store. The new phishing config is returned
|
||||
*
|
||||
*
|
||||
* @returns {Promise<object>} Promises the updated blacklist config for the phishingDetector
|
||||
*
|
||||
*/
|
||||
async updatePhishingList () {
|
||||
// make request
|
||||
let response
|
||||
try {
|
||||
response = await fetch('https://api.infura.io/v2/blacklist')
|
||||
} catch (err) {
|
||||
log.error(new Error(`BlacklistController - failed to fetch blacklist:\n${err.stack}`))
|
||||
return
|
||||
}
|
||||
// parse response
|
||||
let rawResponse
|
||||
let phishing
|
||||
try {
|
||||
const rawResponse = await response.text()
|
||||
phishing = JSON.parse(rawResponse)
|
||||
} catch (err) {
|
||||
log.error(new Error(`BlacklistController - failed to parse blacklist:\n${rawResponse}`))
|
||||
return
|
||||
}
|
||||
// update current blacklist
|
||||
this.store.updateState({ phishing })
|
||||
this._setupPhishingDetector(phishing)
|
||||
return phishing
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiates the updating of the local blacklist at a set interval. The update is done via this.updatePhishingList().
|
||||
* Also, this method store a reference to that interval at this._phishingUpdateIntervalRef
|
||||
*
|
||||
*/
|
||||
scheduleUpdates () {
|
||||
if (this._phishingUpdateIntervalRef) return
|
||||
this.updatePhishingList()
|
||||
this._phishingUpdateIntervalRef = setInterval(() => {
|
||||
this.updatePhishingList()
|
||||
}, POLLING_INTERVAL)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this._phishingDetector to a new PhishingDetector instance.
|
||||
* @see {@link https://github.com/MetaMask/eth-phishing-detect}
|
||||
*
|
||||
* @private
|
||||
* @param {object} config A config object like that found at {@link https://github.com/MetaMask/eth-phishing-detect/blob/master/src/config.json}
|
||||
*
|
||||
*/
|
||||
_setupPhishingDetector (config) {
|
||||
this._phishingDetector = new PhishingDetector(config)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BlacklistController
|
@ -28,7 +28,6 @@ const PreferencesController = require('./controllers/preferences')
|
||||
const CurrencyController = require('./controllers/currency')
|
||||
const ShapeShiftController = require('./controllers/shapeshift')
|
||||
const InfuraController = require('./controllers/infura')
|
||||
const BlacklistController = require('./controllers/blacklist')
|
||||
const CachedBalancesController = require('./controllers/cached-balances')
|
||||
const RecentBlocksController = require('./controllers/recent-blocks')
|
||||
const MessageManager = require('./lib/message-manager')
|
||||
@ -55,7 +54,10 @@ const HW_WALLETS_KEYRINGS = [TrezorKeyring.type, LedgerBridgeKeyring.type]
|
||||
const EthQuery = require('eth-query')
|
||||
const ethUtil = require('ethereumjs-util')
|
||||
const sigUtil = require('eth-sig-util')
|
||||
const { AddressBookController } = require('gaba')
|
||||
const {
|
||||
AddressBookController,
|
||||
PhishingController,
|
||||
} = require('gaba')
|
||||
const backEndMetaMetricsEvent = require('./lib/backend-metametrics')
|
||||
|
||||
|
||||
@ -112,8 +114,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||
})
|
||||
this.infuraController.scheduleInfuraNetworkCheck()
|
||||
|
||||
this.blacklistController = new BlacklistController()
|
||||
this.blacklistController.scheduleUpdates()
|
||||
this.phishingController = new PhishingController()
|
||||
|
||||
// rpc provider
|
||||
this.initializeProvider()
|
||||
@ -1301,7 +1302,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||
*/
|
||||
setupUntrustedCommunication (connectionStream, originDomain) {
|
||||
// Check if new connection is blacklisted
|
||||
if (this.blacklistController.checkForPhishing(originDomain)) {
|
||||
if (this.phishingController.test(originDomain)) {
|
||||
log.debug('MetaMask - sending phishing warning for', originDomain)
|
||||
this.sendPhishingWarning(connectionStream, originDomain)
|
||||
return
|
||||
@ -1781,11 +1782,11 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adds a domain to the {@link BlacklistController} whitelist
|
||||
* Adds a domain to the PhishingController whitelist
|
||||
* @param {string} hostname the domain to whitelist
|
||||
*/
|
||||
whitelistPhishingDomain (hostname) {
|
||||
return this.blacklistController.whitelistDomain(hostname)
|
||||
return this.phishingController.bypass(hostname)
|
||||
}
|
||||
|
||||
/**
|
||||
|
877
package-lock.json
generated
877
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -228,7 +228,7 @@
|
||||
"file-loader": "^1.1.11",
|
||||
"fs-extra": "^6.0.1",
|
||||
"fs-promise": "^2.0.3",
|
||||
"gaba": "1.0.0-beta.65",
|
||||
"gaba": "^1.0.1",
|
||||
"ganache-cli": "^6.1.0",
|
||||
"ganache-core": "^2.5.3",
|
||||
"geckodriver": "^1.14.1",
|
||||
|
@ -1,56 +0,0 @@
|
||||
const assert = require('assert')
|
||||
const BlacklistController = require('../../../../app/scripts/controllers/blacklist')
|
||||
|
||||
describe('blacklist controller', function () {
|
||||
let blacklistController
|
||||
|
||||
before(() => {
|
||||
blacklistController = new BlacklistController()
|
||||
})
|
||||
|
||||
describe('whitelistDomain', function () {
|
||||
it('should add hostname to the runtime whitelist', function () {
|
||||
blacklistController.whitelistDomain('foo.com')
|
||||
assert.deepEqual(blacklistController.store.getState().whitelist, ['foo.com'])
|
||||
|
||||
blacklistController.whitelistDomain('bar.com')
|
||||
assert.deepEqual(blacklistController.store.getState().whitelist, ['bar.com', 'foo.com'])
|
||||
})
|
||||
})
|
||||
|
||||
describe('checkForPhishing', function () {
|
||||
it('should not flag whitelisted values', function () {
|
||||
const result = blacklistController.checkForPhishing('www.metamask.io')
|
||||
assert.equal(result, false)
|
||||
})
|
||||
it('should flag explicit values', function () {
|
||||
const result = blacklistController.checkForPhishing('metamask.com')
|
||||
assert.equal(result, true)
|
||||
})
|
||||
it('should flag levenshtein values', function () {
|
||||
const result = blacklistController.checkForPhishing('metmask.io')
|
||||
assert.equal(result, true)
|
||||
})
|
||||
it('should not flag not-even-close values', function () {
|
||||
const result = blacklistController.checkForPhishing('example.com')
|
||||
assert.equal(result, false)
|
||||
})
|
||||
it('should not flag the ropsten faucet domains', function () {
|
||||
const result = blacklistController.checkForPhishing('faucet.metamask.io')
|
||||
assert.equal(result, false)
|
||||
})
|
||||
it('should not flag the mascara domain', function () {
|
||||
const result = blacklistController.checkForPhishing('zero.metamask.io')
|
||||
assert.equal(result, false)
|
||||
})
|
||||
it('should not flag the mascara-faucet domain', function () {
|
||||
const result = blacklistController.checkForPhishing('zero-faucet.metamask.io')
|
||||
assert.equal(result, false)
|
||||
})
|
||||
it('should not flag whitelisted domain', function () {
|
||||
blacklistController.whitelistDomain('metamask.com')
|
||||
const result = blacklistController.checkForPhishing('metamask.com')
|
||||
assert.equal(result, false)
|
||||
})
|
||||
})
|
||||
})
|
@ -752,8 +752,7 @@ describe('MetaMaskController', function () {
|
||||
})
|
||||
|
||||
it('sets up phishing stream for untrusted communication ', async () => {
|
||||
await metamaskController.blacklistController.updatePhishingList()
|
||||
console.log(blacklistJSON.blacklist.includes(phishingUrl))
|
||||
await metamaskController.phishingController.updatePhishingLists()
|
||||
|
||||
const { promise, resolve } = deferredPromise()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user