diff options
Merge branch 'master' into i1805-LiveBlacklistUpdating
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | app/scripts/background.js | 5 | ||||
-rw-r--r-- | app/scripts/lib/is-phish.js | 38 | ||||
-rw-r--r-- | package.json | 1 | ||||
-rw-r--r-- | test/unit/blacklister-test.js | 24 |
5 files changed, 67 insertions, 2 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index ba8bdd16c..823b131be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - Fix bugs that could sometimes result in failed transactions after switching networks. - Include stack traces in txMeta's to better understand the life cycle of transactions +- Enhance blacklister functionality to include levenshtein logic. (credit to @sogoiii and @409H for their help!) ## 3.9.1 2017-7-19 diff --git a/app/scripts/background.js b/app/scripts/background.js index 01bb39186..bc0fbdc37 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -11,6 +11,7 @@ const NotificationManager = require('./lib/notification-manager.js') const MetamaskController = require('./metamask-controller') const extension = require('extensionizer') const firstTimeState = require('./first-time-state') +const isPhish = require('./lib/is-phish') const STORAGE_KEY = 'metamask-config' const METAMASK_DEBUG = 'GULP_METAMASK_DEBUG' @@ -153,9 +154,9 @@ function handleNewPageLoad (port, message) { if (!pageLoaded || !global.metamaskController) return const state = global.metamaskController.getState() - const { blacklist } = state + const updatedBlacklist = state.blacklist - if (blacklist && blacklist.includes(pageLoaded)) { + if (isPhish({ updatedBlacklist, hostname: pageLoaded })) { port.postMessage({ 'blacklist': pageLoaded }) } } diff --git a/app/scripts/lib/is-phish.js b/app/scripts/lib/is-phish.js new file mode 100644 index 000000000..68c09e4ac --- /dev/null +++ b/app/scripts/lib/is-phish.js @@ -0,0 +1,38 @@ +const levenshtein = require('fast-levenshtein') +const blacklistedMetaMaskDomains = ['metamask.com'] +let blacklistedDomains = require('etheraddresslookup/blacklists/domains.json').concat(blacklistedMetaMaskDomains) +const whitelistedMetaMaskDomains = ['metamask.io', 'www.metamask.io'] +const whitelistedDomains = require('etheraddresslookup/whitelists/domains.json').concat(whitelistedMetaMaskDomains) +const LEVENSHTEIN_TOLERANCE = 4 +const LEVENSHTEIN_CHECKS = ['myetherwallet', 'myetheroll', 'ledgerwallet', 'metamask'] + + +// credit to @sogoiii and @409H for their help! +// Return a boolean on whether or not a phish is detected. +function isPhish({ hostname, updatedBlacklist = null }) { + var strCurrentTab = hostname + + // check if the domain is part of the whitelist. + if (whitelistedDomains && whitelistedDomains.includes(strCurrentTab)) { return false } + + // Allow updating of blacklist: + if (updatedBlacklist) { + blacklistedDomains = blacklistedDomains.concat(updatedBlacklist) + } + + // check if the domain is part of the blacklist. + const isBlacklisted = blacklistedDomains && blacklistedDomains.includes(strCurrentTab) + + // check for similar values. + let levenshteinMatched = false + var levenshteinForm = strCurrentTab.replace(/\./g, '') + LEVENSHTEIN_CHECKS.forEach((element) => { + if (levenshtein.get(element, levenshteinForm) <= LEVENSHTEIN_TOLERANCE) { + levenshteinMatched = true + } + }) + + return isBlacklisted || levenshteinMatched +} + +module.exports = isPhish diff --git a/package.json b/package.json index dcd25cda6..10afc8228 100644 --- a/package.json +++ b/package.json @@ -80,6 +80,7 @@ "express": "^4.14.0", "extension-link-enabler": "^1.0.0", "extensionizer": "^1.0.0", + "fast-levenshtein": "^2.0.6", "gulp-eslint": "^2.0.0", "hat": "0.0.3", "idb-global": "^1.0.0", diff --git a/test/unit/blacklister-test.js b/test/unit/blacklister-test.js new file mode 100644 index 000000000..1badc2c8f --- /dev/null +++ b/test/unit/blacklister-test.js @@ -0,0 +1,24 @@ +const assert = require('assert') +const isPhish = require('../../app/scripts/lib/is-phish') + +describe('blacklister', function () { + describe('#isPhish', function () { + it('should not flag whitelisted values', function () { + var result = isPhish({ hostname: 'www.metamask.io' }) + assert(!result) + }) + it('should flag explicit values', function () { + var result = isPhish({ hostname: 'metamask.com' }) + assert(result) + }) + it('should flag levenshtein values', function () { + var result = isPhish({ hostname: 'metmask.com' }) + assert(result) + }) + it('should not flag not-even-close values', function () { + var result = isPhish({ hostname: 'example.com' }) + assert(!result) + }) + }) +}) + |