JavaScript Dependencies: Why You Should Watch Them Closely

Last week, someone injected malicious code into a wildly popular JavaScript library. The library wasn’t hacked; the code was put there by a maintainer who was given access by the library’s creator.

Event-Stream is a JavaScript npm package for handling Node.js streaming data. With roughly two million weekly downloads, its creator found managing it alone difficult and time-consuming. A GitHub user going by ‘Right9ctrl’ was granted access after offering to help maintain the library.

Instead of helping out, this person infused the library with obfuscated code that stole cryptocurrency information from users. Here’s what it all means:

Red (The Bad Stuff)

  • This ‘hack’ was essentially official. The package creator didn’t vet Right9ctrl or ease them into the project.
  • It was aimed at popular cryptocurrency wallet ‘Copay,’ which is available for desktop and mobile.
  • Right9ctrl tried to bury the malicious code by releasing versions of Event-Stream without the crypto-stealing code after the commit with the nefarious code.
  • Though Event-Stream was the high-profile point of interaction, the code itself resided in a different library, Flatmap-Stream.

Green (The Good Stuff)

  • The hack has been identified and stopped.
  • Developers can target Event-Stream version 3.3.4, which doesn’t include the suspect code. Copay versions 5.0.2 through 5.1.0 should not be used.
  • Right9ctrl has apparently been banned from GitHub; their page is dark.
  • This incident targeted a single cryptocurrency wallet.

Refactor (Our Take: Don’t Blame the JavaScript Community)

Users of open-source projects should have a ‘trust but verify’ mentality, but most care only that the libraries compile and run effectively. Similarly, maintainers should be more judicious about access to vital systems. The vetting of Right9ctrl seems to have focused on their activity and involvement with various other libraries, which is a good barometer for skill and interest, but not a measure of intent.

Levels of obscurity exist here, which is another issue altogether. The nefarious code was buried in a different, less popular repo, then included in the wildly popular Event-Stream. GitHub, essentially the de facto developer portal for open-source projects and libraries, doesn’t have a strong method for mapping dependencies. Sadly, GitHub repos still often read like documentation, which we’d argue many (most?) likely don’t read (or read to understand, at least).

As the malware focused on Copay, the damage wasn’t widespread. Rather, the ‘hack’ was a clever means to compromise Copay by infecting its dependencies; there was no way Right9ctrl would be allowed access to Copay directly, so they seeded their attack in a dependency. Clever.

Notably, the questionable code was discovered by a user or users poking through the repo. As with most endeavors on GitHub, this was a group effort, and it took a community to bring down the bad actor. Sadly, that’s not sustainable, so we’re hoping GitHub’s newest tool, which scans for malicious code in repos, scales quickly to help identify problems.