[remark] Securing my static site server with seccomp

by Ciprian Dorin Craciun (https://volution.ro/ciprian) on 

Given a simple enough HTTP server, and by employing seccomp, one could easily achieve a quite secure(er) server, with a small enough attack surface that the potential attacker might want to look elsewhere in the stack for vulnerabilities.

// permanent-link // Lobsters // HackerNews // index // RSS

Last week I've published an article about the static site hosting hurdles in which I also pitch my own implementation, Kawipiko. Then I've submitted that article to Lobsters and HackerNews, and someone else also submitted it to Reddit.

During the discussion cycle, many (if not most?) have failed to see the great potential such a simpler server (like my own) has with regard to security (and other directions). Most participants were happy with their generic HTTP server that also serves static files.

However, how secure are these HTTP servers? (Please bear with me for a second; I'm not suggesting my own implementation is safer, on the contrary...)

Quickly searching the CVE database, we identify around 100+ reports for NGinx and around 500+ for Apache HTTP. (Granted this is only a keyword search, and at least in the case of Apache not all are related to the HTTP server; but the fact that there are tens of reports is enough.) As such, it's not unreasonable to say that neither of them are without security flaws.

But, I quickly hear some say: "yeah, these are complex pieces of software, and I only use the file serving functionality, plus I chroot my server..."

To which I can only point to CVE-2021-33909, an interesting vulnerability that allows any user (or service) to achieve root privileges by just playing with the file-system. Would that work in a chroot? It depends upon one actually employing this measure, because looking at the ArchLinux NGinx inside chroot documentation I doubt many have done so... (And the same applies to most complex web servers.)

Now getting back to my own static server, Kawipiko, because it uses an embedded CDB database for all the request serving, I was able to employ Linux's seccomp facilities (via libseccomp) to reduce the allowed syscalls to the minimum amount required to have it working.

Does it need chroot? Perhaps, but given it requires root to bootstrap it, I think it's impractical (and a source of security issues itself). However, it's not needed because once started, the server can't even look at the file-system without getting the process kill-9-ed by the Linux kernel.

Furthermore, with the flexibility afforded by seccomp I was able to gradually strengthen the filtering in multiple phases (one can only remove capabilities):

Thus, I was able to reduce the attack surface to a handful of system calls, which in the case a security vulnerability (which certainly exists in my code or one of its dependencies) is exploited, the worst an attacker can do is mess with other connections or create threads and allocate memory until it hits (configurable) resource limits. In summary, at worst one can DoS the service.

Could this have been done with NGinx or Apache? Certainly! Although perhaps not in a day of tinkering and with the same level of strictness...

Want to take this even further?

I've already experimented with deploying Kawipiko inside Firecracker (a KVM-based virtual machine developed by AWS for their own Lambda and Fargate services).

How would an attack look in this case:

Quite a challenge, right? :) Only time (and effort) can tell...