Skip to content(if available)orjump to list(if available)

Show HN: unsafehttp – tiny web server from scratch in C, running on an orange pi

Show HN: unsafehttp – tiny web server from scratch in C, running on an orange pi

33 comments

·August 16, 2025

Hey HN, I wanted to get more familiar with C programming, *nix socket programming and C compilation, so I wrote this "web" ""server"". It's running on a tiny SBC in my office, and there's as little as possible between you and it.

Happy for you to try and break it, hopefully with something more interesting than a DoS though :) Please let me know if you find any issues.

nneonneo

If you want to make it actually decently safe, one approach would be to make a list of all the syscalls you critically need after you have loaded all the content in memory (strace can help), then write a seccomp filter to block all the others. Since you don’t need filesystem interaction or pretty much anything except socket I/O, your syscall allowlist can be pretty short. This will ensure that even if an attacker manages to exploit a bug (like a UAF) they’ll be dropped into a sandbox with very little useful functionality.

lionkor

I've got a similar one, but with http 1.0 and partial 1.1 support, multi threaded, etc. in C

https://GitHub.com/lionkor/http

GSGBen

Noice!

SJC_Hacker

Easiest way to make it safe is

1) Run it in a container

2) Isolate it through a reverse proxy, probably nginx

mwcremer

Reminds me of Jef Poskanzer’s micro_http: https://acme.com/software/micro_httpd/

JdeBP

You are lucky that all of your sample files have dots in their names. (-:

a1o

I don't understand this, could you explain?

kjellsbells

around line 663. there's a call to strrchr, checking for a period in the filename. then immediately after that, there's a strlen that uses the results.

Which is fine, unless the first call returns NULL, because there was no period in the name, and then the program will crash.

GSGBen

Oof, thanks.

Hydraulix989

I saw the title, and this is everything I have ever hoped for.

MelvinButtsESQ

Consider it broke. You are getting hugged to death by HN. Throw Cloudlfare in front.

GSGBen

Should be back up now with a very temporary workaround in place.

p0w3n3d

I would expect GitHub page. The server seems down

201984

It had a link to the GitHub page while it was still up.

https://github.com/GSGBen/unsafehttp

joncfoo

Doesn't seem to be up =\

GSGBen

Found the issue - a use after free in send_response() if I close the session early due to an error. Was continuing to the next bit. Put a temp fix in place, will push a proper one later.

GSGBen

Still seems to have an issue, but no output before the crash. Will have to do some more debugging. Thanks for the test HN!

Source is here btw: https://github.com/GSGBen/unsafehttp/blob/main/src/main.c

Retr0id

hotfixing httpd UAFs is peak HN spirit :)

GSGBen

Whoops, should be back up now. I'll have to check logs later to see why it went down.

eyjafjallajokul

You're going to need a bigger host to support HN traffic :)

201984

What is it about HN that overwhelms small servers like this? It was a small static page so I wouldn't think it'd be that much load on the server itself, even for an OrangePi like this one.

Too many simultaneous connections for his router maybe? Or too much bandwidth for his internet connection?

contingencies

Are you near Sydney? I noted a possible link to the Central Coast. I will contribute a smaller device if you're game to host it.

PS. You may be unaware that your shortened domain name 'benren' from your whois-available real name means "stupid person" in Mandarin. Only noted because there is a company registered with the same name since 1999. On the off chance it's yours, probably not the best marketing in a global world. Just throwing it out there.

nneonneo

It could be self-deprecating! Plus, I would more readily read it as 本人 (this person/me/myself) - than as 笨人 (stupid person).

Also, Pinyin is more susceptible to accidental interpretations than most writing systems due to ambiguity and tonality. For example, “mana” can be parsed into 32 different syllable-tone combinations (man/a or ma/na times 4x4 tone combinations for each syllable), and while most aren’t meaningful, that still gives you a ton of potential words to match against.

qskousen

Almost everything is going to sound like something else in some other language, I don't know that there's much you can do about that. On the plus side, maybe the silly association will make the name stick in people's heads!

throwaway1492

Nice effort but this isn’t interesting at all. You skipped the most interesting part; parsing http. This is beejs networking tutorial with writing a file to a socket.

Harsh? Maybe, but you’re posting this to a site with some of the most talented developers on planet. Real talk, sorry.

bevhill

I swear that the only thing that draws people to this industry is the desire to escape their home village. It certainly isn't the quality of conversation with like-minded tinkerers. It's just losers like you who think a big paycheck for playing with Jira means you're the smartest boy in the world. God help us.

bevr1337

Shitty reply and this critique isn't helpful at all. You assumed the most interesting part; the thing you personally want.

Harsh? Maybe, but you're posting this to a site with some of the most jaded developers on the planet. Not sorry.

RVuRnvbM2e

Obviously you aren't one of them with an attitude like that.

tom_

Parsing HTTP is entirely unnecessary. That's the web client's job.

000ooo000

Let's see throwaway1492's code

roominator

nah this is pretty cool