A modern web app in c
2 points by thasso
2 points by thasso
This reads like slop, the linked-to website looks like slop, and the presented arguments don't make much sense.
Using C means there's no second language for your editor to half-detect, no mixed-syntax where highlighting falls apart, no plugin dance to get the two languages to cooperate.
You're still outputting HTML from within C. The author noted they aren't using a templating language, so they're presumably just using printf or something. You still have HTML embedded in another language, but doing it this way means it's not even possible for your editor to recognize that the format string contains HTML. If you're using a templating language, your editor can at least recognize it.
Instead of serving static assets the traditional way, I route all traffic from httpd to the CGI binary. Every asset is compiled into the executable and served from memory.
Why? For deployment, sure, but relinking your entire webapp every time you want to make a small tweak to a static file sounds pretty annoying.
Compromising it would require compromising libcurl... a project the entire internet watches, not a package with eleven weekly downloads and an owner who left in 2019.
Memory safety (or the lack thereof) is the much more likely way you'd get compromised, but there's no discussion of it.
As much as I hate the webdev ecosystem, it's not like the only two extremes are "basing your web-app on noname npm packages" and "C uberminimalism". For example, there's Go, which the author mentioned - which also has a stellar stdlib with plenty of eyeballs on it.
I like the section about how C has all this great tooling (valgrind, sanitizers) to deal with issues other languages don't have. That's a big benefit.
Snark aside, I'm still a C weirdo, and I do like the idea of BCHS, if you know what you're getting into. Plain CGI is also pretty fun to use, as the barrier to entry is very low - you can experiment in pretty much any language you want, without any special libraries. I had a blast writing some simple CGI apps in Lua a few years back.
I'm not seeing much difference between CGI, and a server to reverse proxy to. Both use HTTP(ish) as an interface, but an always running service can be much more efficient. A persistent database connection, no startup time... small things that add up.
Sure, there are situations where that doesn't matter, and deploying a CGI script might feel more convenient. Not sure it is in practice... but ok, it's been two decades or so I last ran CGI, but making it run as a different user as the httpd was a bit awkward at the time. I hope that improved, because with a long running service, that's trivial - and it never runs as httpd, not even for a second.
This sounds like a simple, straightforward approach to building a web app. I like how it mostly uses technologies that anyone knows (you may exchange C for a different language), and how it makes heavy use of the kernel. Specifically, many web frameworks implement multitasking capabilities which any modern kernel provides. Since you've got the kernel anyway, it seems nice to not add the extra layer of implementing a bespoke multitasking logic in the web framework. I also think the pledge and unveil features of OpenBSD sounds great; I had not been aware of them and this is another of those moments that makes me want to get into BSDs.
However, as pointed out in the article, CGI is a rather old method of building web applications. I was not around when CGI was popular, and I wonder why it fell out of fashion. I think one of the problems was speed and handling many clients at once. Maybe this is less of a problem today with faster processors, faster memory and better multitasking logic in the kernel.
I'm also curious about the security risks of rolling your own input escaping, say. I'm sure this is already clear from my post, but I am not knowledgeable about web programming, and, personally, I'd be afraid of falling victim to SQL injection and the like from failing to properly sanitize my input. I would guess that many web frameworks feature sanitization code that has been developed and tested by many experts on security concerns like these, and, hence, will protect me from many kinds of attacks.
I think CGI fell out of favor because creating a new process was thought to be too expensive (and now, even creating a thread is considered too expensive and thus we get the horrible replacement of async IO and callback hell, but I digress). The expensive process creation was exasperated by slow start up of scripting languages and with web bot activity at insane levels in recent years, it's no wonder CGI is all but ignored.
I still run my blog through CGI. It's also written in C so the start up time is quite fast (compared to Python, Ruby, or even perl). But even so, I've had to tune my web server quite a bit to not fall over to the web bot onslaught (biggest win---limiting single IP addresses to 20 concurrent connections. If you think there's no reason for any client to connect more than 20 times, you'd be surprised, and I'm still considering dropping it lower).
I'm also curious about the security risks of rolling your own input escaping, say ... I'd be afraid of falling victim to SQL injection and the like from failing to properly sanitize my input.
I don't know quite how to explain this, but it's overblown and not taken seriously enough at the same time. Using your own solution makes it a unique target and not worth the time for crackers to target you. My site gets constant probes for WordPress (or other highly common PHP frameworks) and for files that shouldn't show up (like .env files, whatever those are used for). The source code for my blog is published, and yet, no one has directly targeted it in 27 years. I also don't use SQL of any form for my blog, but if I did, I would definitely look into using prepared statements, which is something that a lot of web tutorials neglect to mention.
But on the other side, I've been surprised over the years about what garbage my CGI script receives. I pretty much immediately reject malformed input (for example, any input that contains control characters other than HT, LF, or CR gets a 400 response). My web server (Apache) at least rejects very bogus requests like "/%2e%2e/%2e%2e/%2e%2e/%2e%2e/proc/self/environ" so I don't have to bother with that, but I do wonder just how bad some servers out there were a double-encoded invalid request like "/cgi-bin/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/bin/sh" would work. If that didn't work, I wouldn't see requests like that all the time.