5 ms·
I don't understand this argument. For example, if I use a language that doesn't allow buffer overflows to happen, I've eliminated an entire class of security bu
by seanwilson 12y ago
I don't understand this argument. For example, if I use a language that doesn't allow buffer overflows to happen, I've eliminated an entire class of security bugs being caused by programmer error. Why would you not want to use such a language? Performance and existing libraries will factor in to this obviously but I don't understand why you wouldn't consider security built into the language as a benefit.
Yes, security issues are found in Java and every other language, but when these are patched all programs that use that language are patched against the issue. The attack surface is much smaller.
- AnthonyMouse 12y ago> Yes, security issues are found in Java and every other language, but when these are patched all programs that use that language are patched against the issue. The attack surface is much smaller. All patches work like that; when there is a bug in libssl and OpenSSL patches it then all the programs using libssl are patched. The difference with Java is that when a C library has a bug only programs using that library are exposed but when Java has a bug all Java programs are exposed. Moreover, Java itself is huge. It's an enormous attack surface. Your argument would hold more weight if the "much smaller" attack surface actually produced a scarcity of vulnerabilities.
- weland 12y ago> For example, if I use a language that doesn't allow buffer overflows to happen, I've eliminated an entire class of security bugs being caused by programmer error. There are several assumptions behind "if I use a language that doesn't allow buffer overflows to happen" which you aren't taking into account. For instance, are you entirely sure that the implementation of that language's compiler will not allow buffer overflows to happen? We have a good example of a possible failure of that model in Heartbleed: when it came up, a bunch of people in the OpenBSD community raised their eyebrows, thinking hmm, that shouldn't happen for us, we have mitigation techniques for that. Turns out -- for performance reasons -- OpenSSL was implementing its own wrappers over native malloc() and free(), doing some caching of its own. This, in turn, rendered OpenBSD's own prevention mechanisms (e.g. overwriting malloc()-ed areas before using them) useless. The language specifications may not allow such behaviour, but that doesn't mean the implementation won't, too. You're also underestimating a programmer's ability to shoot himself in the foot. Since I already mentioned OpenBSD and Heartbleed, here's a good example of a Heartbleed-like bug in Rust: http://www.tedunangst.com/flak/post/heartbleed-in-rust http://www.tedunangst.com/flak/post/heartbleed-in-rust . The sad truth is that most vulnerabilities like this one don't stem from accidental mistakes that languages could have prevented; they stem from fundamental misunderstanding of the mode of operation which are otherwise safe constructs in their respective languages. Granted, this isn't a buffer overflow, which, in a language that doesn't allow arbitrary writes, would be an incorrect construct and would barf at runtime, if not at compile time; but then my remark about bugs above still stands (and I'm not talking out of my ass, I've seen buggy code produced by an Ada compiler allowing this to happen), buffer overflows can be increasingly well mitigated with ASLR, and the increased complexity in the language runtime is, in and by itself, an increased attack surface. Edit: just to be clear, I do think writing software in a language like Go or Rust would do away with the most trivial security issues (like blatant buffer overflows) -- and that is, in itself, a gain. However, those are also the kind of security issues that are typically resolved within months of the first release. Most of the crap that shows up five, ten, fifteen years after the first release is in perfectly innocent-looking code, which the compiler could infer to be a mistake only if it "knew" what the programmer actually wanted to achieve.
- Dewie 12y agoFrom comments I read about that when it was written, it's not clear to me that the author actually demonstrated the same behaviour of Heartbleed. I'm not the person to be the judge of that, but for what it's worth here is the top comment from /r/rust on the topic. Then you can make up your own mind about that. https://www.reddit.com/r/rust/comments/2uii0u/heartbleed_in_rust/co8ozb1 https://www.reddit.com/r/rust/comments/2uii0u/heartbleed_in_...
- weland 12y agoThat comment sort of illustrates my point: > You should note that Rust does not allow unintialized value by design and thus it does prevent heartbleed from happening. But indeed no programming language will ever prevent logic bugs from happening. Under OpenBSD, that values would not have been uninitialized, were it not for OpenSSL's silly malloc wrapper -- a contraption of the sort that, if they really wanted, they could probably implement on top of Rust as well. What is arguably a logic mistake compromised the protection of a runtime that, just like Rust, claimed that it would not allow uninitialized values, "by design". Of course, idiomatic Rust code would not fall into that trap -- but then arguably neither would idiomatic C code. It's true that Rust also enforces some of the traits of its idioms (unlike C), but as soon as -- like the OpenSSL developers did in C, or like Unangst did in that trivial example -- you start making up your own, there's only that much the compiler can do. At the end of the day, the only thing that is 100% efficient is writing correct code. Better languages help, but it's naive to hope they'll put an end to bugs like these when they haven't put an end to many other trivial bugs that we keep on making since the days of EDSAC and Z3.
- Dewie 12y ago> Under OpenBSD, that values would not have been uninitialized, were it not for OpenSSL's silly malloc wrapper -- a contraption of the sort that, if they really wanted, they could probably implement on top of Rust as well. What is arguably a logic mistake compromised the protection of a runtime that, just like Rust, claimed that it would not allow uninitialized values, "by design". I really disagree. Rust does not allow uninitialized values by design - end of story. If a piece of Rust code let's uninitialized values bleed through, then it is broken. The semantics of Rust demands this. (OpenSSL on the other hand only broke/Overrode OpenBSD's malloc - they didn't break C.) It is news to no one that you can break - break - Rust's semantics if you use anything that demands `unsafe`. That's why anyone who uses `unsafe` and intends to wrap that `unsafe` in a safe interface has to be very careful. Complaining about Rust being unsafe - in the specific sense that the Rust devs use - by using the `unsafe` construct, is like complaining that Haskell is impure because you can use `unsafePerformIO` to `launchMissiles` from a non-IO context. > Of course, idiomatic Rust code would not fall into that trap -- but then arguably neither would idiomatic C code. It's not even a question of being idiomatic. If someone codes in safe (non-`unsafe`) Rust, then they should not fall into the trap that you describe. If they do, then someone who implemented something in an `unsafe` block messed up and broke Rust's semantics. What if that same thing happened in C? Well, then it's just another bug. --- I'd bet you'd be willing to take it to its next step, even if we assume that a language is 100% safe from X no matter what the programmer does - "what if the compiler implementation is broken?". And down the rabbit hole we go.