Shouldn't have happened: A vulnerability postmortem

This page summarizes the projects mentioned and recommended in the original post on news.ycombinator.com

Our great sponsors
  • WorkOS - The modern identity platform for B2B SaaS
  • InfluxDB - Power Real-Time Data Analytics at Scale
  • SaaSHub - Software Alternatives and Reviews
  • ring

    Safe, fast, small crypto using Rust (by briansmith)

  • Note that the readme is outdated. With the upcoming 0.17 release, which is in the making for almost a year already, you can use link multiple versions of ring in one executable: https://github.com/briansmith/ring/issues/1268

    Similarly, while the policy is still that ring only supports the newest rust compiler version, due to the fact that there has been no update for months already, you can use it with older compiler versions.

    Last, the author used to yank old versions of its library, which caused tons of downstream pains (basically, if you are a library and are using ring, I recommend you have a Cargo.lock checked into git). This yanking has stopped since 3 years already, too.

    So a great deal of things has improved, although I'd say only the first bullet point is a permanent improvement, while the second two might be regressed upon. idk.

  • sudo

    Utility to execute a command as another user

  • How do you know that it was actually "extremely well-maintained"? Everybody thought OpenSSL was well-maintained since it was used as critical infrastructure by multi-billion dollar megacorporations, but it was actually maintained by two full-time employees and a few part-time volunteers with maybe a quick once-over before a commit if they were lucky. How about sudo, a blindly trusted extremely sensitive program [1], which is maintained by basically one person who has nearly 3,000,000(!) changes[2] over 30 or so years?

    Assuming that something is well-maintained because it is important is pure wishful thinking. Absent a specific detailed high quality process, or an audit that they conform to a well-established process that has demonstrably produced objectively high-quality output in a large percentage of audited implementations of that process (thus establishing nearly every instance of the audited process -> high quality output) all evidence indicates that you should assume that these code bases are poorly maintained until proven otherwise[3]. And, even the ones that are demonstrably maintained usually use very low quality processes as demonstrated by the fact that almost nobody working on those projects would be comfortable using their processes on safety-critical systems [4] which is the minimum bar for a high quality process (note the bar is "believe it is okay for safety-critical"). In fact, most would be terrified of the thought and comfort themselves knowing that their systems are not being used in safety-critical systems because they are absolutely not taking adequate precautions, which is a completely reasonable and moral choice of action as they are not designing for those requirements, so it is totally reasonably to use different standards on less important things.

    [1] https://news.ycombinator.com/item?id=25919235

    [2] https://github.com/sudo-project/sudo/graphs/contributors

    [3] https://xkcd.com/2347/

    [4] https://xkcd.com/2030/

  • WorkOS

    The modern identity platform for B2B SaaS. The APIs are flexible and easy-to-use, supporting authentication, user identity, and complex enterprise features like SSO and SCIM provisioning.

    WorkOS logo
  • tiny-rust-executable

    Using Rust to make a 137-byte static AMD64 Linux executable

  • go-licenses

    A lightweight tool to report on the licenses used by a Go package and its dependencies. Highlight! Versioned external URL to licenses can be found at the same time.

  • > I don't think the exact URL is the problem, it is the fact that it is so easy to include dependencies from external repository that is the problem. In Rust every non-trivial library pulls in 10s or even 100s of dependencies.

    But it's also quite a lot easier to audit those dependencies, even automatically (incidentally, GitHub provides dependency scanning for free for many languages).

    > Then there is the issue of licencing - how to verify that I am not using some library in violation of its licence and what happens if the licence changes down the road and I don't notice it because I am implicitly using 500 dependencies due to my 3 main libraries?

    This is also an automated task. For example, https://github.com/google/go-licenses

    > go-licenses analyzes the dependency tree of a Go package/binary. It can output a report on the libraries used and under what license they can be used. It can also collect all of the license documents, copyright notices and source code into a directory in order to comply with license terms on redistribution.

    > Rust and Go have solved memory safety compared to C and C++ but have introduced dependency hell of yet unknown proportions.

    I mean, it's been a decade and things seem to be going pretty well. Also, I don't think anyone who has actually used these languages seriously has ever characterized their dependency management as "dependency hell"; however, lots of people talk about the "dependency hell" of managing C and C++ dependencies.

    > Python and other dynamically typed languages are in a league of their own in that on top of the dependency hell they also do not provide compiler checks that would allow user to see the problem before the exact conditions occur at runtime.

    I won't argue with you there.

  • trophy-case

    🏆 Collection of bugs uncovered by fuzzing Rust code

  • You need to read the list more carefully.

    • The list is not for Rust itself, but every program every written in Rust. By itself it doesn't mean much, unless you compare prevalence of issues among Rust programs to prevalence of issues among C programs. For some context, see how memory unsafety is rare compared to assertions and uncaught exceptions: https://github.com/rust-fuzz/trophy-case

    • Many of the memory-unsafety issues are on the C FFI boundary, which is unsafe due to C lacking expressiveness about memory ownership of its APIs (i.e. it shows how dangerous is to program where you don't have the Rust borrow checker checking your code).

    • Many bugs about missing Send/Sync or evil trait implementations are about type-system loopholes that prevented compiler from catching code that was already buggy. C doesn't have these guarantees in the first place, so lack of them is not a CVE for C, but just how C is designed.

  • JDK

    JDK main-line development https://openjdk.org/projects/jdk

  • I think you're making my point for me, no? Your arguments are all variants on "I don't understand modern Java and prefer to keep writing buffer overflows than finding out".

    To answer your questions:

    1. Java is these days like UNIX, there are lots of compatible "distros". OpenJDK is the upstream on which most of them are based. You can just use that unless you have some particular preference for the other vendors.

    2. You don't need to install Java alongside your app. The JVMs is just a library and a few data files. You can easily bundle it with your app and the user will never know.

    3. JCA/JSSE is built in to Java so there's nothing to build. Additionally you don't have to build Java libraries to use them anyway, because binary distribution works so everyone just distributes binary JAR files.

    4. The source code is spread around several modules because JCA is pluggable. But for example a lot of the crypto code is found here:

    https://github.com/openjdk/jdk/tree/master/src/java.base/sha...

    5. Oracle maintains it. It's released under the GPL with Classpath exception license. They aren't going to come after you for using it - there are 12 million Java developers in the world. The only company that has ever got sued is Google and that's because they violated the (at the time non open source) license of Java to make a mobile version that wasn't from Sun. Since then Java became fully open source and this no longer applies, and it'd have never applied to normal users of it anyway.

    I'm not trying to convince you here of anything, only to point out that everyone saying "there was no alternative" is just wrong. The failure mode here is not sufficiently advanced fuzzers. The failure is that there has been an alternative to NSS for years but C++ shops like Mozilla keep maintaining crappy decades old C libraries with memcpy calls all over the place, because they know and like C. That's it. That's all it boils down to.

  • automaxprocs

    Automatically set GOMAXPROCS to match Linux container CPU quota.

  • AFAIK, it hasn't changed, this exact situation with cgroups is still something I have to tell fellow developers about. Some of them have started using [automaxprocs] to automatically detect and set.

    [automaxprocs]: https://github.com/uber-go/automaxprocs

  • InfluxDB

    Power Real-Time Data Analytics at Scale. Get real-time insights from all types of time series data with InfluxDB. Ingest, query, and analyze billions of data points in real-time with unbounded cardinality.

    InfluxDB logo
  • rfcs

    RFCs for changes to Rust

  • Preventing timing leaks requires unsafe code because the Rust compiler lacks support for constant-runtime code [0]. Adding that support is one step in making it "good enough to use for everything".

    What are several more of the "plenty of reasons to occasionally use unsafe code"? I can think of only one: interfacing with hardware or unsafe OSes that control access to the hardware.

    [0] https://github.com/rust-lang/rfcs/issues/2533

  • CppCoreGuidelines

    The C++ Core Guidelines are a set of tried-and-true guidelines, rules, and best practices about coding in C++

NOTE: The number of mentions on this list indicates mentions on common posts plus user suggested alternatives. Hence, a higher number means a more popular project.

Suggest a related project

Related posts