Live data from Hacker News

A routine gem update ended up creating $73k worth of subscriptions

serpapi.com

111–120 of 336 posts

Re: A routine gem update ended up creating $73k worth of subscriptions

#111

I wish more developers would abide by the old saying "don't fix it if it ain't broke." It's one thing to update because you know a newer version has fixed a bug you're experiencing, but if everything is already working as you'd expect, IMHO you're just asking for trouble. There's a reason a lot of the infrastructure systems that many people don't even know about --- until something breaks --- hasn't changed in litera…

You are asking for security issues if you take this approach. Better to increment on several small iterations of dependencies, making changes accordingly, such that you will be able to take a CVE-fixing patch without having to refactor your entire app all at once.

Introducing changes to the semantics of query operators in minor releases sounds like a great way to introduce security issues.

How many CVEs over the years are because of someone screwing up their operator precedence in permissions checks?

Re: A routine gem update ended up creating $73k worth of subscriptions

#112

Earlier quoted context omitted.

I don't think you can ever make a breaking change like the one described. There's just no way to audit the correctness of all your users after that change. You need to leave the old thing with the old behavior and only add the new behavior to a new thing.

Rails changed the meaning of NOT and nobody batted an eye - https://til.hashrocket.com/posts/3zyftipjiu-rails-will-chang... These sorts of changes do in fact happen fairly frequently and developers need to be aware that they can't blindly accept upstream dependency changes.

That is asinine. Why not change it in 5.x->6.0 if they knew it was a problem. Why even use version numbers at that point? Just use DateVer or 0ver at that point.

Re: A routine gem update ended up creating $73k worth of subscriptions

#113
post #112

Earlier quoted context omitted.

Rails changed the meaning of NOT and nobody batted an eye - https://til.hashrocket.com/posts/3zyftipjiu-rails-will-chang... These sorts of changes do in fact happen fairly frequently and developers need to be aware that they can't blindly accept upstream dependency changes.

That is asinine. Why not change it in 5.x->6.0 if they knew it was a problem. Why even use version numbers at that point? Just use DateVer or 0ver at that point.

> Why not change it in 5.x->6.0 if they knew it was a problem

Because Rails explicitly has a versioning policy where minor versions are equivalent to SemVer major versions (but with deprecation notice in a previous minor version) and where major versions are also SemVer major with subjective significance distinctions; they call it “shifted SemVer”.

https://guides.rubyonrails.org/maintenance_policy.html

This is somewhat obnoxious, but not as bad as saying you use real SemVer and then brazenly breaking things in minor releases.

Re: A routine gem update ended up creating $73k worth of subscriptions

#114

Earlier quoted context omitted.

> Mongoid follows versioning guidelines as outlined by the Semantic Versioning Specification, so you can expect only backwards incompatible changes in major versions I will note that this reverses the direction of implications. In SemVer, you should expect breaking changes only in major versions. (All version changes with breaking changes should be major, but nonbreaking changes can occur in major or minor versions.)…

They may actually mean what they say. It’s not uncommon for projects to release the last minor version at the same time as the next major. For example, Drupal 9.0.0 was functionally equivalent to Drupal 8.9.0, except 9.0 had all deprecations dropped. New 9.0+ only features didn’t show up until 9.1.

Yeah, that is probably the smart way to do it. Frontload all of your necessary new features in 8.9/9.0-dev (so you can complete the deprecations), roll over the major and remove only the deprecated code paths without introducing any new ones.

Re: A routine gem update ended up creating $73k worth of subscriptions

#115

Breaking change on minor version changes. Ouch. Not a MongoDB expert, but you don't really need an 'ORM'[0] do you? I thought it spoke JSON natively like couch. If I was in this project I might have argued strongly for just doing that. Others might have argued back telling me that we can't possibly send JSON to a thing that expects JSON that's too low level, let's rely on this library by some guy instead. Sorry, flas…

I think Mongoid is an official MongoDB lib. But yeah, we should have used the raw Ruby MongoDB client at least for this. This way the code would have been more explicit.

Re: A routine gem update ended up creating $73k worth of subscriptions

#116

That sounds like a major, incredibly dangerous update to the DB driver. Their 7.1, 7.2, 7.3 versions seem to all have breaking changes [1]. Yet they are in obvious violation of SemVer expectations, which they declare to follow [2]: > Mongoid follows versioning guidelines as outlined by the Semantic Versioning Specification, so you can expect only backwards incompatible changes in major versions [sic] [1] https://docs…

Yeah, semver is great, except nobody follows it. The amount of times I have updated minor or even patch releases of packages with things breaking--I have pretty much determined everything in a project stays the same unless there's some pressing need.

The worst part is that breakage is often far from obvious, and spending good time wondering why everything breaks when it shouldn't is really really infuriating and makes me feel like the entire world of software is hopelessly broken.

Re: A routine gem update ended up creating $73k worth of subscriptions

#117

Earlier quoted context omitted.

They don’t need to keep anything. The card details will be stored with Stripe, if they don’t actively tell Stripe to delete those details then they’ll be able to create a new subscription and charge the card. For the vast majority of cases all you need to charge a card is the 16 digit number on the front and an expiry date. Pretty much everything else is optional (CVV, Name, Address etc), but opens you up to stupid l…

Card issuer risk model heuristics will also apply different amounts of scrutiny based on transaction size and type. You could do a two dollar transaction just with card number, I wouldn't expect a twenty thousand dollar transaction to go through without the other fields.

Yes-- at my local suoermarket a small purchase will just go through, while a larger one (~$25 is the threshold) requires a signature.

Re: A routine gem update ended up creating $73k worth of subscriptions

#118
post #62

Earlier quoted context omitted.

probably a combination of realistic-seeming desktop browsers (eg. headless chrome with stealth patches) and residential IP providers (eg. luminati)

Their website says >In addition, each API request runs in a full browser, and we'll even solve all CAPTCHAs. Mimicking completely what a human will do. Wow how would they do that?

Not sure, but maybe they use a CAPTCHA-Solving-API like https://anti-captcha.com

Re: A routine gem update ended up creating $73k worth of subscriptions

#119
post #93

Earlier quoted context omitted.

> All dependency changes are changes. And changes should be tested before being deployed. OP did not say changes should not be tested. > If you update your dependencies and ship it based on version numbers alone, you can’t blame the maintainers OP did not if you update your dependencies and ship it based on version numbers alone you can blame the maintainers.

Shipping something with zero testing is always crazy. Even a minor bug fix in a library can expose a critical bug in your own code.

There's a huge difference between "zero testing" and "we didn't have this particular test case covered because the state space is massive". Lets say you even have "100% code coverage", do you really have a unique case for each possible condition in that query? Often times chaining operators like TFA give "deceptive" coverage results because they mark that whole code path as covered, without verifying the state space of the operands is covered fully. You can sometimes "cheat" coverage e.g. by using ternary operator assignment in place of if/else (often by mistake).
Post reply on HN