aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--app/scripts/background.js5
-rw-r--r--app/scripts/lib/is-phish.js38
-rw-r--r--package.json1
-rw-r--r--test/unit/blacklister-test.js24
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)
+ })
+ })
+})
+