Cryptocurrency users narrowly escaped losing all their funds last week after an attacker poisoned a digital wallet with malicious code that stole their blockchain access details.
The attacker injected malicious code into Agama, a cryptocurrency wallet created by Komodo. If successful, they could have stolen around $13m of Komodo’s KMD cryptocurrency, which is a privacy-centric coin. Luckily, they were thwarted by quick action from both Komodo and software repository npm.
On 8 March 2019, the sneaky developer published what appeared to be a useful update to a software component used by the Agama wallet. The attacker, who called themselves ‘sawlysawly’, posted the update on the GitHub developer collaboration website where Komodo hosts its source code.
An npm package called
electron-native-notify was introduced by sawlysawly as a dependency in the Agama wallet, meaning that the new version of the wallet would use that code.
At the time of the commit, the version of
electron-native-notify (1.1.5) on npm was legit, but 15 days after making the commit, the npm package was updated to 1.1.6, which included a malicious payload. The next version of Agama was released on 13 April 2019.
The change in
electron-native-notify enabled the attacker to steal the wallet seed, which is a secret phrase that enables users to retrieve their coins using any wallet.
Wallet seeds are a great way to get at your coins from anywhere, meaning that if your hard disk crashes and your wallet is erased, you can still get your coins back (unlike this guy). The downside is that if anyone gets your seed, they can use it to pilfer your cryptocurrency by accessing your addresses and transferring the coins out.
The attacker configured the malicious code to copy the seed phrases from infected Agama wallets to a public server. That way, the attacker could visit the site and access the seeds, but no one could pin the crime on them. They then began emptying peoples’ accounts, said Komodo.
The npm team discovered the problem in early June after its own security analysis software alerted it. It told Komodo, which then raced to secure the vulnerable funds. It used the seeds stored on the public server to retrieve the compromised funds, moving them to a secure wallet.
This was a well thought out attack, explained Komodo in its own post on the topic:
It now seems clear that the bug was created intentionally to target Komodo’s version of Agama wallet. A hacker spent several months making useful contributions to the Agama repository on GitHub before inserting the bug. Eventually, the hacker added malicious code to an update of a module that Komodo’s Agama was already using.
The company has begun returning coins, urging affected users to fill out an online form. It has prioritised accounts with smaller amounts, under 7777 KMD, promising to return these accounts’ funds by 15 June. As of Sunday 9 June, it explained on its Discord channel that it had returned these users’ KMD in full, amounting to around $1m in funds, beating its own deadline by a week. Now it can begin on the larger accounts.
Komodo was eager to point out that only the Komodo Agama wallet was affected, and that another version of Agama, supporting a different Komodo project called VerusCoin, was not affected.
This shows how important it is for developers to test any third-party package on which their software depends. The more dependencies you use, the larger your potential attack surface becomes. Repositories can do some of the security work, but then you’re relying on a third party working on its own schedule to verify the software that you’re using. Props to npm for flagging this when it did, and to Komodo’s team for acting so quickly to fix the issue.
One comment on “Cryptocurrency attack thwarted by npm team”
“This shows how important it is for developers to test any third-party package on which their software depends.”
Is this really reasonable? First off, what is implied of “test”? Looking through all the code for malicious pieces? For every single update? For every single dependency?
Any large node project will have a ton of dependencies, and those dependencies will in turn have dependencies. (I don’t know if subdependencies are vulnerable as well, but I don’t have a reason to believe they would be immune.)
Obviously something needs to be done; but I think it should be done more like intrusion detection. I’m not smart enough to know what that would look like, but I’m just not sure there’s any way to reliably “test” all dependencies for malicious code