4 ms·
Asking for some feedback for Node.js What (if at all) should Node.js do better to protect users from this sort of attack vector? Is a deno-like surface where
by inglor 8y ago
Asking for some feedback for Node.js
What (if at all) should Node.js do better to protect users from this sort of attack vector?
Is a deno-like surface where users opt into packages getting network permissions desirable? More guides on npm-audit or stronger auditing tools?
- koolba 8y agoExplicit whitelisting for network access. Explicit whitelisting for fs access. A programmatic way to tell if the publisher of a module has 2FA enabled. I’m a fan of public shaming to enable 2FA, if not making it mandatory (again tricky if you have automated builds).
- michaelmior 8y ago+1 to this. I hadn't heard the suggestion of making 2FA use public before, but I really like the idea.
- andrew_ 8y ago-1 to this. while 2FA is a no-brainer for most of us, publicly listing (or showing status) not only encroaches individual liberty to make a choice, it would open such users to be targets of an attack. Enforcing 2FA in an organization seems more appropriate. Perhaps npmjs.com has implemented that since last I looked, but I know in the past that enforcement was not available. I also greatly dislike the trend of public "shaming" that's so prevalent today. The internet has made us cruel.
- akvadrako 8y agoIndeed, why would we want to use packages from people who can't be bothered to use 2FA?
- koolba 8y ago> -1 to this. while 2FA is a no-brainer for most of us, publicly listing (or showing status) not only encroaches individual liberty to make a choice, it would open such users to be targets of an attack. Saying that you refuse to enable 2FA is the information security equivalent of saying you refuse to wear a condom. Of course people are free to make their own choices but I personally wouldn't take anyone who publishes software seriously if it's not enabled. This isn't like securing access to a social media or shopping account. The ramifications of a breach can quickly cascade and 2FA is low hanging fruit to stop a lot of that. It's far from perfect but it goes a long way. > Enforcing 2FA in an organization seems more appropriate. Perhaps npmjs.com has implemented that since last I looked, but I know in the past that enforcement was not available. The nested nature of dependencies makes partial enforcement pointless: A (2FA) > B (2FA) > C (2FA) > D (no 2FA!) > I also greatly dislike the trend of public "shaming" that's so prevalent today. The internet has made us cruel. I wholeheartedly agree with you on both points and, outside of security, I can't think of any other example where I'd be open to it. I like to think I hold myself and people in our own industry to higher standards than the Internet at large.
- Kalium 8y agoI, too, greatly dislike the cruelty of public shaming. It's inhumane, and dehumanizes us all. Recently I was tasked with improving 2FA usage in my company's GitHub organization. My first approach was to nicely, neatly, and personably ask people, coupled with regular announcements to make sure everyone knew. Every interaction came with documentation on how to do it and a sincere offer to walk them through it. Totally reasonable approach, executed with kindness and compassion. The cynic in me was unsurprised when this rapidly became a Sisyphean task. A number of people, upon faced with being informed in half a dozen different ways, professed to have no idea that they were expected to enable 2FA. Others swore up and down to me that they knew what to do and would shortable enable it, only for it to still be off a week or more later. At this point I decided that kindness and human compassion were a drain on my time and clearly ineffectual. So I grabbed a junior engineer and we wrote a script that automatically removes from the org anyone who doesn't have 2FA enabled. Announced it to everyone, every manager on board, and turned it on. Overnight, the problem went away, and has largely stayed away. Once in a while people publicly ask why they were kicked out and are reminded that they were informed of the 2FA requirement. This isn't an approach characterized by humanity and kindness. It is, however, one that is effective and time-efficient.
- snowwolf 8y agoWhy did you need to write a script? GitHub allows you to enforce 2FA at the organisation level. https://help.github.com/articles/requiring-two-factor-authentication-in-your-organization/ https://help.github.com/articles/requiring-two-factor-authen...
- Kalium 8y agoYou're absolutely right! GitHub does offer that wonderful feature. There are some legacy bot accounts that we cannot readily tradition to 2FA and we cannot do without. The feature you have so rightly pointed to would evict them from the org. That's not an acceptable outcome in this case. I skipped over this in my previous comment because I felt it wasn't germane to the story or the point.
- probably_wrong 8y agoI hope you also publicly shame services that only offer 2FA in exchange for your phone number. My phone number identifies me much better than my email address and/or cookies ever will. As someone who cares about privacy, I don't give it to anyone. And yet, publicly shaming me for not enabling 2FA would shame me by proxy for caring about privacy.
- selbyk 8y agoSecurity > Privacy, and there are plenty of ways to get static burner phone numbers for a small fee if privacy is that important to you. (Skype, Google Voice, Burner Phone, etc)
- inglor 8y ago> Explicit whitelisting for network access. > Explicit whitelisting for fs access. Would you (or anyone else reading this) be interested in exploring what that would look like for Node.js? (If you do, feel free to reach me at my email in https://github.com/nodejs/node https://github.com/nodejs/node under benjamingr) I think it would be interesting - one solution could be a loader (ESM) that only lets you load other "unprivileged" files by default - then importing things like `child_process` or `fs` could require more privilege. A little like how apps work. > A programmatic way to tell if the publisher of a module has 2FA enabled. I will bring this up. Personally I think I understand the objection of the reply below about this information being risky. That's something NPM likely can/should solve and not Node.js. For what it's worth GitHub orgs can already tell who has or doesn't have 2FA. Node.js itself for example enforces GitHub 2FA for all the organization. I assume GitLab has a similar feature.
- Waterluvian 8y agoNot just network permissions, opting into what local directories it can see. Allow it to see absolutely nothing but its own directory and temp. I don't have a good answer on a good method to override this when necessary. Ideally never, but realistically some form of whitelist. npm-audit is good for post-disaster cleanup, but it's too late to prevent anything.
- inglor 8y ago> Not just network permissions, opting into what local directories it can see. Well, one way I personally do this for my own stuff is with Docker. The problem is that I don't think it's reasonable to expect every developer to run in Docker - at least until it's at least as easy as the atlernative.
- Waterluvian 8y agoMaybe I just haven't taken the time to learn Docker well enough but the blocker that stopped me from doing this last time is how much my dev environment (VSCode and other tools) depend on my node package and its dependencies being accessed from a certain spot for import autocomplete, intellisense, etc.
- infogulch 8y agoThis was the blocker for me to use it on my local machine as well. How can we fix this? Is there a way to do it without updating every tool to explicitly special-case docker? Dev machines are one thing, but there is no reason our CI tools should ever expose credentials in a way that is accessible to any build or test step. Build and test steps should be sandboxed to take input and produce an artifact, which is then uploaded to wherever in a completely separate sandbox.
- t3h2mas 8y agoWhen I develop locally using Docker, I live link my code directory into the container. I.E. docker run -v "$PWD":/some/app/location ... My editor doesn't know I'm using Docker. You can change your workflow when you want to deploy to a container registry, etc.
- vorpalhex 8y ago1. Sandbox file access 2. Limit network calls without additional permissions 3. Warn when the dependency tree goes too deep (8 or 9 levels of deps) 4. Better auditing of suspicious patterns (accessing .npmrc should throw a flag)
- inglor 8y ago> 3. Warn when the dependency tree goes too deep (8 or 9 levels of deps) Hmm, why? > 4. Better auditing of suspicious patterns (accessing .npmrc should throw a flag) As in - when `.npmrc` is accessed as a result of `npm install` you would want NPM to warn?
- vorpalhex 8y agoI can't imagine most modules need to read or write your .npmrc directly (npm itself does). That should flag a module (with the understanding that I'm sure there's some modules that do legitimately need that access - eg to easily swap which registry you're publishing too). When a dependency tree starts going too deep, it's too easy for malicious modules to get snuck in. You pull in Popular Library X which depends on well-known module A, which in turn pulls in shim B, which in turn depends on an unpinned utility C. Somebody sneaks a malicious hook into utility C which isn't used directly by anybody really, but propagates the malicious code to all the users of Popular Library X (eg Babel).
- tolmasky 8y agoNot a solution for everything, but one of the key reasons we made RunKit is precisely to allow you to try random packages without giving them access to your computer (its basically an easy way of the "run everything in a Docker container" suggestion below). NPM links directly to this where it says "try <package> in your browser", but you can also just do it yourself: https://runkit.com/new https://runkit.com/new.
- lewiscollard 8y agoHow about something like OpenBSD's pledge(2) system call [0] for Node? First: everyone decide on a set of potentially dangerous things for a program to do. Three examples off the top of my head: disk I/O, accessing the network, executing external programs. A function could declare that it will only do some subset of potentially-dangerous operations, and an exception will be thrown if either it or anything further down the call stack does any of the others. In this particular case it seemed to be some post-install build script that caused it - but if this was present in the Node core would it be that difficult to implement in npm (i.e. "my post-install script and its dependencies will only ever do disk I/O")? If this is possible, and if it was adopted in the community widely enough, this would halt the imminent "some thing I depended on depended on something else that depended on a string function that turned into a credentials hoover" apocalypse... [0] https://man.openbsd.org/pledge.2 https://man.openbsd.org/pledge.2 [edit: very tiny clarification]