You are on page 1of 4

npmhydrawormdisclosure

Author:SamSaccone

tl;dr
Itispossibleforasinglemaliciousnpmpackagetospreaditselfacrossmostofthenpm
ecosystemveryquickly.Thispackagecouldenabledeliveryofapotentiallytargeted,malicious
payloadtocorporateentities.

Installingcodefromapackagemanagerhasthesamelevelofsecurityas
curlsite.com|
bash
,
howeverthemajorityofdevelopersperceivegeminstalloraptgetinstallornpminstallto
belessrisky.

Thenpmpackagemanager,likemostotherpackagemanagershasaconceptof
lifecycle
scripts
.Thesescriptscanexecutearbitrarycommandsonyoursystem(ideallydoingoperations
likecompilingcode).Innpm,theselifecyclehooksrunasthecurrentuser(ifrunwithsudothe
commandrunsas
nobody
),withthecurrentpermissionsinanonsandboxedenvironment.
Simplyput,anythingthatyoucando,thescriptscando.
However,thenpmclientandregistryareexploitableduetoacombinationofthefollowing
factors.

Factor 1: semver allows for changing dependencies


Thefirstpart
oftheexploitbeginswiththesimplefactthatnpmencouragesusersto
usesemver.Installeddependenciesarenotlockedtoaspecificversionbydefaultandusers
mustmanuallylocktheirprojectsvia
npmshrinkwrap
.Itisimportanttokeepinmindthat
packageshavesubdependenciesthatalsomayhavesemverrangesfortheirdependencies,
andsoonandsoon.

Let'stake
PhoneGap
forexample.Currentlyithas463transitivedependencies,andofthose
dependencies,276individualnpmaccountscanpushnewversionsofthesepackages.This
meansthatwhensomeonedoesnpminstallinsideoftheproject463unknownandunlocked
dependenciesareinstalled,eachwiththeabilitytoexecutearbitrarycodeatinstalltime.

Factor 2: Persistent auth allows any script to publish with user credentials
Thesecondpart
oftheexploitdependsonthefactthatonceauserisloggedintonpmontheir
systemtheyareneverloggedoutuntiltheymanuallydoso.Sincenpmcanrunarbitraryscripts
oninstallthatmeansthatanyuserwhoiscurrentlyloggedinandtypesnpminstallisallowing
anymoduletoexecutearbitrarypublishcommands.

Factor 3: Centralized registry serves huge userbase daily


Thethirdpart
oftheexploitisdependentonthatfactthatasingularnpmregistryisusedbythe
thelargemajorityofthenode.jsecosystemonadailybasis,andtyping
npmpublish
ships
yourcodetosaidregistryserver,tobeinstalledbyanyone.

Exploit Steps
Giventheabovecombinationoffactors,itisatrivialexercisetoauthortheselfreplicating
exploit.Forexample:

1. Sociallyengineeranpmmoduleownertonpminstallaninfectedmoduleontheir
system.
2. Wormcreatesanewnpmmodule
3. Wormsetsalifecyclehookonthenewnpmmoduletoexecutethewormonanyinstall
4. Wormpublishesthenewmoduletotheuser'snpmaccount
5. Wormwalksalloftheusersownednpmmodules(withpublishpermissions)andadds
thenewmoduleasadependencyineach's
package.json
.
6. Wormpublishesnewversionstoeachoftheownedmoduleswitha
bugfixlevelsemver
bump.Thisensuresthemajorityofdependentmodulesusingthe
^
or
~
signifierwill
includetheselfreplicatingmoduleduringthenextinstall.

Exploit Impact
Withthesesteps,thewormwouldbeabletoquicklyspreadacrosstheecosystemasusers
installedpackages,asmostnpmusersdowithoutthinking.Using
PhoneGap
asatestbed,it
wouldonlytake1personoutofthe276toinstallapackagethatcontainedthewormtoinfect
the
PhoneGap
project.

Mitigation strategies:
User mitigation:

Asauserwhoownsmodulesyoushouldnotstayloggedintonpm.(Easilyenough,
npm
logout
and
npmlogin
)
Use
npm
shrinkwrap
tolockdownyourdependencies
Use
npminstall
someModule
ignorescripts

npm mitigation:

Automaticallyexpirelogintokens
Requiresomeformoftwofactorauthforpublishoperations
Tellusersthattheyshouldlogout

Corporate mitigation:

Runalocalmirrorofthenpmregistry
Preventinstallingfromthemainregistry,andinsteaduseatrustedauditedregistry.

Timeline of disclosures:

Jan12016
Initialdiscoveryofexploit
Jan42016
Initialdisclosure+proofofconcepttonpm
Jan52016
PrivatedisclosuretoFacebook
Jan72016
Responsefromnpm
Jan82016
Confirmationofworksasintendednointentiontofixatthemomentfrom
npm.
Feb52016
Sharedthedisclosuredoc

Jan262015
"forced"reminderof"scriptrunsasuser"badnessdemonstration?
https://github.com/joaojeronimo/rimrafall
Jan272015
AdamBaldwin(nodesecurityexpert)followup
https://blog.liftsecurity.io/2015/01/27/amaliciousmoduleonnpm

You might also like