1. 32
  1.  

  2. 4

    This is a pretty good overview! Using the .init_array section to hide code the OS runs for you on load is pretty ingenious. Also as a die-hard member of the “crates.io without namespacing is just fine the way it is” camp (and let’s not start that debate again please), the “misleading name” part is a pretty good argument for privileged namespaces.

    Some of these exploits can be mitigated by efforts like cargo-crev and rustsec, which I have high hopes for since they have tools for checking dependencies and those can be built into automated workflows. But they still require work both for people to find the vulnerabilities and heed them when they are found.

    1. 1

      Not asking you to restart the namespaces debate, but do you know what I should look for to find what people have said about it?

      1. 2

        users.rust-lang.org has several megathreads about it with lots of arguments for and against. There are lots of reasons, but ultimately it’s crates.io team’s decision. They know the trade-offs, and have deliberately chosen a single namespace.

    2. 4

      Couple of more cases (although these won’t work for transitive dependencies):

      • use .cargo/config to override rustc to do a bad thing
      • use rust-toolchain.toml for the same effect

      See https://github.com/jonas-schievink/mallory for examples.

      1. 2

        I really wish articles like this would provide more background on how to improve the status quo. At this point it is well known that package managers/repositories are definitely a weak link in the ecosystem. There’s nothing new I learned from this article that would increase the security of the code I am writing/the dependencies I am using.

        Ultimately it is up to the goodwill and trust I place in random strangers. Same way I trust that the maintainers for my operating system won’t package malware (even accidentally). At some point you have to place your trust somewhere.

        1. 3

          My personal takeaway is that it’s time to get serious about using machine level isolation for day-to-day development, since no better protections are coming along to help me. It kind of sucks to treat your own codebase as potential malware, but maybe that inconvenience is just a “cost of doing business” in development ecosystems driven by self-published libraries?

          1. 2

            I wish we had a better solution than this, because this doesn’t prevent malware from getting into executables, so your production environment or machines of your users remain vulnerable.

          2. 1

            Review the dependencies. Do it with cargo-crev, so others could benefit from your reviews and you could benefit from theirs.

            Even just looking through cargo tree and asking “what’s this crate?” is better than nothing (it could save you from typosquatting, at least).

            1. 1

              Start with signatures. The maintainers of my operating system cryptographically sign the packages I install. I choose to trust them because their signatures are tied to real identities verified in real life. Bad stuff can still sneak in through key theft, malicious trusted individuals and problems up the supply chain, but having a trust infrastructure is table stakes.

            2. -7

              This is why Rust’s ecosystem is fundamentally and unrecoverabky broken and which is why I’m glad to be able to rely on my package manager and large standard library in C.

              Probably the only reason why Rust crates aren’t pwned to oblivion is the fact nobody cares about Rust other than evangelists and those who still have to find out how messy it is.

              To provide an alternative, look at Ada, an absolutely beautiful and secure language with many great ideas and concepts.

              1. 4

                Probably the only reason why Rust crates aren’t pwned to oblivion is the fact nobody cares about Rust other than evangelists and those who still have to find out how messy it is.

                Okay, I don’t really care about Rust, but I doubt this. If I were to hazard a guess, I’d say that the real reason is more likely that executing effective attacks this way is complicated, it’s still a fairly new area, and the Rust community is waking up and mitigating some of the flaws in what is undoubtedly a flawed system.

                If nothing else, there is a lot of money to be made successfully exploiting Rust, given the number of high-profile projects now adopting it. Like it or not, Rust got past the ‘only evangelists and idiots’ phase a long time ago, and the teams using it are, with the best will in the world, not going to rewrite their code in Ada. I don’t see the point in writing it off like this.

                1. 4

                  nobody cares about Rust other than evangelists and those who still have to find out how messy it is

                  I care about Rust and I’m neither.

                  1. 1

                    It’s a little bit easy to just point at the shortcomings of one side but ignore the other. You’re trading a mature ecosystem that allows git commit tagging to something that doesn’t even have a definition of external library except for linking with what ever is currently in your path variables. Which is neither secure nor reproducible.

                    What you’re suggesting is that we should all go and rely on your package manager not to break or get pwned (which did happened multiple times in debian). This kind of build system has no idea of versions, security updates, revocation and such, it just ships what happens to be the thing that got into your package management, together with all the changes they thought are useful. (And sometimes, they actually make it worse.)

                    There is much to be said about securing build scripts and macros, but most of the things shown in this article also work with c (make scripts, macros, init functions..). And due to all the shortcomings of C it is even easier to hide something in there. When you use what debian ships for TLS, you hopefully trust the debian people (and transitively the authors) and you trust people building your software to have an up to date version of it. When you pin stuff in rust, you trust the people running crates.io (see debian) and the authors that put stuff up there. But your users (or upstream distro) will have to actively select a bad version when building it, to get the same effect. Pick your poison.

                    In a perfect world we sandbox any build scripts and macros and use the rust-sec extensions for crates.io to verify the trustworthiness of our dependencies. At that point the only thing that can go wrong is a malicious build, built inside your sandbox, delivered to everyone.