5 ms·
When Heartbleed was a topic of discussion, some pointed out that Rust wouldn't have 100% protected from that vulnerability. So it is good to see some proof tha
by stonemetal12 4y ago
When Heartbleed was a topic of discussion, some pointed out that Rust wouldn't have 100% protected from that vulnerability. So it is good to see some proof that using a safer language does in fact pay off in terms of fewer defects. I just wish there were some info around cost associated with development effort. Did the Rust code take longer to develop? If initial development was longer, what if we include time saved from reduced effort for bug resolution?
- phlip9 4y agoI think even heartbleed would be mitigated with (safe) Rust. IIRC heartbleed was caused by a missing bounds check, which allowed attackers to read past the message buffer and leak secrets from nearby memory. Safe Rust would just panic (crash) if you tried to slice past the end of the buffer.
- estebank 4y agoAn example from an experiment to benchmark Rust and Java I did recently, where I sent files from one app to another: perf was good enough without tuning, with tuning I could triple the speed and final total time on both versions was comparable. Memory was much greater for Java (even with graalvm). The Rust version didn't suffer from any memory safety issues or race conditions when sending multiple files, but I did have a vuln where you could specify a relative path that could escape and write anywhere in the receiver's filesystem. Rust didn't protect me from that, and those are the kind of vulnerabilities that we'll continue seeing regardless of language. But the threat surface I had to be scared about was much smaller than it would have been in other languages. And because the fallible APIs are obvious, I handled many edge cases that I might have forgotten about otherwise.
- selfmodruntime 4y ago>Rust didn't protect me from that, and those are the kind of vulnerabilities that we'll continue seeing regardless of language I'm still thinking about how we could integrate something like that in a language or the languages package manager. I'm unsure if it's possible.
- estebank 4y agoThe only things I can think of is the use of newtypes around PathBuf that enforces things like expansion and that makes the check for you when restricting tk a specific directory. Now that I'm writing this out, this feels like it could be a very useful small crate or addition to Camino. Thank you for making me think further about this. Of course, the impl would have an associated runtime cost for the check and a more involved API surface because it's asking the developer for more information. But once you do that you can have an TryInto<PathBuf> impl to pass it to any standard method.
- manbart 4y agoHow about in the OS? This sounds like exactly the type of thin SELinux is meant to handle
- insanitybit 4y agoYeah, I think the thing is... path traversal is pretty trivial to solve. If you have a single tenancy app and you just don't want the service accessing shit it shouldn't just throw it in docker. If you have a multi-tenancy app just put every user behind a uuid.
- fiedzia 4y agoIt's possible and easy (have types for path coming from untrusted source), but it's a matter of a standard library rather than a language.
- stonemetal12 4y agoIn C++\Java this would be solved by a static analysis tool. For example Fortify covers this error.
- mcronce 4y ago> Rust didn't protect me from that, and those are the kind of vulnerabilities that we'll continue seeing regardless of language. It didn't on its own, but it is worth noting that with type-safe languages, you can protect yourself from this by encoding that invariant into the type system. Using Rust as an example, take a &std::path::Path (or &camino::Utf8Path or whatever) in your public API; have custom InternalPathBuf and InternalPath types that perform validation to ensure they aren't using relative paths to "break out" during construction, and then pass those around in your internal API. Bingo bango, now there's no way (short of transmuting, an `unsafe` operation) to pass invalid paths to the functions that hit the filesystem without a compile error. No redundant runtime checks required, and no need for you as the developer to keep track of which codepaths have already validated a Path and which haven't. I'm sure you already know this, and I would imagine that Java can do the same, but it's a big step above languages like Python where you can do whatever you want to anything you want. EDIT: lol while I was typing this you made a post about the same thing below.
- estebank 4y agoGreat minds and all that :) I guess it is also an often used square peg that fits really nicely in the square Rust typesystem hole (no, not talking about those typed holes, haskellers).
- scns 4y agoThis technique is mentioned in the article. It is called the Typestate pattern: http://cliffle.com/blog/rust-typestate/ http://cliffle.com/blog/rust-typestate/
- kobebrookskC3 4y agomaybe https://docs.rs/cap-std/latest/cap_std/fs/index.html https://docs.rs/cap-std/latest/cap_std/fs/index.html would prevent that?
- insanitybit 4y agoCapabilities are a good way to mitigate this problem, yes. At minimum cap_std::fs would prevent "../" attacks. "../" attacks are also just way less of an issue when you shove your programs into minimal containers, which at this point is more or less standard practice.
- eklitzke 4y agoRust and C++ are about equally difficult (or easy) to program in, the languages are much more alike than they are different.
- kaba0 4y agoYeah, Rust is basically modern C++ idioms made mandatory by the compiler (move, copy semantics).
- jackmott 4y ago