Live data from Hacker News

Strong_password Rubygem hijacked

withatwist.dev

21–30 of 133 posts

Re: Strong_password Rubygem hijacked

#21

Earlier quoted context omitted.

Sure, obviously reinventing as many wheels as possible will minimize your exposure to third-party malfeasance. As in all forms of engineering there are, of course, no absolutes, only trade-offs to be made. The more wheels you reinvent, the slower your velocity for solving the core business problems that pay your bills. Moving too slowly can be fatal to the business. It’s a tricky balance. Signing isn’t perfect, but i…

Reinventing the wheel is one end of the spectrum, but so is putting a bunch of magic words in a file and thinking you needn't worry. (To be fair, too many tutorials hand wave away what really happens in Gemfile/package.json/etc and barely pay lip service, if at all, to the responsibilities that come with having those dependencies) I don't miss the "old" days of searching for libs, extracting a zip, and trying to figu…

> Reinventing the wheel is one end of the spectrum, but so is putting a bunch of magic words in a file and thinking you needn't worry.

Yeah. I didn’t claim otherwise? Like I said, there are only trade-offs here. You can gain a ton of velocity if you abstract it all out to a file of 50,000 “magic words”; but obviously then your exposure to these issues is enormous.

Trade-offs are like that.

> I don't miss the "old" days of searching for libs, extracting a zip, and trying to figure out the integration steps, but there is something to be said for there being a bit more of a sense of ownership.

Eh, to the extent that I get any such feeling, I think it’s mostly a completely false sense of security. I did some stuff in a C++ codebase that was fully developed that way, and did the ol’ “hunt, unzip, and compile” for some boost libs. I didn’t audit the source. It being boost C++ god knows if I’d even have been able to recognize a heavily template-metaprogrammed exploit.

If boost’s account had been compromised I’d have been every bit as fucked as people who use this gem were. Supply chain attacks are dangerous regardless. All you can do is try to balance your exposure vs your time spent on solving problems that don’t pay the bills vs those that do.

Re: Strong_password Rubygem hijacked

#22

We need a sort of capability and permission method for libraries. For example a "strong_password" library should only by given "CPU compute" permissions, no I/O. But even with this, the problem will be like we see on phone, popular libraries will require all the permissions. You'll want to install React, and React + it's 100 dependencies will request everything.

There is a bunch of work going on for this in JavaScript see https://www.infoq.com/news/2019/06/making-npm-install-safe/ for links.

Re: Strong_password Rubygem hijacked

#24

We need a sort of capability and permission method for libraries. For example a "strong_password" library should only by given "CPU compute" permissions, no I/O. But even with this, the problem will be like we see on phone, popular libraries will require all the permissions. You'll want to install React, and React + it's 100 dependencies will request everything.

To be honest, even the coarsest-possible permissions of "can do I/O" vs. "can't do I/O" would be exceedingly effective at stymieing these sorts of attacks; all malicious software of this sort needs to do I/O at some point, and relatively few libraries actually have a good excuse to do I/O (though logging might be thorny).

That said it seems easier said than done to impose those sorts of restrictions on a per-dependency basis. Attempts to statically verify the absence of I/O sounds like a great game of whack-a-mole, and I don't know how you'd do it dynamically without running all non-I/O dependencies in an entirely separate process from the main program.

Re: Strong_password Rubygem hijacked

#25

Earlier quoted context omitted.

Hm, interesting. One way to solve this would be to have a language with a very rigid import system - it should be _impossible_ for a library to use a module it hasn't imported, even if that module has been loaded elsewhere in a process. This is probably harder than it looks, and many languages have introspection features that are incompatible with this goal. With a rigid import system, each library would be forced to…

> With a rigid import system, each library would be forced to declare what it's going to import (including any system libraries), and then you could e.g. enforce a warning + confirmation any time an updated dependency changes its import list. Which means you would get warnings on pretty much any functional upgrade of most dependencies, which would make the whole system useless from a security point of view.

In theory, a point release of a library really shouldn’t be requiring new permissions, and you shouldn’t be randomly upgrading your code to newer major versions without checking for compatibility anyway.

Why should a functional upgrade of a dependency introduce new dependencies anyway? A library that sets out to do a particular thing shouldn’t grow new features that require new capabilities willy-nilly.

Re: Strong_password Rubygem hijacked

#26

Earlier quoted context omitted.

Sure, obviously reinventing as many wheels as possible will minimize your exposure to third-party malfeasance. As in all forms of engineering there are, of course, no absolutes, only trade-offs to be made. The more wheels you reinvent, the slower your velocity for solving the core business problems that pay your bills. Moving too slowly can be fatal to the business. It’s a tricky balance. Signing isn’t perfect, but i…

I interpreted that differently: it's fine to have many dependencies, even third-party ones. What's a problem is having many third-parties. The maintenance and trust verification overhead for a micro "5 lines of code" dependency is usually way higher than just rewriting those 5 lines yourself. As an aside: just because someone made their code available doesn't mean it's good or that it solves all your edge cases. Gett…

> The maintenance and trust verification overhead for a micro "5 lines of code" dependency is usually way higher than just rewriting those 5 lines yourself.

Sure. I was in no way advocating “JS-style, 5 line microlibs Uber Alles”, merely pointing out that there’s a clear trade-off between dependencies and velocity that there’s no silver bullet for.

There’s absolutely nothing wrong with OP saying “we can afford to make Spring our only dependency”, but there’s also nothing wrong with saying “we need actor-based concurrency and the business will be dead before we roll are own, let’s bring in Akka”, “we need to deal with time and spending 40 hours a month keeping up with every legislature on the planet’s timezone-related lawmaking doesn’t pay the bills, bring in JodaTime”, etc.

It’s engineering; these trade-offs should of course be carefully considered (is_even should fail most any sane consideration), but it’s a bit silly to suggest they can just be avoided entirely by businesses that have to make money to pay the bills.

Again, signing helps when you need to make those trade-offs. There are no absolutes here.

Re: Strong_password Rubygem hijacked

#27

We need a sort of capability and permission method for libraries. For example a "strong_password" library should only by given "CPU compute" permissions, no I/O. But even with this, the problem will be like we see on phone, popular libraries will require all the permissions. You'll want to install React, and React + it's 100 dependencies will request everything.

I know this is about ruby, but it's worth noting that this kind of thing would be solved by effect systems, e.g. Haskell's IO type. If IO isn't part of the signature, you know it's cpu only. Furthermore, you can get more specific such as having a DB type to indicate some code only has access to databases rather than the internet as a whole.

I think you'd also need to prevent things like unsafePerformIO, and equivalent loopholes.

Re: Strong_password Rubygem hijacked

#28

We need a sort of capability and permission method for libraries. For example a "strong_password" library should only by given "CPU compute" permissions, no I/O. But even with this, the problem will be like we see on phone, popular libraries will require all the permissions. You'll want to install React, and React + it's 100 dependencies will request everything.

So, we need a version of pledge from OpenBSD that can surround components / classes https://man.openbsd.org/pledge.2 https://www.youtube.com/watch?v=bXO6nelFt-E

Re: Strong_password Rubygem hijacked

#29
post #24

We need a sort of capability and permission method for libraries. For example a "strong_password" library should only by given "CPU compute" permissions, no I/O. But even with this, the problem will be like we see on phone, popular libraries will require all the permissions. You'll want to install React, and React + it's 100 dependencies will request everything.

To be honest, even the coarsest-possible permissions of "can do I/O" vs. "can't do I/O" would be exceedingly effective at stymieing these sorts of attacks; all malicious software of this sort needs to do I/O at some point, and relatively few libraries actually have a good excuse to do I/O (though logging might be thorny). That said it seems easier said than done to impose those sorts of restrictions on a per-dependen…

> That said it seems easier said than done to impose those sorts of restrictions on a per-dependency basis.

Isn't this the sort of thing type inference is made for? Along with return types, functions have an io type if they're marked (std lib) or if they contain a marked function. Otherwise they have the pure type.

Re: Strong_password Rubygem hijacked

#30
post #24

We need a sort of capability and permission method for libraries. For example a "strong_password" library should only by given "CPU compute" permissions, no I/O. But even with this, the problem will be like we see on phone, popular libraries will require all the permissions. You'll want to install React, and React + it's 100 dependencies will request everything.

To be honest, even the coarsest-possible permissions of "can do I/O" vs. "can't do I/O" would be exceedingly effective at stymieing these sorts of attacks; all malicious software of this sort needs to do I/O at some point, and relatively few libraries actually have a good excuse to do I/O (though logging might be thorny). That said it seems easier said than done to impose those sorts of restrictions on a per-dependen…

> running all non-I/O dependencies in an entirely separate process from the main program.

Maybe that's not such a bad idea. This "strong_password" thing is written in Ruby, a few milliseconds delay is probably not noticeable anyway and vastly preferable given the security implications.

Post reply on HN