6 ms·
>> I cannot consistently write safe C/C++ code. I think it's going to depend on your attack surface. Could I sit down and write a web-facing server from scratc
by Nursie 6y ago
>> I cannot consistently write safe C/C++ code.
I think it's going to depend on your attack surface. Could I sit down and write a web-facing server from scratch and have a reasonable expectation of safety? Probably not.
Can I write a piece of firmware for an embedded device with no internet access and a very limited serial protocol, and have a reasonable expectation of that being 'safe'? That seems more likely, particularly if I follow good practice and use available analysis tools where possible.
I think the biggest problem with these languages is that when something goes wrong (as it so often does), the keys to the kingdom are up for grabs as the whole of everything can suddenly be manipulated, to read out arbitrary memory (e.g. heartbleed)
- mumblemumble 6y agoIt almost goes both ways. Yes, being on an embedded device with no Internet access reduces your external attack surface. But it also limits your ability to use lots of newer language features designed to improve safety, because those features often cost CPU cycles or memory. My (completely uninformed) guess is that most of any net benefit from being on an embedded system comes from the simple fact that "embedded" implies "constrained", which implies "less code," which, in turn, implies "fewer opportunities to create bugs in the first place."
- Nursie 6y agoIt certainly plays into it - fewer moving parts means less opportunity for things going wrong.
- MarcusE1W 6y agoI don’t think that you are limited regarding newer language features when you develop for embedded devices or limited in the use of more safety focused languages. E.g. Ada, despite being in the older age for computer languages was specifically designed with embedded programming and safety features in mind and does this quite good. It also supports OOP if you want that sort of thing and more crucially has pretty good concurrency support build into the language while still being reasonably safe. With SPARK/Ada you even get a language variant that can be formally proven. To name some more modern use cases.
- mumblemumble 6y agoBut this wasn't talking about using other languages with more of a safety focus. It was talking about using newer features of C++ that are meant to support safer programming. Most of these come in the form of abstractions with non-zero cost.
- AnimalMuppet 6y agoOK, but... I see three options. 1) Use the non-zero-cost abstraction to do X safely. 2) Write the equivalent abstraction to do X safely, which will cost you the time to write and will probably be buggier than C++'s version. 3) Don't do X. The fourth option - do X but in an unsafe way - should not be on the table for a professional developer. Now, C++'s philosophy is that you can't write your own thing to do X more efficiently than C++'s builtin version. They may not perfectly achieve that in all cases, but they come fairly close. That plus bugs means that I won't reach for option 2 unless I have really good reason to think I can do better. That leaves using the builtins to do X safely, or not doing X. At least that's how it looks to me...
- ActorNightly 6y ago>Could I sit down and write a web-facing server from scratch and have a reasonable expectation of safety? Probably not. This is very suprising to me that people think this. I am not a fantastic programmer, but I don't see writing safe code diffucly at all, you just have to understand the basics how attacks work, and follow some basic rules when writing code. In order for a piece of software to be exploitable, you need to have an input channel that is not isolated from the functionality- something like taking the parameters in the url and passing it directly to a shell is a massive failure in isolation. As long as you do proper input sanitation, where the input must have certain format, and certain length for each part, and certain formatting for each part, the attack surface goes down to an absolute minimum. For example, for all the C/C++ code that I have seen that deals with web, only once I remember seeing a check on characters in the passed data being in the set of [0x10, 0x13, 0x20-0x7e], which should be the first check performed on any HTTP data passed to it, even before you start invalidating HTTP characters. As far as memory safety goes, never rely on null terminated strings, allways copy the exact amount of data to a statically defined max, and make the buffer that holds data have the length max+1 with an extra byte that is allways set to null for every copy into the buffer. For malloc/free, design your code so that malloc and free are in the same function at the beggining and end, and allways run memcheck and valgrind before deploying to production. Between all the other mechanisms in place, like non executable stack/heap, stack canaries, ASLR, and the tools like memcheck and valgrind, the possibility of you making an exploitable software is as low as coding it in a "proven safe" language (if such a thing exists) and messing up some parser input that can lead to unexpected behavior. And of course, there is still the possibility of using a library that has an exploit, or coding in an exploit in higher level logic, but that is a danger for any language. I would bet that if taking an exploitation class for CS degrees was a hard requirement, where people understood the concept of stack, heap, and how the different types of exploits work, the outlook on this would change. I also wonder if teaching people C++ instead of C, and relying on built in memory management mechanisms to build software instead of making them manually write all the allocations by hand has an effect of a less understanding on what goes on under the hood.
- Nursie 6y ago> In order for a piece of software to be exploitable, you need to have an input channel that is not isolated from the functionality And prove that your input validation is correct for every possible value, and that under stress the system doesn't start doing something weird, and there are no possible integer overflows that might cause something funny to happen and ... > For example, for all the C/C++ code that I have seen that deals with web, only once I remember seeing a check on characters in the passed data being in the set of [0x10, 0x13, 0x20-0x7e], which should be the first check performed on any HTTP data passed to it Unless it's unicode of course, which it really should be these days if we're talking about the web, and when really you want a unicode parsing library to validate, and then you're reliant on that having no exploits, and anything of any significant complexity usually turns out to have some somewhere. > "Between all the other mechanisms in place, like non executable stack/heap, stack canaries, ASLR, and the tools like memcheck and valgrind, the possibility of you making an exploitable software is as low as coding it in a "proven safe" language" This is provably false though, and that's part of the point of the article, even well looked-after software written by experienced people with an eye on security suffers from problems, and with unsafe languages there are classes of attack that are just not possible with safer languages. These keep on happening regardless of the apparent skill level of the practitioner. The author has been doing it for 25 years and doesn't think they could do it reliably. I was a C programmer for 15 and I agree, past a certain level of complexity it looks like there just are going to be errors of this sort somewhere in your code. Sure, programs written in 'safe' languages are not bug-free or exploit-free, but for public-facing, networked code they do seem to be better as they eliminate a huge number of damaging attack types straight off.