
Backdoor in event-stream library dependency - cnorthwood
https://github.com/dominictarr/event-stream/issues/116
======
slg
I really have a hard time putting as much blame on the author as the people in
that Github thread are doing. Maybe they could have handled this specific
issue a little better, but the underlying problem is just one of the flaws in
the open source community that everyone has to accept. Maintaining a project
is a lot of work (even just having your name attached to a dead project
involves work) and the benefit from doing that work can be non-existent. If
the original author has no use for the project anymore and someone offers to
take it over from them, why should the author be expected to refuse? Isn't
adding another potentially unknown maintainer generally better for the
community than a project dying?

~~~
ericcholis
It's better if the new maintainer's intentions are altruistic. From
@dominictarr, the maintainer:

> 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.

That's just plain irresponsible. He must have known how popular the library
was. Taking ownership of browser extensions and common software libraries is
becoming a very popular attack vector. Owners of these need to be a little
more diligent when transferring ownership.

Perhaps there should be some sort of escrow jail for new maintainers where all
changes are reviewed. Certainly better vetting needs to take place.

~~~
_wmd
This is entitlement speaking, and it's clearly a solution that doesn't scale.
Downstream _must_ be responsible for only depending on software from reputable
sources, there simply is no alternative.

I hate to have to do this, but the requirement runs right to the core of how
this development model functions _whatsoever_ :

    
    
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
        FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
        DEALINGS IN THE SOFTWARE.
    

I'd suggest one problem here is a user interface / packaging model issue: end
users / downstreams may override the version choices made by their upstream
dependencies. In the case here, the reputability of that upstream varied over
time. Permitting version locking allows a chain of reputability to be exist,
allowing a limited amount of trustworthiness to be imparted by upstream's
selection of dependencies ("I trust this guy's package, so I trust all their
dependencies too")

~~~
lsc
The real problem is that so far, open source has been mostly more responsible
than closed source. mostly. So many companies and people just go 'eh' and
accept the defaults rather than really digging in. Which, in a real way, means
they get what they deserve, but on the other hand, what is the alternative?

I mean, personally, the alternative _I_ like is a sort of hybrid model, where
you pay someone else to do the vetting, like RHEL, but nobody I support is
willing to stay within the RHEL package world, or to otherwise pay to really
vet the packages they use, so it's defaults all the way down, and it usually
works just fine! until it doesn't.

~~~
jwhitlark
It always takes time for parasites to evolve in a new system.

------
StavrosK
I had this exact same problem from both sides (not working on a project any
more and wanting to find someone to maintain it/wanting to maintain a project
someone wasn't working on because I found it interesting). It's not always
easy to find people who are interested, and, while giving maintainer access to
someone you know very little is usually fine and works out great, sometimes
you get results like these.

In the end, I built something to "solve" this, a project called Code
Shelter[1]. It's a community of vetted maintainers that want to help maintain
abandoned FOSS projects, so if you want your project to live on but don't want
to do it yourself, you just add it there and you can be reasonably sure that
nothing like this will happen to it.

Of course, you have to get a large enough pool of trusted maintainers that
someone will be interested in each project, but it's still better than blindly
adding people. I can't fault the maintainer of that project, since trusting
people is usually fine, but it's too bad this happened to him. The commenters
are acting a bit entitled too, but I guess it's the tradeoff of activity vs
security.

[1] [https://www.codeshelter.co/](https://www.codeshelter.co/)

~~~
samirm
Why would the average joe trust something like this? Your FAQ says each
maintainer is vetted and handpicked, but nothing about criteria or how they're
picked.

Do you mind explaining this vetting process a little more? How can we be sure
that something like this flatmap thing doesn't happen on codeshelter?

~~~
StavrosK
Sure! They're either people I know personally and trust (and hopefully people
will trust me to do this transitively) or they are people who are already
authors of popular libraries and have shown they are experienced in
maintaining OSS projects and trustworthy (since they're already pushing code
to people's machines).

Trust is definitely an issue here, and trust is something you build, so I hope
we'll be able to build enough trust to let people not think twice about adding
their projects.

~~~
baby
to quote linus: if you don't do security with a network of people you trust,
you're doing it wrong.

------
thrower123
NPM is just a mess, and the whole culture and ecosystem that surrounds it.
Micropackaging does make a little bit of sense at least in theory for the web,
where code size ought to matter, but in practice it's a complete shitshow, and
leads to these insane dependency paths and duplication and complete
impossibility to actually keep abreast with updates to dependencies, much less
seriously vet them.

The insidious threat is that these bad practices will start leaking out of
Javascript world and infect other communities. Fortunately most of them are
not as broken by default as JS, and have blessed standard libraries that
aren't so anemic, so there is less for this type of activity to glom on to.

~~~
joekrill
I don't see how this problem is limited to just NPM. This is a problem of any
package manager. Or any software distribution system in general, really. Look
at all the malware found on the Play Store and the Apple Store.

Unless you're willing to meticulously scrape through every bit of code you
work with you're at risk. Even if you can, what about the OS software? How
about the software running on the chipset? This is exactly why no one in their
right mind should be advocating for electronic voting. There's simply no way
to mitigate this problem completely.

~~~
nneonneo
NPM is quite a different software distribution mechanism than a typical app
store.

In an app store, apps are self-contained packages with low to no dependency on
_other_ apps in the store, meaning that a single compromised or malicious app
can only really affect that app's users. The OS may also isolate apps from one
another at runtime, further limiting the amount of damage such an app can do
(barring any OS bugs).

On the other hand, NPM packages depend on a veritable forest of dependencies,
motivated by the "micropackaging" approach. Look at any sizable software
package with `npm list`. For example, `npm` itself on my computer has over 700
direct and indirect dependencies, 380 of which are unique. That's bonkers - it
means that in order to use npm safely, I have to trust that not a single one
of those 380 unique dependencies has been hijacked in some way. When I update
npm, I'm trusting that the npm maintainers, or the maintainers of their
dependencies, haven't blindly pulled in a compromised "security update". And
`npm` is in no way unique here in terms of dependency count.

So this problem _is_ limited to NPM, as far as the potential impact of a
single compromised package goes.

~~~
chopin
Most Linux distribution package managers also draw in dependencies (alas not
that much as npm) automatically. You have to trust that all are vetted
correctly.

------
floatingatoll
Unpinned dependencies are harmful.

If you aren’t reviewing the diffs of your dependencies when you update them,
you’re trusting random strangers on the Internet to run code on your systems.

Espionage often spans multi-year timelines of preparation and trust building.
No lesser solution will ever be sufficient to protect you. Either read the
diffs, or pay someone like RedHat to do so and hope that you can trust them.

~~~
dmortin
If you have tons of depedencies then it's not feasible to check every diff.
You may able to do it or pay someone if you are a bigger organization, but a
small shop or solo developer can't do this.

~~~
choward
That's why you lock your dependencies.

~~~
dmortin
Dependencies need bugfixes and you may even want to use new features, so
locking is not a permanent solution.

~~~
twodave
If you're on point enough to know which features/bugfixes you're getting then
you're probably doing enough to be safe already. Just don't go around running
npm -u for no reason and you should be fine.

The only way to be truly safe from this attack vector is to own all of your
dependencies, and nobody is willing to do that so we're all assuming some
amount of risk.

------
rglover
That thread is a huge argument for paid software. It's mind blowing how folks
expect people to maintain things for nothing and get mad when it doesn't work
perfectly. Some silly choices were made by the original maintainer but give
the dude a break. He doesn't owe you a damn thing.

~~~
trickstra
do you know how many of your paid software contains a similar disclaimer that
removes their responsibility for the damages caused by the software? Only
you'd never have a chance to look at that code and find this injection...

~~~
rglover
You're not wrong; quite right, in fact.

My point here is less about payment guaranteeing a lack of bugs or having
someone to point a finger at and more at incentivizing the team building it to
fix things quickly. Of course, there's always the <Insert Negligent, Well-
Compensated Fortune 500 Company Here> problem, but that's a case-by-case
issue.

------
raesene9
Get ready for more of these type of attacks as time goes by, and they won't
all be as obvious as this one.

Supply chain attacks are increasingly being seen as a good vector and there
are thousands of unmaintianed Open source libraries buried in the dependencies
of popular projects.

Also worth noting that package security solutions, which check for known
vulnerabilities, are unlikely to solve this kind of problem unless they track
"known good" package versions and alert when things change.

------
Yetanfou
The (most recent) payload turns out to attempt to steal Bitcoin wallets:

[https://github.com/dominictarr/event-
stream/issues/116#issue...](https://github.com/dominictarr/event-
stream/issues/116#issuecomment-441745900)

------
kevin_b_er
Move fast and break things. I view this as an endemic fault of how npm, and to
a larger extent javascript, culture works and thinks.

I believe npm to be a giant landmine of untrustwothy packages thrown together.
No package is trustyworthy as the dependency chain runs too wide and too deep.
And having unwieldy dependency trees is considered a feature of npm.

~~~
tschellenbach
This exploit is not NPM specific, could be any programming language. (Though
NPM is a bit easier to exploit since there are so many packages and a large
tree of deps)

~~~
dkns
Would it be possible to put compromised package in Debian repository? Or has
something like this happened in the past?

~~~
flukus
It's certainly possible but to my knowledge hasn't happened. This case
specifically where a random person got the authority to publish new versions
would be prevented by debians organisational policies. Other distro's are much
less stringent and open to this kind of attack though, arch/yaort for instance
will happily install straight from github and this exact scenario could have
played out there.

The gatekeeper model is a proven one, be it an organisation like debian, a
paid curator like redhat or a locked down ecosystem like iOS.

------
CoffeeDregs
A related question: I'm a NodeJS, Python and Java user/developer; can anyone
explain why this problem appears more frequently in the _npm_ ecosystem than
in Maven, PyPi, etc?

Is it the Github-ization of package creation and maintenance? Is it the
pervasiveness of left-pad style packages? Is it _npm 's_ governance? Is it the
community's perspective and culture? Have the malicious just not made it to
other repo systems yet?

~~~
gkya
> Is it the Github-ization of package creation and maintenance? Is it the
> pervasiveness of left-pad style packages? Is it npm's governance? Is it the
> community's perspective and culture?

A nasty combination of all of those, probably some more.

I was very excited with Node.js when I first heard about it here on HN years
ago. I enjoyed watching Dahl's presentation. But as soon as the crowd that
went "it's JS, I can document.getElementsByClassName(...), so I can code
servers" flocked in and npm became a thing, that was the end of Node.js as a
nice, bright little thing.

I don't want to defend or encourage gatekeeping, but Node.js brought in lots
of folk that did not know what they were doing into software development, and
they did not stop to learn a thing or two before creating a monstrosity like
npm or making things like leftpad and this possible and popular. And there
wasn't any seasoned leaders like Python or Perl communities had, so all that
happened with no authoritative opposition. If it was Node.lua or Node.pl, the
world would've been a different place today for the software development
community.

~~~
joshmanders
> I don't want to defend or encourage gatekeeping

Goes on to defend and encourage gatekeeping.

~~~
gkya
Yes, that's what I do, and thats what the word "but" after the part you quoted
indicates.

If gatekeeping is bad, not checking who's passing through those gates when
they're wide open is worse.

------
rdtsc
Also note the same user owns this library:

[https://github.com/right9ctrl/node-
scrypt](https://github.com/right9ctrl/node-scrypt)

I would be very suspicious of that as well and audit anything that library has
touched.

~~~
luizfzs
I'm not a crypto guy but this change really makes me scratch my head:
[https://github.com/right9ctrl/node-
scrypt/commit/52a1cb792bc...](https://github.com/right9ctrl/node-
scrypt/commit/52a1cb792bc7ae0e4051ba4ad53e7b60fa5c806d#diff-91bff4c651c287ea055148b8b3eb1062)

~~~
regularfry
That just looks like a convenience function to me. Rather than passing
1,2,4,8,16 in as the value of N, you pass in 0,1,2,3,4. Has the benefit that
it's not possible to pass in a number that's not a power of 2 (which might not
be valid, I don't know how scrypt works).

~~~
CiPHPerCoder
IIRC scrypt is only defined for powers of 2 for N.

------
lexicality
Looks like the sleuths on github just found out it targets a bitcoin wallet
called `copay-dash`

[https://github.com/dominictarr/event-
stream/issues/116#issue...](https://github.com/dominictarr/event-
stream/issues/116#issuecomment-441744625)

------
marco1
We may need permissions for our dependencies (cf. Android apps). Ryan Dahl
already did this with Deno, specifically because he saw weaknesses in Node:
network, environment variables, file system, sub-processes.

We may need reproducible builds and reproducible minification. If we want
developers to audit their own dependencies, in case we deem that practical,
packages cannot ship their own minified sources. Auditing the non-minified
source is hard enough.

We may need (for-profit) organizations that audit packages and award their
official seal which you can trust before you add or update a dependency.

We _may_ need better standard libraries and fewer micro-packages.

------
wyldfire
> Now we have to run a background check when someone wants to help? The
> problem is in the tools.

I don't agree with this comment, really. But -- there's almost always room for
improvement w/tools. IIUC this unpacks encrypted JS bytecode and then executes
it? Is there any way to statically know whether this could happen?

    
    
        "var newModule = new module.constructor;"
        ...
        newModule['_compile']()
    

From what terribly little I know about Javascript it looks like it would be
hard to create a lint/warning that finds this sort of thing without false
positives. However, an audit tool that merely discloses this and any other
things-that-deserve-greater-scrutiny would be valuable. If you could walk your
dependency tree and see whether/when this changes, it would be very useful. Of
course, to be useful you probably need some kind of dependency pinning too,
which IIUC npm does not (yet) support?

~~~
yoklov
That doesn't look that far off from what you'll see in generated code, e.g.
something like babel could easily output the lines you've pasted.

The rest of it is extremely dodgy, of course.

~~~
wyldfire
I feared as much would be the case. Even in non-generated code there's perhaps
some instances where that code would make sense.

However, if you were to audit your dependencies and find a new case of this,
you could examine it further to determine whether it passes muster. I suspect
code like this is infrequently added to packages.

~~~
yoklov
Eh, again, this kind of thing is common for compiler output, and the use of
such compilers is very common.

I think you'd have more luck looking at static strings and warning on any
string that has a sufficiently high entropy. Sure, some of them will be hashes
for verification, or compressed harmless data, but it it seems like it would
be rare enough to be auditable.

------
paulsutter
This isn’t about Dominic, this is about using node for anything secure (for
example, somehow people use node in cryptocurrency projects)

If you have any security requirements whatsoever, and you are using node, you
need to do your own audits of the (hundreds of) packages you use. If that’s
not practical then node isn’t practical

------
dmortin
I guess it's not npm specific, because the same thing can happen in any other
open source repo, can't it? Some guy takes over maintenance of a dormant
package and then adds code which no one bothers to check.

~~~
ghostly_s
Well, not really. Anyone can "take it over" in the sense of creating a new,
maintained fork, but the various distro package managers have policies that I
think generally require some review/approval process to transfer ownership of
a package they publish. I don't know anything about NPM, but imagine it's a
more lax process than something like Debian. It sounds like the maintainer
here did something shady or simply reckless in effectively transferring
ownership but not disclosing this to folks at NPM?

~~~
raesene9
there's a split here.

Linux package managers (by and large) have a maintenance process.

Programming language package managers, by and large, do not

So this could happen on rubygems, PyPi, Nuget, etc

~~~
dcbadacd
Thankfully other languages really do require less less known external
packages.

------
tboyd47
I don't think most people in HN are seeing the real story here. This is not
another harmless stunt like left-pad to make us all wag our fingers at the
Node community. This is a coordinated, targeted attack on a popular Bitcoin
wallet software to steal private keys using a popular open source library and
NPM as an attack vector.

This is potentially the biggest Bitcoin heist since MTGox and the biggest news
in Bitcoin all year. The last time BitPay got scammed they lost 5,000 BTC and
that was back in 2015. I wouldn't be surprised if this is causing the current
mass sell-off. Does anyone know how to find real-time transaction volume stats
broken down by client, country, etc.?

~~~
danso
Most people on HN may not be Bitcoin investors. More HN people are probably
programmers who depend on open source.

------
ufmace
Makes me wonder if there's a business opportunity. Make your own version of
NPM, based off of the real NPM, but some level of auditing for package
updates. Don't report suspicious commits from new contributors right away,
that sort of thing. Charge companies a few hundred $ a month to use your site
instead of NPM, and they can update packages at will without risk of picking
up something nasty.

Then again, the fact that nobody has done this already suggests that it
wouldn't work.

~~~
cellis
Not really:
[http://www.paulgraham.com/schlep.html](http://www.paulgraham.com/schlep.html)

~~~
btbuildem
Schlep is precisely a business opportunity -- tedious drudgery that you have
to do regularly OR can pay and not worry about it again.

~~~
tomjakubowski
I think GP was responding to the second paragraph, which suggested that this
business might not be viable just because it hadn't yet been tried.

------
jt3
Would anyone want to support a third party which audits popular dependencies,
and digitally signs off after being reviewed? I currently audit source code
for private companies, would be cool to pivot and focus on open source
projects.

Feel free to email me, jt3@justin-taft.com

------
spondyl
This whole debacle has been really interesting.

I've personally met Dominic and chatted with him in the past (although I doubt
he would remember me) and he's a great guy. I may not agree with his world
views but he's respectable.

Just giving away a repo, and reading his description of it, sounds like
something he would do, haha. I'm sure from his view, he's just been open
sourcing experimental modules (however big or small) and that's all it is: fun

On the flipside, the inhouse CSS framework where I work actually pulls in
event-stream as a sub-sub-subdependency which could have bitten us possibly if
the attack wasn't so specific.

It's easily to blame Dominic but ultimately, he's just a guy who made some
code for fun and people started using it.

I'm sure when you're in a position like that, one of two things is likely:

1) You either don't look at download/usage analytics because why would you?
It's one of many projects and you're not measuring their success by anything
more than how you feel. People can use whatever code but it's not exactly a
product being sold

or

2) You do look at the numbers perhaps but 2 million people? How do you even
quantify that? It could be 1 million bots, 2 million hobbyists, 50,000
enterprises who don't cache internally and npm install over and over, or even
all 3 combined!

Anyway, this whole event hasn't happened in a vacuum so at least it'll
(hopefully) spark constructive discussion about the state of JS and
companies/projects relying on possibly unmaintained sub-sub-sub... you know

------
isseu
Someone post a list of every public package that depend on that one
[https://github.com/dominictarr/event-
stream/issues/116#issue...](https://github.com/dominictarr/event-
stream/issues/116#issuecomment-441731288)

A lot of very common packages...

------
jamp897
This is one of the gaping security holes that open source has always had, you
don’t know where the code came from and your best indication if it’s safe is
how popular it is. Npm and Maven libs being the scariest since there are
hundreds for even small apps.

~~~
syn0byte
Are those points not the same for closed source products? "You don't know
where the code came from" and "your best indication if its safe is how popular
it is."

------
g-harel
NPM needs to make accessing the source code easier. It has always bothered me
that the linked repository can be set to absolutely anything the author wants.

~~~
shados
Not sure how that would help. Anyone can publish anything to npm, it doesn't
even need a repository. So unless the source code itself was hosted on npm,
and the entire toolchain was controlled by npm, there's not much to do.

~~~
g-harel
Exactly, I think a source code browser on
[https://www.npmjs.com/](https://www.npmjs.com/) would be nice to have

------
ivanhoe
IMHO there are only 2 long-term solutions to this type of problems: 1) Reduce
the number of external dependences as much as possible 2) Pay authors to
properly maintain the packages that you rely on. If you use them on commercial
projects it's the first and the cheapest possible security measure you should
invest in.

~~~
abecedarius
The best solution is a module system that obeys the principle of least
authority. An event-stream library shouldn't be _able_ to find your
cryptocurrency wallet, or communicate back to its author either.

------
shshhdhs
Wow, looks like it was also used in Microsoft and BBC News repos.. unless I
read the updates incorrectly. Perhaps the attacker was targeting a specific
user?

------
staltz
I think the underlying issue here is ownership of a package, that is the
sensitive thing that was given away. This is why I prefer to publish scoped
packages, e.g. `@dominictarr/event-stream` not `event-stream` onto npm, so
that ownership doesn't need to be given away. If someone wants to give
continuity to the project, it can be done under a different fork. Also, it's
important to pin versions for immutability. Naive OSS software, with changing
owners and evolving versions, is essentially "mutable", and a weak spot for
attacks.

~~~
yuchi
Actually in such a case Domenic would have transferred the ownership of the
package anyway, probably retaining some power in the process, but the major
harm would have been done already.

------
anonlastname
Another example of how social engineering is usually what gets you hacked as
opposed to a software vulnerability

------
bandrami
So, I'm not a javascript person. I don't know the ecosystem that well. I'm not
really even a programmer except at gunpoint, just a sysadmin.

But even 5 years ago I remember thinking "400 dependencies for a project is
just WAY too many" and imagining something like this. And now I see some of
the big frameworks require literally thousands of packages. Is there something
about Javascript that necessitates this kind of ultra-fine hairsplitting on
packages, or could that be made better?

~~~
MrStonedOne
In the web, any dependencies have to be sent to the client as well, so making
them small and having the build chain handle grouping them all up in one
minified file is suppose to make things quicker for clients.

also languages like python require an affirmed compile time resolved call to
the classes so it can more easily know what code is not used or not going to
ever be used.

Javascripts string based introspection and runtime generation of code being
the backbone to the entire framework also makes it impossible to know what
parts of included code are even used, just because no code calls out to it at
build time doesn't mean the code isn't going to generate calls to it.

~~~
bandrami
People surely aren't evaluating strings in production code, are they? The
LISPer in me just died a little.

------
cellis
Is there a way to get stats on suspicious activity on NPM repos? I feel like
this is a service that every node.js project is in need of after left-pad and
now this.

~~~
kofejnik
check them into your git

~~~
dmortin
How does that help? You still update from time to time get fixes, new features
and then you can get some unwanted code which is not discovered yet.

~~~
kofejnik
it enables you to run git diff after updating your npm dependencies, so you at
least have a chance to detect something shady

~~~
bbody
In this situation, wouldn't it tell you the package had a version bump?

------
GordonS
Are there actually any future plans for JavaScript to add a decent standard
library?

Coming from other languages, the lack of built-in functions seems crazy, and
the NPM situation just _weird_. An empty template I use for bootstrapping
jquery-based web apps, based on using Gulp 4 for transpiling ES6, SASS
compilation etc, has a node_modules folder with 23,268 Files across 3,080
Folders!

------
olingern
I was understanding until I read:

"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."

in the thread. Then, I looked through the commits and realized how not ready
@right9ctrl was to maintain a heavily used package. Basic linting and small,
iterative changes are absent.

So, when I see Dominic-さん just "handing" the package over -- it seems
careless. This is often why -- I try to write my own packages unless I
absolutely need some sort of framework. It's trading one set of problems for
another (the potentiality for bugs vs. a package as a security issue).

------
bcherny
It looks like no one is even sure what the code actually does? Or am I
misreading that thread.

~~~
geocar
It's attacking a particular package -- some package out there depends on ps-
tree directly or indirectly, and its description is the secret key.

~~~
sroussey
Which means there is a finite list to check, unless the package is something
internal and not on npm.

~~~
evan_
from the github issue it looks like a couple people are working on that using
publicly available lists, and they've even found a few valid decryption keys,
but none that turn the payload into executable javascript

~~~
geocar
It's AES: Anything the right length will decrypt to _something_.

~~~
geocar
Aha: It's:

    
    
        npm_package_description = 'A Secure Bitcoin Wallet';

~~~
sroussey
Of course!

------
ianwalter
People have to understand that the Node.js ecosystem is different than in
other programming languages/platforms. Modules are composed from smaller
modules with a granularity so small that it is almost unique. When you're
publicly publishing something low-level to npm you really should understand
that the community may build on top of it to the point where it is used by
many modules and as a result used by many end-users. You are not obligated to
maintain it, but it's not really fair to be totally careless either. The
community is like society, if you're in it, try to be a good citizen or the
community will move against you to preserve it's ideals.

~~~
JustSomeNobody
So much irony here. So, the community can be careless and just import
whatever, but the maintainer can't pass maintainership on to someone else
without it being dubbed careless? Shouldn't this whole situation be the fault
of the community because they let in a bad actor? Society is great when
everyone is benefiting, but something goes wrong and out comes the pitchforks.

~~~
ianwalter
Don't get me wrong, I believe the author's heart is in the right place. I find
his willingness to be inclusive and get other people involved refreshing
actually, but the problem is that he should know better. He's seemingly used
npm enough to know that there is no mechanism within npm to notify downstream
modules that he is transferring the package to someone else (and that there is
now a new security risk that they must re-evaluate). The course of action
taken was simply not thought through. I'll leave it to others to explain what
the appropriate course of action should have been, but keep in mind that
society is built on trust, otherwise you have nothing to build on. You're too
busy doing every job instead of one that builds upon others.

------
jwlake
This is one of the reasons npm packages with a compiled minified dist js files
are a bad idea, makes hiding malicious code surprisingly easy.

~~~
kentm
I'm not sure that it would matter much in practice. I don't think anyone
really reads the code for their transitive dependencies.

------
zawerf
Anyone know how this was found and whether that process can be automated?
There are likely a lot more packages that are infected with the same
technique.

I looked at the linked commits: [https://github.com/dominictarr/event-
stream/commits/master](https://github.com/dominictarr/event-
stream/commits/master)

and it looks so surprisingly normal.

I am pretty sure I wouldn't have caught it even if I was code reviewing it.

Did someone heroically rerun every package's build process to see if the
minified output was tampered with?

~~~
gnulinux
For what it's worth: it'd be undecidable to catch all vulnerabilities even if
you very precisely define the semantics of your virtual machine, because it'd
require knowing whether a certain line of code will be executed, which is
known to be as hard as the halting problem. Practically, maybe? Maybe one can
use ML to check codebase for suspicious code. But in an ecosystem like npm no
matter what protection you have against hackers, someone will try very hard
and inject vulnerabilities like this. You should defend yourself and use
checksums for deps and execute only trusted code.

~~~
zawerf
Not really asking for perfect/decidable.

Just wondering out loud on how to detect even one of the other active exploits
that are surely in the wild. This one was live for 3-4 months before it got
found by luck?

For example I would really appreciate if they added something to detect/warn
when a package needs eval or http requests permissions (yes, I know npm
packages don't have a concept of permissions).

Anyway your commonly repeated advice on how to defend yourself isn't practical
(short of not using npm). The dependency that got me was nodemon. That ought
to be "trusted code" with 17k github stars, 1 million downloads per week but
apparently not. As I said already, even if I did check the commits to all my
dependencies, I don't think I would've caught this one. It's a one line change
in the minified build file of a transitive dependency nested 4 deep. All the
commits around it are very normal looking.

~~~
gnulinux
I wasn't intending to say reading every single commit of your dependencies is
practical. I was arguing that _unless_ you do that, you get absolutely no
guarantee of security. If you take code for granted because it has 17k
internet points, you're putting yourself at risk. I can't see how this is not
very simple.

~~~
zawerf
It's "very simple" that you will also "get absolutely no guarantee of
security" unless you personally rewrite every line of code you use in a
provable/verifiable language, design and manufacture your own hardware, hide
in a cave to avoid all social engineering, and so on.

Hopefully you see why your advice is similarly impractical.

------
jpalomaki
Running the open source projects through organizations like Apache Software
Foundation [1] would help. They can have processes for handling abandoned
projects and also set guidelines that projects must follow when it comes to
including 3rd party packages.

This is not just a security risk. There might be some business implications if
somebody would sneak in for example some AGPL licensed software to the
dependency chain of a popular package with more permissive license.

[1] [https://www.apache.org/](https://www.apache.org/)

------
jrockway
I love reading these threads. People seem to expect way more out of open-
source software than is actually guaranteed to them. It is a template of some
computer code that may be relevant to your work; nothing more, nothing less.
"I can't believe you let this happen to me!" Well, read the license: "THE
SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED". If you don't agree to that, you have no legal right to use the code.
Not sure what else there is to discuss.

~~~
jabberthemutt
> Not sure what else there is to discuss.

Morals and ethics.

~~~
PurpleBoxDragon
Is it ethical to use code while not agreeing to the license it is provided
under?

~~~
AndrewGaspar
The license doesn't say "You can't call the author out when they make a bad
decision"

------
vhost-
Might be unpopular, but I'm super okay with maintainers just disappearing and
ignoring their projects. Stop putting so much weight on the original package
namespace. I know it's a lot of work, but in my experience, when maintainers
disappear, the community creates a fork that's better maintained and people
migrate to that version.

I think if you want to stop working on a project, and it's on github, just
leave a note in the README, archive it and move on with your life. Don't give
the keys to someone on the internet.

------
nijave
Regardless of if the author's to blame, the outcome would be no different if
the author's Github account were compromised or the author themselves were
compromised/decided to act maliciously. In either case, user's of the code
also have an effort to act responsibly. Are any downstream package author's
that incremented the dependency or failed to lock it to a specific version
less culpable? (event-stream is being used by SuperPopularPackageX which
allows the compromised version)

------
AdmiralAsshat
Seems like we need a linter that can look for binary, hex, or otherwise
encrypted-looking data in source code (I have no idea how you'd teach the
linter to look for anything that "looks like gibberish"\--I'd leave that to
people smarter than me). From past experience with other popular apps that get
backdoored with bitcoin miners, anything intentionally obfuscated in what is
supposed to be an _open source_ application is almost always suspicious.

~~~
Severian
You could measure the entropy of single lines and determine if the entropy is
high. Although you'd probably get a lot of false positive.

~~~
gnulinux
You can probably just measure the entropy of literals, but then an attacker
might use reflection to construct arbitrary strings. Not an easy problem.

------
pier25
The problem with JS (Node and browser) is that the standard library is pretty
much useless.

What JS/NPM needs is some sort of certification program for secure libraries
that would fill the void of the lack of a standard library. NPM of course
would give a warning when installing a non certified library.

This would be a tremendous effort, but it would really be the only way for NPM
to survive in the long term. NPM is one of the reasons we've moved to Go for
our server side code.

~~~
malvosenior
> _NPM is one of the reasons we 've moved to Go for our server side code._

It's one of the reasons, but far from the only reason. With Go, Python, Rust,
Swift... is there any reason to use Javascript on the backend? Most attempts I
see to "share" code between the browser and the server end up adding needless
layers of abstraction and complexity.

~~~
smacktoward
The appeal of being able to use one language across the whole project, rather
than one on the backend and a different one on the frontend, is _very_ strong.

~~~
malvosenior
I know the pitch for this is _very_ strong but I've never seen any benefit in
real life. Javascript was designed to be a client side browser scripting
language, it's not equipped with a standard library that competes with other
languages that were designed from day one for the server or systems
programming. The skill sets of front-end and back-end developers are also very
different. In my experience, when you use Node you end up with front-end devs
programming back-end servers very poorly or you end up with back-end devs
forced to use Node/JS. I've never actually met a seasoned back-end developer
who would choose JS for the domain given no constraints.

------
gwbas1c
To the outsider, these threads assume so much context that they don't make
sense. (Of course, if you are a computer or you have intimate knowledge of
these tools, and these threads make perfect sense!)

Who, what, where, why, and how need to be answered.

Usually when there's a link like this on hacker news, one of the highly
moderated comments explains the situation in ways that don't require as much
context as a typical commiter would have.

~~~
jpmoyn
The original maintainer of a widely used npm package had moved on and didn't
have time to maintain the package anymore. Someone approached them asking if
they needed someone to take the reigns and maintain the package going forward.
That person was a hacker who, after having access to publish rights to the
package, installed a malicious dependency. Anyone who has updated the original
npm package within the last 3 months was hit by the attack. The details of the
attack aren't extremely clear, but a few comments suggest the code was aiming
to get bitcoin wallet credentials.

------
STRML
Scoping dependencies to their author by default would help (not eliminate)
this problem.

For example, if this had been @dominictarr/event-stream the entire time, and
he chose a new maintainer, that would then _by definition_ change the name of
the package to @right9ctrl/event-stream, requiring all users to intentionally
change their dependency.

Yes, it's painful. But it prevents getting caught out by a malicious patch
release.

That said, the whole github/npm relationship is broken to begin with. No
simple mechanism exists that I'm aware of to verify that a tag as pushed to
GitHub is exactly the same as what is published to npm. And due to various
prepublish hooks, it can be very difficult to actually prove this. One
solution would be GitHub support for building & publishing packages, with a
Travis-like build log, so users can be assured that the package as it sits on
npm actually was built from expected source.

@right9ctrl could have just avoided committing this entirely, and just
published a malicious patch release. If he had done that for a few days then
published another that removes the injection, it might have gone unnoticed for
months.

~~~
shados
> One solution would be GitHub support for building & publishing packages

Except you can build packages using one of a million different tools. Unless
you could only publish packages that were built using specific vetted tools
(and vetted plugins for those tools), that wouldn't change anything. If I can
change anything in the build pipeline, I can control the output.

------
geocar
Clever.

Something out there depends on ps-tree (directly or indirectly) and the
description in its package.json is the AES key for this string.

~~~
geocar
Aha: It's:

    
    
        npm_package_description = 'A Secure Bitcoin Wallet';

------
daburninatorrr
This situation reminds me a lot of the hypothetical situation outlined in this
post [1]. Definitely worth the read for anyone who hasn't already seen it.

[1] [https://hackernoon.com/im-harvesting-credit-card-numbers-
and...](https://hackernoon.com/im-harvesting-credit-card-numbers-and-
passwords-from-your-site-here-s-how-9a8cb347c5b5)

------
ultraluminous
All these arguments about Moral/Legal liability are just head-scathingly
nonsensical to me.

Look, if you're pulling external dependencies into your project from
_anywhere_ , and you don't version pin and hash compare those dependencies
every time you build, then you get _ZERO_ security guarantees. Simple as that.
You might have some "in a perfect friendly world" _expectations_ , but no
guarantees, no recourse and no one else to blame when the world does not
conform.

The notion that the author of the package could/should do anything to mitigate
that for you is ridiculous. Ignoring many, many plausible coercion/honest
mistake scenarios, just consider that a once-reputable maintainer can over
time _become_ malicious. That's it. If you have any actual real security
requirements, then I'm sorry but you don't get to say "but but but DRY!!!" and
call it a day. You are responsible for what software you run in your product.

------
tjholowaychuk
Semver seems like a huge problem here, blindly pulling in changes is just
asking for a lot trouble, intentional or not.

I'd also say NPM's centralized naming structure is also problematic, people
don't want to update 1000's of modules to some new latest version of X which
was forked and is now maintained, so it's handed off like this.

------
jrochkind1
it's kind of impressive this compromise was discovered _at all_. Anyone know
the story of how it was? There seems to be a lot of back story before the
linked issue begins.

I'm interested in who noticed the compromise, when, and how. Because with open
source, noticing the compromise is about the _best_ we can expect from a
"worst case".

~~~
igolden
A random, lucky find:
[https://github.com/remy/nodemon/issues/1442](https://github.com/remy/nodemon/issues/1442)

~~~
jrochkind1
Interesting. If the malware hadn't buggily triggered a deprecation warning...

~~~
gnulinux
Makes you think how many backdoors out there like this.

------
tschellenbach
I'm also a little bit pissed with the author of this repo. But seriously, how
can you vet everyone contributing to your unmaintained open source project..

Good security scanning and perhaps identity verification on Github could help.
So at least you can ignore pull requests from authors that didn't verify their
identity.

~~~
ocdtrekkie
You can't vet the people, but you can vet the code. Of course, if you just
give someone commit rights, then you can't. But generally speaking the
maintainer understands the code they merge into a project, and that is the
vetting that takes place.

~~~
shittyadmin
Sure, but then they have to actively invest time into the project... not
everyone can afford that.

~~~
heartbreak
Then mark the project as abandoned and add a note suggesting the new
volunteer’s fork.

------
robot2051
Not sure how useful this would be to anyone but i built this tool last year to
learn about Go and highlight issues with dependencies. This tool tries to
enumerate dependencies of the project and highlight concerning facts for each
dependency such as the size of collaborator, the age of the repository or if
it has not been updated for more than 6 months, etc.. The tool currently
supports go-dep, npm, pip, ruby-gem but ONLY support githubapi. The tool can
be found here if anyone is interested or just want an idea to write something
similar for the community:

[https://github.com/GovAuCSU/DRAT](https://github.com/GovAuCSU/DRAT)

Disclaimer: I am not a dev, just a pentester by trade so the code is probably
ugly as fuck for many of you =))

~~~
robot2051
PS: if you fork the project, it will have big security warning for
dependencies, that is because i have a couple of test dependency files for
pip,nodejs,rubygem for testing the crawler job.

------
altfredd
I don't believe, that Dominic (the former maintainer, who gave the control of
package to complete stranger) is the sole party to blame here. The biggest
responsibility lies with so-called "administration" of NPM, who have
systematically failed to promote security and robustness in their package
system.

The practice of handing control of open-source packages to new maintainers is
old and well-established. You can go to Sourceforge and request to take
control of any old, low-impact, unmaintained repository and Sourceforge
administration will likely grant it to you after a considerable delay and some
investigation (at least they used to do so in the past, not sure if they will
continue to after all this mess). The responsibility to ensure, that new
versions of packages haven't been subverted by malicious actors, have always
lied with people, who brought those packages into distribution — the package
maintainers. Unfortunately, NPM does not have any "maintainers" in the
traditional sense — package authors can't be trusted to remain impartial, and
"administrators" just sit on their backs, waiting for devs to fill their
repository with quality software. There is zero oversight — you can do
anything with your packages as long as it does not outright contradict local
law, including openly selling them to hackers, openly incorporating backdoors,
and even sabotaging entire package ecosystem by unilaterally deleting hundreds
of popular packages.

Covert transfer of control should not even be possible in centralized
repository like NPM. If you want to give your package to someone, that act
should be registered with repository administration, and future users of
package should be warned of it — just like users of services and goods are
commonly informed when an existing company changes it's organizational
structure. It is one thing to privately give access to Github repo to someone.
It is entirely different thing to hand over a repository package — which is
automatically distributed onto large number of computers around the world. In
later case authors, who failed to announce the change of ownership to
repository maintainers, should bear full monetary responsibility for their
actions.

------
yefim
This eerily reminds me of [https://hackernoon.com/im-harvesting-credit-card-
numbers-and...](https://hackernoon.com/im-harvesting-credit-card-numbers-and-
passwords-from-your-site-here-s-how-9a8cb347c5b5)

------
thomasjudge
Can I ask a simple question not being a javascript guy? Should this be
considered a security vulnerability in need of mitigation, ie should I try and
identify all the places this/these packages may used in our production code,
and ...do something?

------
anonytrary
This is one reason why you don't depend on trivial libraries you can roll in-
house and maintain yourself. Shame on people perpetuating the "depending on
is-array or left-pad is totally fine" ideology.

------
marcus_holmes
We're going to see a lot more of this. Dependencies are a security risk. If
you're writing a secure system that will be storing personally-identifiable
information as GDPR defines it, then you need to audit every dependency that
you include in your project (and every dependency that each of those
dependencies include). And then again every time they change version.

The golden days of including any old gem or npm package that seems to solve
the problem you're looking at are over.

------
xvector
Looks like the malicious commits were made with a fake user account. No
identifying information, barely any repos, generic profile picture.

------
koolba
Is there a way to run npm and show what _would_ be installed via an 'npm
install' short of actually installing it? That combined with a diff tool
against package-lock versions would limit the review list. AFAIK, the way it
is now you can't tell if one thing changed or one thousand until after
completed.

~~~
52-6F-62
Just add the --dry-run argument.

    
    
        npm i --dry-run event-stream

------
perpetualcrayon
We need to incorporate the fact that people will move on with their lives and
transfer ownership of projects.

This could be solved in a few ways.

Maybe instead of signing over ownership, maybe the protocol should be to force
a fork and make notes in the README that there's a new repo whose author has
not been vetted and should be used with caution.

------
Myrmornis
Is one solution a system where our ssh keys participate in some sort of trust
graph like SSL certificates do?

(I expect that question is very naive from the point of view of people who
know this area, but I'd be interested to be pointed in the right direction.)

------
mike-cardwell
It would be nice if we could pin libraries to a particular maintainer, as well
as a version.

------
dirkk0
Great breakdown of events here: [https://schneid.io/blog/event-stream-
vulnerability-explained...](https://schneid.io/blog/event-stream-
vulnerability-explained/)

------
smarx007
I know I am going to be in the minority, but I think it's time for the JS
community (and others) to reconsider whether Apache & Eclipse orgs with more
"rigid" governance requirements should used more for popular packages.

------
mehrdadn
I see a way to solve this with technology and that is for tools to allow
secondary developers to publish on the package repository, but after a
mandatory N-day delay. The main owner can then always have a chance to review.

~~~
yuchi
And then attackers would just wait that N days before pushing exploits.

~~~
mehrdadn
No, I meant every pushed change has to wait N days before being published to
users.

~~~
gnulinux
Doesn't make sense if the "owner" abandoned the project and N goes to
infinity. Then we have the same problem. If you're producing open source
software, you have ALL the right in the world to abandon a project for
arbitrarily large N days. If you don't want vulnerabilities, don't run code
from untrusted sources, simple as that. This whole discussion is a farce. The
reason open source comes with a license attached to it is for situations like
this.

~~~
mehrdadn
It makes a lot of sense if you realize many people who don't actively spend
time maintaining something might still have a desire to spend 10 seconds
glancing at others' changes to make sure their own rears don't get burned.

~~~
gnulinux
Sure, but this fails if they don't want to spend that 10 seconds, which they
totally are allowed to. Since there are hundreds of packages in your dep tree
and it takes only one attacker for all your bitcoins to be stolen, your scheme
is not enough.

------
sergiotapia
A lot of butthurt people railing on the guy. Maybe he just doesn't care
anymore about a dead package he has no intention of maintaining.

Blame yourselves devs, not the author who donated hours and hours of free work
for your benefit.

~~~
xvector
It’s about ethically handing off a package. No one is forcing him to maintain
it. But when you make a package used by millions of people, you become
responsible for their safety. To then hand over a package to a hacker or
unknown party is just morally wrong.

Just mark it as deprecated and call it a day, like a normal and responsible
person.

~~~
perfunctory
Well, he didn't really hand it over to a hacker, did he?

~~~
pcnix
His responsibility as a maintainer is to signal when there's a change in
power, since the package is trusted via his credentials.

~~~
perfunctory
> the package is trusted via his credentials.

Somebody really needs to explain to me how this works. The dude's bio on
github is "antipodean wandering albatross". Nothing against it btw.

------
jameslk
I see a lucrative business opportunity in alerting users when pwned/vulnerable
NPM packages are used in their projects. Maybe something like this exists
already?

~~~
scarejunba
GitHub does it for Ruby Gems.

~~~
wild_preference
They do it for NPM deps too.

------
fagnerbrack
STOP RELYING ON 10000000000000 PACKAGES FROM DIFFERENT PEOPLE! Create 0
dependencies packages or at least a package with dependencies you control!

------
gyrgtyn
If this is possible (a repo being maintained by not the original owner), then
you have to assume it's happening.

So how can you be mad?

------
lbj
This is bound to happen from time to time. We should invent some tools to nuke
the affected code from orbit.

------
epai
Tl;dr: event-stream repo was injected with an attack that crawls your
dependencies trying to find “copay-dash”. It then attacks it to steal all your
bitcoin. The attacker was given maintenance rights to the repo by simply
emailing the owner, who gave the rights freely. The owner and npm didn’t do a
background check. Because of the MIT license, the owner has no
liability/responsibility for his actions.

~~~
gnulinux
"Because of the MIT license" is a little misleading. Any FLOSS license out
there would disclaim the same sort of warranties.

------
riston
Instead of blaming the original authors of the package start contributing to
OSS.

------
mito88
$ npm ls event-stream flatmap-stream / └── (empty)

------
villgax
Boy am I gonna start versioning real soon.

------
daveheq
The more I read about major security vulnerabilities that should not have
passed inspection, the more I believe someone put it intentionally or was told
to.

------
timkpaine
its like watching people learn about the warranty clause of software licenses
in real-time!

------
joepie91_
Hi all,

Here's a quick summary of the situation.

WHAT HAPPENED?

==============

A widely-used dependency was handed over to a different maintainer, who
proceeded to add a malicious sub-dependency to it. The sub-dependency only
contained the malicious code in a single release, and only in the minified
version, likely to avoid detection.

WHAT DID THE MALICIOUS CODE DO?

===============================

The malicious code used the 'package description' to decrypt its payload; this
was done to ensure that the malicious code would only run when the dependency
was used in a specific application.

That specific application was the Copay Bitcoin wallet, from BitPay. The
malicious code injects itself into the application, steals the user's Bitcoin
wallet, and sends it off to a remote server. It's currently unknown who
operates this server.

There may be other forks or projects with the same package description, "A
secure Bitcoin wallet", that are also affected.

HOW DO I KNOW WHETHER I WAS AFFECTED?

=====================================

As a developer: Look in your `package-lock.json` or `yarn.lock` for an entry
of the `flatmap-stream` dependency, specifically version 0.1.1. Unless you
were developing on Copay, the code probably wouldn't have run, but you should
still remove the dependency.

As a Copay user: No release of Copay included this malicious dependency. It's
unclear whether copay-dash, a fork of Copay, did. Contact your wallet
developer for more information.

HOW CAN THIS BE PREVENTED IN THE FUTURE?

========================================

This is probably the most crucial question here. There's already a "lol JS"
bandwagon gaining steam in many places, but that's not really the issue here;
nor are small modules the issue.

Dominic Tarr is an established contributor to the ecosystem and part of the
community, not some random unknown party, so this issue would have existed
regardless of the size of the dependency.

I would argue that the real problem here is of a social and partly-economic
nature: There's no clear way for maintainers to find a good new maintainer for
their projects.

This is not a problem that is unique to JS, either; such support structures
are missing in most ecosystems.

As a developer community, we should probably have a serious discussion about
the security risks introduced by lack of funding, and by the lack of a support
structure for no-longer-maintained packages.

The latter can be solved on a grassroots level, without any payment being
involved. The former is going to involve funding models of some sort, and I
hope that this discussion can be had in a neutral manner, not as a marketing
pitch for a specific startup.

Another important problem is that there's essentially no code review tooling.
While in this specific case even a review would have been unlikely to catch
the issue, it's pretty much impossible right now to review all of your
dependencies in a project (in any language) without going crazy.

Possible solutions to that would include a review tracking system, that
integrates with your package management and flags any new dependency in the
tree as 'needs review' before accepting it.

------
admax88q
nodejs and the javascript community continues to be a shit show run by
amateurs.

------
always_good
There are a few issues with NPM that make this kind of thing especially
easy/lucrative:

\- An ecosystem of massive amounts of transitive dependencies increases the
number of people you need to trust. If I wanted to attack a project that used
NPM, their package.json dependencies would be a really good place to start.
Find the least popular transitive dep they use and email the owner to see if
you can be a contributor (repeat for all of their xdeps). If they don't
immediately give you publishing rights like OP did, then show some chutzpah
and make valid commits until they do. While this attack works on any
programming language's dep system, it's easier the more transitive deps a
project has. People ITT blaming the OP don't understand this attack always
works on a long enough timescale. Do you think there isn't someone out there
who would make high quality contributions to an xdep of primedice.com (online
gambling site) for 5 years to finally get publish access?

\- Anything may run during `npm install`. npm install supports an --ignore-
scripts argument to not run any scripts during install. This should be the
default.

\- Unqualified module names make it more desirable to "take over" a package
than just publish your own package "npm install <username>/event-stream", so
it contributes to an ecosystem of ownership-transfer that's far less likely to
exist on, say, [https://package.elm-lang.org/](https://package.elm-lang.org/)
where everything is qualified by a Github username.

\- NPM website doesn't show you source code. The github link on the project
page is just a convention. I think the NPM website should have a light source
code browser of whatever is in the tarball that you download and execute
during `npm install`. Bonus points for reproducible builds from that source.

\- Developers don't actually review every bit of code they use and execute,
especially not transitive deps. And we certainly aren't going to bother to
download the tarball from NPM and unpack it to inspect the code of every dep.
Most people reading this don't even know how to do that.

I've thought of some ideas to help the situation, like creating a Github
shield that verifies that a conventional build script like `npm run publish-
build` reproduces the tarballed code on NPM, but then I would just be doing
free work for the NPM organization, and it's still just a hack.

~~~
gyrgtyn
I don't see how the same thing couldn't happen with an elm package? The
attacker can commit to the github repo.

~~~
always_good
Be specific: what exactly would you do in Elm to pwn someone? It would be a
much more limited and a much more visible attack.

NPM modules don't even have source code on display. Someone has to download
and check the tarball before npm install.

Also, Elm packages are qualified by a github username so there isn't an
ecosystem of ownership transfer. No juicy name squatting. People just fork.

Finally, don't forget that my point is "there are a few issues with NPM that
make this kind of thing especially easy/lucrative". That's a far cry from
"everything else is bullet-proof" but it's tempting to argue with me as if I'm
saying that.

------
verytrivial
"Hey! This random piece of software I found under the table at the pub does
not have my best interests at heart?! My feelings are hurt!"

------
zeroname
Everyone is fired.

If you insist on pushing out hundreds of packages on npm, then drop support
for them and hand over rights to random strangers, you are acting completely
irresponsibly. You shouldn't be given a pass because you're doing it all
voluntarily. Your professional reputation should suffer for it.

~~~
tjholowaychuk
Easy for people who have zero packages and no pressure to say. Don't
contribute to OSS and you have no problems.

If these huge companies profiting off OSS work actually contributed
financially and with time, maybe maintainers would happily remain maintaining.

~~~
zeroname
> Easy for people who have zero packages and no pressure to say.

If you have this "no warranty, no responsibility" attitude then how can you
have pressure to maintain anything? How does that translate into pressure to
hand off the project to strangers? _Nobody_ asked for that.

> Don't contribute to OSS and you have no problems.

Yes, please _don 't_ contribute if you have this kind of attitude. It's
harmful. If you can't maintain the package, deprecate it. Don't hand it over
to an unvetted entity. If we can just agree on that M.O. we'll have a much
better situation.

> If these huge companies profiting off OSS work actually contributed
> financially and with time, maybe maintainers would happily remain
> maintaining.

Ifs and buts and sugar and nuts. They _don 't_ contribute, they never have and
they probably never will, _you_ are responsible for your packages even if you
are doing it voluntarily.

~~~
tjholowaychuk
Dozens of emails / notifications, people pinging / bothering you on multiple
platforms, multiple emails, etc.

It's stupid to blindly trust someone's code, regardless of who they are of if
they are the current maintainer, that is not how you build secure software.

If you want to start some organization which vets people for maintainers go
for it, but don't expect maintainers to do it, I can guarantee you that
thousands of maintainers do not. You're responsible for what ends up on your
servers.

~~~
zeroname
> Dozens of emails / notifications, people pinging / bothering you on multiple
> platforms, multiple emails, etc.

Two options:

1\. Stop supporting the package, mark it as deprecated, ignore/delete the spam

2\. Hand over project to a stranger, endangering all of your users

One of these options is irresponsible, the other one isn't. I'm not asking
anyone to do something for me, I'm asking them to _not_ do something for the
sake of sanity.

> It's stupid to blindly trust someone's code, regardless of who they are of
> if they are the current maintainer, that is not how you build secure
> software.

I agree, but both of us know that pretty much the entire Javascript ecosystem
_is_ exactly that stupid. Let me ask you: What have you personally done to vet
your dependencies? Have you used Babel or any of the other popular Javascript
packages that have a huge dependency tree? If you have, chances are you are
effectively blindly trusting all the developers in that tree. You're not
checking every single commit that goes into it.

> If you want to start some organization which vets people for maintainers go
> for it, but don't expect maintainers to do it, I can guarantee you that
> thousands of maintainers do not.

I don't expect that they do, I expect that if they fuck up that their
reputation takes a hit. That would some incentive for _not fucking up_.
Instead, there isn't even any consensus that this guy fucked up. He's taking
no responsibility whatsoever.

------
whitelister
Is anyone going to bother crawling through all dependents of this library,
extracting the package.json descriptions to find the proper key to decrypt the
string and find out which package was being targeted?

~~~
whitelister
The aes256 key is 'A Secure Bitcoin Wallet'.

------
G4BB3R
Well, it would not happen if people used Elm :)

~~~
always_good
This doesn't make sense because Elm is client-side only, and all code that
ships is client-side executable.

Node, a general purpose language, has a scope that's much, much larger.

------
antocv
Well this undermines everything dominictarr has done for secure scuttlebutt
and other projects, including datproject and its connection to Knight
Foundation.

"Oops, I just gave the repo to an unkown dude", OK. Sure. Just replace "unkown
dude" with "to my colleagues at 5 eyes secret service organization"

This kind of mistake is not a mistake, not from a dude like dominic.

~~~
AndrewGaspar
Seriously, I don't get how the others in this thread don't get this. Nobody's
talking about the legalese of the license - he's undermined his _own_
credibility, which is all that really matters in open source. If he's fine
with people not trusting his packages in the future, that's fine, but THAT's
the trade-off, regardless of how you license the code.

~~~
gregknicholson
He's been too naive and creduluous in judging a person based on limited
information. His coding skills aren't in question — the software was fine
while he was still in charge of it.

I suspect Dominic didn't see himself as _the_ maintainer of the package, but
as _a_ maintainer of a copy of the package (like how git is designed to work).
With this perspective, of course someone else can be a maintainer.

The problem is that NPM changed their upstream from Dominic to right9ctrl
without checking. (Maybe because Dominic clicked a button — NPM is still
responsible for accepting that decision or not.)

~~~
tjholowaychuk
Not to blame them NPM, they're great people, but I often get requests from
random people going through NPM support to use an existing name (saying they
will bump major).

The centralized naming scheme is to blame here, it normalizes these "cute"
names and users have demanded these since day one. They could/should have
probably been scoped from the beginning, or people should just stop trying to
capture fancy names.

I get tired of receiving emails about those kinds of things personally, you
try to just ignore them, sometimes their request sounds reasonable but still,
can those people be trusted, who knows.

~~~
preommr
> NPM support to use an existing name (saying they will bump major).

Sorry, could you please explain what this means? I keep seeing comments about
bumping version numbers (e.g. the right9ctrl did some shenanigans with
versioning).

~~~
tjholowaychuk
Ah sometimes you get people asking to use a name such as my "log" pkg in npm,
but bumping from 2.0 to 3.0 so that dependencies aren't messed up. Assuming
the person has no bad intentions I think it's a perfectly reasonable request.

I ignored this particular request via email a few times, because I just really
don't want to spend time dealing with Node stuff. You then get a request from
NPM support asking the same thing, so I agreed to it, that's all it takes to
get access to a package really.

I think from now on I'm just going to tell people to come up with a different
name, this wouldn't be a problem if the names were scoped by default.

