I've spent the better part of the year messing around with every HTTP server I could get my hands on. I would not recommend OpenBSD httpd.
It's supposed to be simple, and it is simple compared to Apache, but it also has way fewer eyes on it. Ultimately, a big pile of string-handling C is likely to have some problems. There was a trivial-to-exploit server-crashing segfault in httpd's FastCGI implementation that was only fixed in the last month or so. There were also recent issues related to null bytes and line feeds in headers causing strange, exploitable misinterpretations of incoming requests in relayd. Much of this is now fixed, but I wouldn't be at all surprised if there were more low-hanging fruit remaining.
If you're looking for a lightweight HTTP server written in C, I recommend Lighttpd. It's older, more widely-used, and more standards-compliant. I'm not trying to dump on OpenBSD; I run it on my primary laptop. I just wouldn't use their HTTP tools for anything mission-critical yet.
No HTTP server software can be guaranteed to be completely secure, but OpenBSD httpd is at least privsep, always runs in a chroot, and each process is pledged quite tightly, that means http/tls protocol speakers can't write to the filesystem, can't fork any processes, and can't execve(2).
Surely the most secure would have to be a server written in a memory safe language? While you can do stupid things in any language, I would jump to Caddy (Go) or a Rust based toolkit before anything written in C.
You can do stupid things with "memory safe" languages too, and nothing protects you from misconfiguration. The bsd approach of just locking it down seems to be to be at least as secure if not more to me.
> I love how having a couple of new languages make older, hardened programs insecure in an instant.
As someone who has been dealing with Unix since the early 90s, most of those old C programs were always security nightmares. There were a few exceptions: djb's stuff, dovecot and (surprisingly) Apache. But most of the other popular C servers were absolutely riddled with buffer overflows and other security problems. The Morris worm, the entire rsh family, you name it. Sendmail was awful for a long time, too.
Memory corruption errors still make up 70% of security holes in modern C and C++ code, and that's after decades of improvement. That entire set of vulnerabilities could be avoided in the 90s by using Perl 5 or Java, which were insanely popular. (PHP came with its own supply of security holes, both in the interpreter, the language design, and the awful database APIs.)
We've had popular memory-safe options for decades. All Rust brings to the table is the ability to be memory safe without needing GC (which is great). But with rare exceptions, the popular C servers were always full of holes.
There's no reason you couldn't also pledge an HTTP server written in a safe language too.
One key thing to keep in mind is that exploit mitigations are largely about limiting degrees of freedom. It's quite hard to contain an attacker who has gained code execution in a process (such as due to memory corruption) due to the massive amount of control they have. On the other hand, if you're able to prevent them from gaining such a strong foothold to begin with (such as by using safer languages which don't have such issues), you're in a much better spot because now they don't even gain any control over the process.
They have become insecure not because of new languages but because web is no longer just serving a bunch of files. You are delivering executable text mixed with untrusted input that must not improperly interfere with other users and for that you need impeccable string handling. Just reliably segfaulting every time there's a problem won't do.
Because they used to have Apache in base from 1998 to 2014 (the 5.6 release) and found it frustrating to maintain? Given the developers and what they do with the operating system, I can understand why they would consider having an HTTP server in base something within the scope of the project.
It is an open source project with both commits and discussion happening in the open (tech@ in particular), so the barrier to understanding is reasonably acceptable. At some point it was also debated to move to nginx, but in the end httpd(8) was championed as a natural offshoot from relayd(8) which was already in base.
You are indeed correct. I recalled that the nginx migration was in progress until around the time of 5.4, but did not remember that it was in base at the time. Thank you for correcting me, it was indeed in tree from 2011 to 2014.
OpenBSD maintained several local patches to nginx, such as chroot [0] by default and reallocarray fixes, but it was rejected by the upstream and too big to maintain locally.
OpenBSD httpd would probably have never existed if nginx upstream reacted differently.
For the same reason that CVS is included in base: it's used by the developers for the continued development of the project. OpenBSD.org runs on httpd(8).
It's supposed to be simple, and it is simple compared to Apache, but it also has way fewer eyes on it. Ultimately, a big pile of string-handling C is likely to have some problems. There was a trivial-to-exploit server-crashing segfault in httpd's FastCGI implementation that was only fixed in the last month or so. There were also recent issues related to null bytes and line feeds in headers causing strange, exploitable misinterpretations of incoming requests in relayd. Much of this is now fixed, but I wouldn't be at all surprised if there were more low-hanging fruit remaining.
If you're looking for a lightweight HTTP server written in C, I recommend Lighttpd. It's older, more widely-used, and more standards-compliant. I'm not trying to dump on OpenBSD; I run it on my primary laptop. I just wouldn't use their HTTP tools for anything mission-critical yet.