5 ms·
Security is not a feature of the language or tool. Neither Rust nor C++ are fully secured even though the former could find more memory safety problems at compi
by kzhukov 6y ago
Security is not a feature of the language or tool. Neither Rust nor C++ are fully secured even though the former could find more memory safety problems at compile time (but not all of them).
Security is the process. It contains continuous risk assessment, penetration testing, fuzzing and using various other tools throughout the product development to eliminate attack vectors. Only then you could build a secured product. Just rewriting everything in Rust won't make it.
- thesuperbigfrog 6y ago>> Security is the process. Yes, but do the programming languages / tools we choose make the security process easier? There is no perfect solution, but some programming languages / tools are better than others for preventing unexpected behavior that can lead to insecure programs.
- jjav 6y agoVery concisely and correctly put, agreed. I sometimes work on the infosec side of the house. It's easy to point at vulnerabilities due to endless memory access problems in C code and fixate on that. And it's true, so it feels satisfying. Just rewrite everything in not-C and this is fixed! And that's true as well. But remeber here the word "this" refers to the memory access bugs. It doesn't refer to vulnerabilities in that sentence. Plenty of systems without a single line of C/C++ code and we have no shortage of ways to break in anyway. So in one sense, everything changed. But wearing the black hat, nothing really changed since I compromised the system anyway. A new language without all the engineering process parent post describes, won't magically get there. For an existing system "just rewrite everything" will guarantee way more bugs for years to come simply because the old system has been battle-tested and reinforced for years. In the long haul the rewrite will converge to a better state but that haul is long (and assumes budget will remain in place long enough, which might not happen so you end up with a half-baked rewrite). For new systems starting from scratch that may in any way ever be run in a security relevant context, sure, starting with not-C is a good idea today. Unfortunately Rust seems to be the only alternative for use cases where C was actually needed (if it could be written in Java or Go or Python or ... then it didn't really need to be in C in the first place). And sadly rust is fairly user-hostile language so my guess is plenty of new projects will start with C for a long time due to lack of friendly alternatives. And tooling.
- MereInterest 6y ago> And sadly rust is fairly user-hostile language Could you elaborate on that? I started using Rust at the end of last year, and have found it to be one of the most user-friendly languages I've learned. There is clear documentation that is easy to generate with the standard toolchain, along with a very good language guide. The compiler error messages are an absolute joy as somebody coming from C++. Pointing out exactly where the borrow checker found errors, or exactly what the type signature should be for a trait, is really useful.
- rob74 6y agoWell, yes, coming from C++, Rust must seem like a breath of fresh air. Coming from almost any other language however, I can understand that it feels a little bit intimidating (and getting more so with every exotic feature added - "const generics" anyone?), no matter how friendly they try to make the documentation and the error messages...
- MereInterest 6y agoI can see that a bit. I suppose for me, the biggest questions are (1) is there a way to unambiguously express my intent and (2) is there exactly one way to do so? I'm fine with more features so long as they match some specific problem that people have that isn't already solved in another way. For example, in the case of const generics, I've used the equivalent in C++ to make a class for a geometric vector in N dimensions. The size varies depending on the number of elements, but is known and can be checked at compile time. The existence of const generics is very closely matched to this particular use case.
- dllthomas 6y agoI don't think "there is exactly one way to do it" is actually a good guiding principle. Forcing it down to an overly simplistic setting, if I need to add 5 to a number I can increment 5 times, or add 2 and then 3, or just add 5. Which of those options should we remove? Perhaps we mean, instead, that there should be one best way, but (sliding into metaphor, I hope) what about when we have a language without 5 and we are considering adding it? Is the use case already handled by 2+3? How are we to decide?
- StillBored 6y agoThis is true, and I suspect that while Rust has this aura of compiler enforced memory safety, its quite possible that the piles of c/c++ tools which _can_ be enabled and run against C code bases make it generally just as secure in practice when those tools are actually enabled. The simple classes of bugs enforced by rust, are also caught fairly quickly with any kind of memory sanitizer (valgrind?), combined with static analysis tools (coverty?), and automated code quality standards (misra). Run a CI/Code coverage monitor while looking for for these kinds of errors, and I would bet the results are actually better than plain rust due to the maturity of some of these tools.
- c-cube 6y agoThat's plain wrong. If static analysis was as reliable as rust, why would all these C codebases still be full of buffer overflows and memory errors? The borrow checker is, in effect, a static analysis tool... that requires a lot of annotations from the programmer, and blocks compilation otherwise. The equivalent for C would be to annotate all your functions in some formal language and then run, say, frama-C. About valgrind or sanitizers: they're runtime, so just like tests they can only show the presence of errors, not their absence. Like dynamic type checking.
- Ar-Curunir 6y agoThe borrow checker is a static analysis tool that is 100% sound, unlike the tools for C/C++
- flukus 6y agoThe borrow checker is 150% sound, it complains about errors but also complains about a lot of things that could have been perfectly fine in reality. There are plenty of times when multiple mutable references would be perfectly safe for instance. Valgrind might not catch 100% of errors, but at least what it catches are actual errors I care about.
- smallnamespace 6y agoThat's an interesting (and correct!) objection — in stats terms, it's the choice between having false positives (your type checker rejects some valid programs) vs. false negatives (Valgrind didn't catch these cases). If you're writing safety-critical software though, being forced to restructure your code to satisfy the type checker (which, in this case, is kind of a simple proof assistant) seems like a sane tradeoff.
- elihu 6y agoSurely part of the security process should be to identify parts of any system that are routinely causing security problems and replace those parts by better ones (as they become available) in any context where security is important (which seems to be rapidly converging on "almost all contexts that normal people using computers encounter in day-to-day life"). Rewriting C or C++ applications in Rust won't fix all security problems. But it would be forward progress. It's just like wearing seat belts won't stop people from being injured in car crashes. You could say that "safety isn't a product but a process," which is fine, but if your safety testing process finds that wearing seatbelts reduces injuries substantially it seems pretty obvious that using a seatbelt product is the way forward. At least until someone invents a better replacement for seat belts, or supplements them with other features like airbags, automatic braking systems, self-driving, etc...
- lmm 6y agoThis sounds wise, but I would bet that for the same amount of effort, "just rewriting everything in Rust" will give a better return than the kind of process you're advocating.
- Quekid5 6y agoWe can pretty much also conclude (given data on CVEs, etc.) that -- in practice -- programmers either aren't following that process or it doesn't have enough of an impact to actually get rid of memory errors of the kind Rust protects completely against. (Caveat: Obviously 'unsafe' is relevant to this discussion, but at least you only have very small areas of code you need to check extra carefully.)
- Someone 6y ago“Security is not a feature of the language or tool […] Security is the process” True, but if the process discovers that a lot of lives are lost because of the use of unsafe tools, it changes the tools to add safety features (https://en.wikipedia.org/wiki/Chainsaw_safety_features https://en.wikipedia.org/wiki/Chainsaw_safety_features), or ditches them altogether (https://en.wikipedia.org/wiki/Hazard_substitution#Processes_and_equipment https://en.wikipedia.org/wiki/Hazard_substitution#Processes_...) So, yes “rewrite in rust” isn’t the full answer, but that does not imply “don’t write it in C” isn’t part of the answer.