aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md2
-rw-r--r--app/manifest.json9
-rw-r--r--app/scripts/background.js26
-rw-r--r--app/scripts/blacklister.js45
-rw-r--r--app/scripts/controllers/infura.js14
-rw-r--r--app/scripts/inpage.js1
-rw-r--r--app/scripts/lib/is-phish.js38
-rw-r--r--test/unit/blacklister-test.js12
8 files changed, 103 insertions, 44 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ab5d635d3..823b131be 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,8 @@
## Current Master
+- Continuously update blacklist for known phishing sites in background.
+
## 3.9.2 2017-7-26
- Fix bugs that could sometimes result in failed transactions after switching networks.
diff --git a/app/manifest.json b/app/manifest.json
index 55e1eb5b1..edc4d7162 100644
--- a/app/manifest.json
+++ b/app/manifest.json
@@ -55,8 +55,13 @@
},
{
"run_at": "document_start",
- "matches": ["http://*/*", "https://*/*"],
- "js": ["scripts/blacklister.js"]
+ "matches": [
+ "file://*/*",
+ "http://*/*",
+ "https://*/*"
+ ],
+ "js": ["scripts/blacklister.js"],
+ "all_frames": true
}
],
"permissions": [
diff --git a/app/scripts/background.js b/app/scripts/background.js
index e8987394f..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'
@@ -90,6 +91,10 @@ function setupController (initState) {
extension.runtime.onConnect.addListener(connectRemote)
function connectRemote (remotePort) {
+ if (remotePort.name === 'blacklister') {
+ return checkBlacklist(remotePort)
+ }
+
var isMetaMaskInternalProcess = remotePort.name === 'popup' || remotePort.name === 'notification'
var portStream = new PortStream(remotePort)
if (isMetaMaskInternalProcess) {
@@ -135,6 +140,27 @@ function setupController (initState) {
return Promise.resolve()
}
+// Listen for new pages and return if blacklisted:
+function checkBlacklist (port) {
+ const handler = handleNewPageLoad.bind(null, port)
+ port.onMessage.addListener(handler)
+ setTimeout(() => {
+ port.onMessage.removeListener(handler)
+ }, 30000)
+}
+
+function handleNewPageLoad (port, message) {
+ const { pageLoaded } = message
+ if (!pageLoaded || !global.metamaskController) return
+
+ const state = global.metamaskController.getState()
+ const updatedBlacklist = state.blacklist
+
+ if (isPhish({ updatedBlacklist, hostname: pageLoaded })) {
+ port.postMessage({ 'blacklist': pageLoaded })
+ }
+}
+
//
// Etc...
//
diff --git a/app/scripts/blacklister.js b/app/scripts/blacklister.js
index 9337599cc..37751b595 100644
--- a/app/scripts/blacklister.js
+++ b/app/scripts/blacklister.js
@@ -1,41 +1,14 @@
-const levenshtein = require('fast-levenshtein')
-const blacklistedMetaMaskDomains = ['metamask.com']
-const 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']
+const extension = require('extensionizer')
+var port = extension.runtime.connect({name: 'blacklister'})
+port.postMessage({ 'pageLoaded': window.location.hostname })
+port.onMessage.addListener(redirectIfBlacklisted)
-// credit to @sogoiii and @409H for their help!
-// Return a boolean on whether or not a phish is detected.
-function isPhish(hostname) {
- var strCurrentTab = hostname
-
- // check if the domain is part of the whitelist.
- if (whitelistedDomains && whitelistedDomains.includes(strCurrentTab)) { return false }
-
- // check if the domain is part of the blacklist.
- var isBlacklisted = blacklistedDomains && blacklistedDomains.includes(strCurrentTab)
-
- // check for similar values.
- var levenshteinMatched = false
- var levenshteinForm = strCurrentTab.replace(/\./g, '')
- LEVENSHTEIN_CHECKS.forEach((element) => {
- if (levenshtein.get(element, levenshteinForm) < LEVENSHTEIN_TOLERANCE) {
- levenshteinMatched = true
- }
- })
-
- return isBlacklisted || levenshteinMatched
-}
-
-window.addEventListener('load', function () {
- var hostnameToCheck = window.location.hostname
- if (isPhish(hostnameToCheck)) {
- // redirect to our phishing warning page.
+function redirectIfBlacklisted (response) {
+ const { blacklist } = response
+ const host = window.location.hostname
+ if (blacklist && blacklist === host) {
window.location.href = 'https://metamask.io/phishing.html'
}
-})
+}
-module.exports = isPhish
diff --git a/app/scripts/controllers/infura.js b/app/scripts/controllers/infura.js
index b34b0bc03..97b2ab7e3 100644
--- a/app/scripts/controllers/infura.js
+++ b/app/scripts/controllers/infura.js
@@ -1,5 +1,6 @@
const ObservableStore = require('obs-store')
const extend = require('xtend')
+const recentBlacklist = require('etheraddresslookup/blacklists/domains.json')
// every ten minutes
const POLLING_INTERVAL = 300000
@@ -9,6 +10,7 @@ class InfuraController {
constructor (opts = {}) {
const initState = extend({
infuraNetworkStatus: {},
+ blacklist: recentBlacklist,
}, opts.initState)
this.store = new ObservableStore(initState)
}
@@ -30,12 +32,24 @@ class InfuraController {
})
}
+ updateLocalBlacklist () {
+ return fetch('https://api.infura.io/v1/blacklist')
+ .then(response => response.json())
+ .then((parsedResponse) => {
+ this.store.updateState({
+ blacklist: parsedResponse,
+ })
+ return parsedResponse
+ })
+ }
+
scheduleInfuraNetworkCheck () {
if (this.conversionInterval) {
clearInterval(this.conversionInterval)
}
this.conversionInterval = setInterval(() => {
this.checkInfuraNetworkStatus()
+ this.updateLocalBlacklist()
}, POLLING_INTERVAL)
}
}
diff --git a/app/scripts/inpage.js b/app/scripts/inpage.js
index ec764535e..9e98c044b 100644
--- a/app/scripts/inpage.js
+++ b/app/scripts/inpage.js
@@ -65,3 +65,4 @@ function restoreContextAfterImports () {
console.warn('MetaMask - global.define could not be overwritten.')
}
}
+
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/test/unit/blacklister-test.js b/test/unit/blacklister-test.js
index d9290795c..1badc2c8f 100644
--- a/test/unit/blacklister-test.js
+++ b/test/unit/blacklister-test.js
@@ -1,24 +1,24 @@
const assert = require('assert')
-const Blacklister = require('../../app/scripts/blacklister')
-
+const isPhish = require('../../app/scripts/lib/is-phish')
describe('blacklister', function () {
describe('#isPhish', function () {
it('should not flag whitelisted values', function () {
- var result = Blacklister('www.metamask.io')
+ var result = isPhish({ hostname: 'www.metamask.io' })
assert(!result)
})
it('should flag explicit values', function () {
- var result = Blacklister('metamask.com')
+ var result = isPhish({ hostname: 'metamask.com' })
assert(result)
})
it('should flag levenshtein values', function () {
- var result = Blacklister('metmask.io')
+ var result = isPhish({ hostname: 'metmask.com' })
assert(result)
})
it('should not flag not-even-close values', function () {
- var result = Blacklister('example.com')
+ var result = isPhish({ hostname: 'example.com' })
assert(!result)
})
})
})
+