Rethinking OpenBSD Security
flak.tedunangst.com
flak.tedunangst.com
And that's in OpenBSD which has had the honest effort and passion of scary geeks with no sense of proportion for how many years?
Compare that to the security posture inherent in projects that install with
sudo bash <(curl -sL someurl.wtf/thatredirectsanyway )
"Secure" computing today is just not going to happen. Not saying its a bad goal, or a waste of time; just that its a metaphysical pursuit of perfection doomed to beautiful failure.The software in question was https://github.com/txthinking/nami
Dang disappoints me again.
Disk read errors may prevent running the entire script or the script may run out of memory, disk space, or other resource limit such as the maximum number of open files or the maximum length of a file path.
Oh wait... There are actually tons of such projects. Why did they not take off? (I'm trying hard not to sound cynical because I don't really know that there is absolutely no way that they could, but also I do feel cynical)
Secure computing requires a relatively low time preference to be economical. Or, more precisely, marginal demand for secure computing increases with a marginal decrease in time preference. Most companies have (artificially inflated) high time preferences, so it's not economical for them to adopt what we consider secure computing.
This is, I believe, to the net detriment of human society as a whole (at least, at my personal time preference).
I'm not going to get too much into why time preferences are so (artificially) high on here, but I encourage people to look into it themselves. A lot of it has to do with government economic intervention, especially around monetary policy.
Don't single it out. Fiscal policy is as much guilty as monetary one. Even civil and criminal legislation help here.
We are doing exactly that, in what concerns me, I switched away into managed languages back in 2006, already replaced a couple of C and C++ based solutions by .NET and Java ones. On my line of work C and C++ only have a place as means to writing bindings to OS libraries written in those languages. what can be replaced by secure languages, gets replaced.
In what concerns big companies, C is persona non-grata on Windows, Azure IoT makes use of .NET and Rust, Microsoft is a big pusher for C++ static analysers, drives Checked C research, did two safe OS whose learnings got added back to .NET (async/await, Span<>, .NET Native), UWP sandboxing is merged with Win32, with upcoming Windows 10X having everything sandboxed in little pico processes.
Google allows very little C and C++ code on its OSes, ChromeOS sandboxes everything, Android has probably the Linux kernel fork with most security knobs turned on, NDK has very little API surface, and Android 11 now requires hardware memory tagging for C and C++ code.
Even though I don't think it is going far, Google is working on eventually use Swift for Tensorflow further developments. It remains to be seen how much C++ are they willing to replace by Swift.
Apple is now since one year driving drivers outside the kernel, with the exception of DriverKit, everything else can make use of Swift as well. Very few modern macOS APIs are C or Objective-C based. Since iPhone X, iOS makes use of hardware pointer validation.
Apple is also hiring Rust developers to replace C based infrastrutured on their backend.
GenodeOS is written in C++, and has since one year started to migrate security critical parts to Ada/SPARK.
Speaking of which, NVidia, a C++ powerhouse, is now using Ada/SPARK for security critical firmware.
We, security conscious people will get there, slowly, might not be on our lifetimes, but society will be there eventually.
Then again, progress only happens one person at a time.
There are lots and lots of software that is both well designed and popular. SQLite is a great example. Postfix and OpenSSH too.
The meta tables declaring all table structures are changeable via SELECT and CREATE VIEW statements, the fulltext search engine still allows follows arbitrary user pointers by default. Well-designed is different.
The problem is not the language, the problem is in the design.
In my experience secure computing is a lot more inconvenient. I don't mean Haskell is inconvenient (it is). I mean like, it's way more inconvenient to write in C# or Java than it is to write in plain C if you want to get real work done.
Speaking of history,
> if a builder build a house for some one, and does not construct it properly, and the house which he built fall in and kill its owner, then that builder shall be put to death.
-- Code of Hammurabi, Babylon.
Naturally, we shouldn't go to such extremes.
OpenSMTPD is a relative newcomer -
Sendmail: 1983
Exim: 1995
Postfix: 1998
OpenSMTPD: 2008 (2013 as active MTA in OpenBSD)
I see how desktops (laptops) are more or less screwed because of the need to run ad-hoc things.
But servers, which are much more controlled ad limited environments, could be more secure. A lot of orgs follow rather sane software security policies; if the software itself were less vulnerable, it would help.
For a lot of end users that would make a significant difference, because they run most of their critical software in the browser anyway.
A single developer can hold much or all of the state and important security considerations in their head. A small team can communicate well and can hold to a single style, and members of a small team can ask each other things easily. Single developers or small teams can write secure code in unsafe languages.
The problem is that this doesn't scale. Add a large number of developers and it becomes increasingly difficult to police security in an unsafe language. Safe languages, unit tests, and fuzzing help a lot more here by making large classes of errors difficult or impossible to manifest or catching them automatically.
Linux is a bit special here: it has a lot of developers but a small number who are responsible for approving things, and it's so massively important and popular that it has a lot of eyeballs on it and gets a lot of automated testing. Security issues still creep in though.
https://kernsec.org/wiki/index.php/Kernel_Self_Protection_Pr...
One of their first activities was to clean the kernel from all usage of C's VLA.
However, a number of projects from OpenBSD have been widely adopted and are successful in their own right, for example:
C:\>ssh -V
OpenSSH_for_Windows_7.6p1, LibreSSL 2.6.4
The two projects above, OpenSSH and LibreSSL, have been even more strongly adopted by Apple, as I understand it. OpenSSH is adopted by just about everybody.Google Android's "bionic" C library is also based on OpenBSD, and I would imagine that the coding concerns for libc will trickle down.
OpenBSD is not the sum of its parts, as so much of it is used in other environments.
[1]: https://en.wikipedia.org/wiki/Bionic_(software)#Components
exec("/bin/sh", "-c", "...");
And its friends? It feels like it does way more harm than it does good.Particularly, the exec() bug here is one of misunderstanding the security guarantees of interfaces; particularly, that there are none. Not validating inputs is the single most universally known security practice, and yet it wasn't done here. On top of that, not using typed objects further increases potential for attacks. This was just shit security design. exec() had about as much to do with the bug as your brakes have to do with you locking up your wheels when traveling too fast in rain/snow/ice. (that you should have been going slower, not that the brakes are defective)
Taking a step back, Unix's programming model is heavily influenced by the design requirements of interactive bourne shell. It's hard to outlaw shell-like things without breaking shells.
watch bash -c “ps | grep argname”
and similar.
And because there are genuine uses for it. I use it in service ./run programs, for example, where simple tooling is not enough and I want shell script things like variable expansions and conditional operators.
The first reason is of particular note because it is two good practices to get used to: employing "--" as the norm; and not passing user credentials around in either environment variables or command-line arguments. (Bernstein checkpassword receives the user credentials as NUL-terminated strings over a pipe.)
This invites the sincere, honest technical inquiry as to why OpenBSD doesn't have an SELinux-style Mandatory Access Control (MAC) facility, but is OK with the traditional Discretionary Access Control (DAC).
People seem to have been experimenting with applying these restrictions from the outside, but it's generally hard to guess how a large program from ports will behave.
The rub being that SELinux is mandatory, so if you don't provide some kind of profile, it simply won't run.
They also do so at runtime, which means they can restrict themselves much more than a generic configuration can.
Once you’ve stated, for example, “this execution of this tool will only read standard input and write file F”, nothing you do, whether it is sloppy programming or the use of third party libraries with bugs, can change that.
Pretty idiotic aim if you're writing it in C.
No unit tests.
There is so much code that parses text input and yet I can’t find a single test that actually shows that the code works and that it properly deals with malicious input.
How do OpenBSD developers test? How do they make sure changes do not regress things.
Why is unit testing just not a thing? (Same for many other C based projects)
But very often when you spend time to write unit tests you discover limitations and bugs in your code while you come up with test scenarios.
The only thing that the FTP bug needed was a "test_redirect_responses()" test. The SMTPd bug was all about parsing user input. Ideal candidate for unit testing and probably even some fuzzing.
The writers who added handling of HTTP would only have added it if they had realized the HTTP library they used could do a redirect. Even if they did, they would have to have thought about redirecting to some specially crafted URL.
ld.so for example is pretty well exercised (https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/regress/libexe...)
Nothing. It is just not a common practice it seems.
Now I don't think unit tests are a silver bullet. But having just code and zero tests is definitely a huge red flag for me.
Please change your page design so that the content is centered horizontally. Otherwise we have to swivel ourselves toward the left side of the screen to read the article.
Sincerely, My Eyes