The whole point of the article is you should implement CSP.
By the time it's all said and done, my "simple" Node project pulls in several hundred dependencies (I didn't go through and count, but my 'yarn.lock' on that project has ~4200 lines). I can't audit all of that code.
A well known German blog just claimed that creating a new skeleton project using @angular/cli results in 31 direct dependencies, almost a thousand dependencies in total and 300 MB code.
That's just wow.
Which Time Zone? Hah!
(Not that this one nit pick takes away from the general very well made point of the article, I just love how TimeZone problems infect everything)
Anyway, I'm being pedantic. There are a lot of great points in this article.
Of course, we all do this. /sarcasm
I thought npm was simply a package manager - I don't see anything in the article that is specific to npm, except he happens to say that word.
Two is that much of it is expected to be served to the browser, so it's minified. Who audits that the minified code is actually the same as the published Github code?
At least in Ruby and Python, the code from Rubygems/Pip should exactly match that version on Github. Not that anyone necessarily audits that either, but at least it's easier.
Otherwise, yes this is a fundamental dependency issue.
im a total noob at security, please attack/modify this idea if it has any value?
I question all these comments by people singling out npm as the root of the problem. doesn't sound to me like they fully understand the issue.
The next problem is that npmjs is "free for all". Imagine anyone could easily add new packages to the debian repo. Sure, I don't expect the debian folks to audit every new addition or update to existing packages, but there is at least some chain of trust, plus there is some incentive to not have malware ridden packages in your distro because it hurts your credibility. A distro is both, an infrastructure and content provider. npmjs is just the infrastructure, so it takes some more messups for people to consider moving away from it.
This same problem would exist if any server-side dependency repositories allow for code to be delivered in a pre-compiled form without any verification, similar to npmjs.
The amount of times I've gone to npmjs.com, looked for the "official" version of a package only to get lost in a web of conflicting version and ownership "signals" is staggering. And yet... if it's on npmjs.com, then it's going into your package.json. No one audits that thing. Unless there is an obvious bloat issue. And dependencies of dependencies? NEVER. We have something like 400MB of shit in our node_modules folder. There is no human on earth that could go through that. This is a few times the size of the entire Linux kernel, for context. And it's minified.
> I’ve now made several hundred PRs (various user accounts, no, none of them as “David Gilbertson”).
> I go through all the passwords and credit card numbers I’ve collected and bundle them up to be sold on the dark web.
So if you get caught, you don't actually exist and you've already sold it all without any traces.
That did mean no jQuery, no Google Analytics, no NPM modules and we had to build it as a standalone page outside our React setup, but it's worth it to be able to definitively inspect every line of code and provide a CSP that locks that page down tight to just our subdomain and our vendor's.
Except that being responsible for your dependencies (and the dependencies of your dependencies...) is impossibly hard. You would need to build everything yourself after auditing the code.
You still need to get the source for all your dependencies and all of their dependencies and so on and build it yourself, but you should probably do that anyway and host the artifacts in your own private repo. That’s good practice and avoids issues like the left-pad thing.
For example, JS doesn't have a standard library. Many languages do. So when JS downloads loads of transitive dependencies, many are there because there's no stdlib.
Have you audited your C++, or Java, or Ruby, or... stdlib lately? Especially those that come preinstalled with your OS of choice?
Same goes for anything that you download via Maven, or gems, or easy_install, or include as direct GitHub references in your Go code.
Have you examined them, though? ;) And yes, I was thinking about Reflections on Trusting Trust as well :)
> In almost all cases, there are no transitive dependencies not managed by the same people.
That's why I said the risk is spread very differently compared to JS :)
If CSP is enabled, the frontend checks to see if the backend code has opened up the particular port or route on the backend.
The back-end code could sniff through require.cache to see if he could hook into the existing server instance ( same port ), or open a new port ( depending on CSP ).
I suppose the CSP equivalent on the backend is some sort of firewall. I also suppose servers have better monitoring of requests. Still, this method would circumvent CSP!!!
Also, hooking into the existing server instance would throw red flags if the instance was ever console.logged. You might also do an audit of your ports and see a suspicious one opened in that method. And a firewall likely would block other ports. But, still, it's feasible even with a CSP, until discovered.
This applies to almost any backend web framework and package manager, but the culture of micro packages in npm suits itself well to this attack.
(I’m only half joking)
EDIT: oh, CSP pinning is actually a thing that’s been proposed https://www.w3.org/TR/csp-pinning/
Take an npm module. It does setInterval and every minute, it checks require.cache for any file with 'config' in it, and sends it to the crook. Is this possible currently?
I would think npm modules should be require-sandboxed to their own directory. Even then, there is compiled code, etc. Oy vey.
Where I work, outbound requests must be made through proxy servers which have a whitelisted set of allowed domains, which is only allowed after a security review.
It also depends on the page you are visiting. If it's just some random post on net I actually don't care much if they do manage to post data elsewhere (the risk in that case is actually higher if I allow ajax.googleapis.com than some random non-google page), but with banking sites and credit card forms you need to be careful.
Amazon has no CSP at all, nor does eBay.
But too-many-dependencies is a problem there too.
Some guy made a cookie session middleware called node-yummy, which eventually became a dependency of Express.
Express has a bajillion downloads, so yummy up and brokered a deal by which on every install they tweeted a like for Hot Pockets.
So, Hot Pockets really started soaring, with no one having any idea what they were tweeting by installing and updating Express, until someone ruined all the fun by posting it on Medium, and getting picked up by HN 
IMO the really not acceptable part is that the open souce projects are not being pulled from Github. When something claims to be open source, we should have a gaurantee from NPM that we can see the source.
The current setup implies the opposite
At the time, I'd never added anything to npm, but since then, I have. It dawns on me that npm versions aren't tied to git revisions at all!
The ship has probably sailed on that line of thinking but in my opinion a lot of the pain we experience in web security today comes from people trying to do things they really should not be doing.
If you need to write a full application why does it have to happen in a browser? Why can't we use the model so successfully employed on mobile devices?
1. Only activate on sessions where it’s never activated before.
2. Only activate one in, say, seven times.
3. Sniff form once, fail to submit, show user "unexpected error, try again", allow normal behavior, success, user moves on
4. pull the numbers
It’s nice to imagine we follow up every single JS or user reported “it fails sometimes?” error, but a clever malicious script author knows we don’t check 100% of the time.
We are required to expect transient and potential errors from third party services, not even Stripe has 100% uptime. This kind of theft looks like a transient and unexplainable error.
An attacker could try to POST the values directly to Stripe instead, but Stripe presumably uses CSRF-prevention techniques (eg. a token in the form) to stop this as well.
1. Use social engineering to get your package included as a dependency;
2. Use obfuscation techniques to hide the real intent of the package;
3. Capture data and send it off to a remote server.
First can be pulled off, but really depends on the community / maintainers doing their job right. In case of Django, I imagine that would be pretty hard - while the codebase is giant, by itself it has no other dependencies (except stdlib and pytz). Then 3 could be either much easier or much harder on the backend, depending on how well the box is secured (e.g. outgoing firewall rules).
However the impact could be much more severe, since you're executing code on the server - at the very least you can inject any malicious JS you like, rewrite the CSP headers (if present), just dump the entire DB right away, and a lot of other bad things.
This basic recipe has a chance to work regardless of the target language/package manager. It's all up to your dev process and security regime to catch it.
Although this is all made up, it worries me that none of this is hard."
So if you want to steal passwords, make some extension like "Mp3 Youtube Downloader" or "Ad Blocker" and get access to millions of happy users' browsers.
CSP looks like an ugly hack rather than a good solution. Why would you need to specify allowed sources for scripts if you control your HTML code? I don't understand why the author praises it. What a stupid time-wasting technology.
Because it appears to be the ONLY solution to the problem described, unless you never use any third party code that you didn’t build from source and audit.