Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blocked people from sending to addresses listed in CityOfZion/phishing #887

Merged
merged 2 commits into from Mar 24, 2018

Conversation

alexhulbert
Copy link
Contributor

What current issue(s) from Trello/Github does this address?
Fixes issue #878

What problem does this PR solve?
Up until this commit, people may have unintentionally sent tokens to malicious addresses

How did you solve this problem?
The first time someone tries to send tokens to an address, neon-wallet fetches the contents of the JSON file at the root of CityOfZion/phishing and compares its contents against the address. If there is a match, the transaction is halted and a message is displayed notifying the user that they just tried to send tokens to a phishing address. Subsequently, the application uses a cached copy of the JSON file.

How did you make sure your solution works?
I tested "AasqbuVKaCARqoWfp64ygM5fxYBqmMMgpq" as my malicious address and "Adr3XjZ5QDzVJrWvzmsTTchpLRRGSzgS5A" as my non-malicious address

Are there any special changes in the code that we should be aware of?
I added node-fetch as a dependency. I was going to add electron-fetch instead, but it was acting up and I didn't want to risk it.

@coveralls
Copy link

coveralls commented Mar 17, 2018

Coverage Status

Coverage decreased (-0.1%) to 40.997% when pulling f52e582 on Taconut:feature-nophishing into eb11d7d on CityOfZion:dev.

Copy link
Contributor

@mhuggins mhuggins left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work! I added a few thoughts, but overall I think the change is good.

package.json Outdated
@@ -81,6 +81,7 @@
"isomorphic-fetch": "2.2.1",
"lodash": "4.17.4",
"neon-js": "git+https://github.com/cityofzion/neon-js.git#3.3.3",
"node-fetch": "^2.1.1",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have axios in this repo -- we should try to avoid bringing in extra packages to prevent bloat.

let addressBlacklist: Array<string> | null = null
export const isInBlacklist = (address: string): Promise<boolean> => {
if (addressBlacklist !== null) return Promise.resolve(addressBlacklist.includes(address))
return fetch('https://raw.githubusercontent.com/CityOfZion/phishing/master/blockedAddresses.json')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could write this with axios and async/await syntax in a pretty direct manner:

import axios from 'axios'

export const isInBlacklist = async (address: string): Promise<boolean> => {
  if (addressBlacklist === null) {
    const { data } = await axios.get('https://raw.githubusercontent.com/CityOfZion/phishing/master/blockedAddresses.json')
    addressBlacklist = data
  }
  return addressBlacklist.includes(address)
}

display: DISPLAY_MODES.CONFIRM
})
}
isInBlacklist(entry.address).then(inBlacklist => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI using async/await syntax here can remove a layer of nesting and improve the readability. We've been favoring this syntax over raw promises throughout the codebase.

You would first need to change the method signature to include async, i.e.:

handleConfirmAddRecipient = async (entry: SendEntryType) => { ... }

Then the skeleton of this function simply becomes:

if (await isInBlacklist(entry.address)) {
  ...
} else {
  ...
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, making that function async/await removes access to the "this" variable. I get Cannot read property 'showErrorNotification' of undefined or ReferenceError: _this11 is not defined. There's a weird workaround to this in withAddressCheck.jsx, but applying it breaks other methods within the class. There's another promise ".then" in the same file, presumably for the same reason.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, that should be fixable by using async function(...) { ... } instead of async (...) => { ... }. Regardless, I can probably merge this as-is and look into it afterwards.

display: DISPLAY_MODES.CONFIRM
})
}
isInBlacklist(entry.address).then(inBlacklist => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, that should be fixable by using async function(...) { ... } instead of async (...) => { ... }. Regardless, I can probably merge this as-is and look into it afterwards.

@mhuggins mhuggins merged commit 23575b3 into CityOfZion:dev Mar 24, 2018
@mhuggins
Copy link
Contributor

mhuggins commented Mar 24, 2018

Thought I'd follow up and mention that the reason your function couldn't be changed to use async was due to a bug in react-hot-loader. I upgraded in #914 to fix it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants