Hacker News new | past | comments | ask | show | jobs | submit login
Redbean Systems (redbean.systems)
224 points by todsacerdoti on June 18, 2023 | hide | past | favorite | 30 comments



Context: "I'm building a new sandboxing technology. Who here wants to hack into it?" From Justine Tunny (jart) https://twitter.com/JustineTunney/status/1670465543470710785...

"It's a SECCOMP + Landlock LSM implementation of OpenBSD pledge() and unveil(). Fully unprivileged sandboxing. No root or containers required."


A little more info for those not familiar with these terms (I was not):

1. pledge is a system call that a process can make that limits what subsequent system calls that process can execute, e.g. "I pledge to only call X, Y, Z": https://unix.stackexchange.com/questions/410056/what-is-open...

2. unveil is the analogous call to restrict filesystem paths: it limits which paths open is allowed to access: https://why-openbsd.rocks/fact/unveil/


@jart also made a writeup on porting pledge to Linux specifically in the cosmopolitan context: https://justine.lol/pledge/.


The "anet" pledge says that "this allows to accept, but not initiate socket connections"...but then still appears to allow for creating new AF_INET SOCK_DGRAM sockets and sendto, which allows for sending UDP packets without an established connection. That's probably a sandbox escape on a lot of systems, since you could sendto localhost UDP daemons.

In general the pledge syscall filters are very permissive, which makes it hard to be sure of security; Chromium libsandbox is insanely restrictive in contrast, because that's really what's needed to be confident in your attack surface, especially if you start worrying about kernel privilege escalation exploits like Chrome does. I wasn't aware of the landlock LSM before this, though, which seems pretty neat and a lot less intrusive than selinux for application specific white/blacklisting.


It needs to be able to send unix datagrams so it can blackhole your IP address in the RAW PREROUTING iptable if you DDOS the system. https://github.com/jart/cosmopolitan/blob/f10845ab9f847e4cad... You can't ban someone's IP without root. So we have two choices: (1) create a setuid binary the web server can launch that does it, or (2) run a daemon as root that listens for AF_UNIX datagrams. To do (1) I'd need to grant fork() + execve() privileges, which I view as more problematic than (2) which only needs sendto (possibly even just write). You've helped me realize that I can make the blackholed integration much tighter than the way it's currently being implemented in https://github.com/jart/cosmopolitan/blob/f10845ab9f847e4cad... so thank you!

As for surface area, I expected people to rake me over the coals for blocking io_uring. I didn't anticipate support for Google's zeal. OpenBSD is actually even more permissive than me when it comes to letting stuff through pledge("stdio"). https://github.com/openbsd/src/blob/fb5793d3d4d0fd4795586dd9... Also surface area isn't a weakness, it's a paradigm. If a weakness actually exists, then you must exploit it. So long as you tell us what you did, for the post-mortem.


I was specifically talking about AF_INET dgram sockets, not AF_UNIX; I saw that it wasn't pledged and assumed that was by design (since having that and sendto would be extremely unsafe, since you could connect to abstract unix sockets). If you want to use an inherited unix socket for the blacklisting, you should use SOCK_STREAM unix sockets instead so you can't sendto. Even allowing localhost UDP sockets isn't safe to expose to a sandbox, IMO, since Linux programs fairly often expose privileged operations over those and have no way of knowing the client is supposed to be sandboxed and rejected.


I see what you mean now. When we created the "anet" category, the main intent was to prevent redbean from making outbound HTTP connections. Allowing UDP looks like a copy and paste error. You're correct that it is a weakness. Thank you for identifying it! I'm in the process of fixing it now. How would you like to be credited?


Just chc4 is fine, otherwise @sickeningsprawl@infosec.exchange (and Twitter, though I haven't used that in several months).



I may just be confused, but couldn't you pass a pipe into the whole (server) process, instead of having it open its own sockets? (In https://github.com/jart/cosmopolitan/blob/48b2afb192ec18eca4..., I gather?)

I haven't followed cosmopolitan / Linux pledge() too closely; but I notice your SERVER_PLEDGE and CLIENT_PLEDGE include stdio, so I expect you have write(2) (and could thus handle a pipe, and maybe even a passed-in AF_UNIX socket?)

Or is making the challenge more interesting - by actually including some networking - part of the fun?


Really excited to see where this goes. Some time ago, @jart answered a message about using pledge() as WASM alternative [0], which made me believe this could be an alternative to using WASM when you just need a sandbox. I would love to be able to run arbitrary code without having to deal with containers, microVMs or having to use a language that supports WASM [2]

[0]: https://news.ycombinator.com/item?id=34647121

[2]: Even for the languages that support WASM, you usually have to deal with incompatible dependencies, properly configuring your compiler, etc.


Jeebus every time I get attention grabbed into diving into redbean I end up just getting on my knees and putting my forehead to the floor.

I would say game knows game but here barely game groks stratospheric game. I am again in awe.


It really is incredibly impressive. Coolest new project I've seen in years hands down, and I've already found several uses for it.


I will be very surprised if SECCOMP and Landlock is enough to secure Linux. Will be interesting to see the result of this anyway!


How come?


They're based on blacklisting rather than whitelisting. Security based on blacklisting means you're always going to forget to ban some critical thing. It's why trying to allow HTML but filter out `<script>` tags never works.

An example of whitelisting would be a capability based OS like Fuchsia or a custom non-HTML markup like Markdown that you then allow to use specific safe features like formatting (yeah I know about HTML in Markdown).

That said, this approach is probably the best you can do in Linux by a long way. I can definitely see use cases - e.g. all those services that have to use ffmpeg to transcode videos should definitely use something like this.


Are you saying this about SECCOMP and Landlock? Just to be clear:

- unveil(), based on the Landlock LSM, is a function which whitelists files.

- pledge(), based on SECCOMP BPF, is a function which whitelists system calls.


Yeah, though looking through the code it does actually look very solid. I didn't see that you actually whitelist `/proc/cpuinfo` before.


I'd love to understand more about what the ".verynice()" call does. Source is here: https://github.com/jart/cosmopolitan/blob/f10845ab9f847e4cad...

What are the effects of limiting a process priority?


The `nice` command alone (a.k.a. setpriority) doesn't do much. The verynice() function is similar to saying:

    #!/bin/sh
    exec ionice -c3 nice "$@"
Since it uses SCHED_IDLE i/o priority too. It's intended to ensure that no matter how much you bog down the system with i/o and cpu usage, my Emacs session and login shells will remain interactive and in control.


The wikipedia article for nice is a decent summary: https://en.wikipedia.org/wiki/Nice_(Unix)


Are high resolution timers allowed from inside the sandbox? I couldn’t tell from a quick glance.


doesn't work:

502 Bad Gateway


It appears it blocks you if you send an X-Forwarded-For header, but if you happen to be behind a proxy which sends one, you'll find you can't access it... Rather broken HTTP behaviour.


Do I get anything for breaking out of the sandbox or am I just testing someone’s side project for free?

edit: I tried anyway but the "API" just 502s, and the only thing I've been able to get it to return is the HTML with the source you see from the browser (but then later, just 502s), so I'm not sure if somebody already beat me/borked it or if there is a bug or what.

If I had to guess what happened, someone borked the HTTP server handler processes in a way that's unrecoverable


Author here. I can offer you public recognition.

You'll also enjoy the glory of being able to say you successfully hacked one of jart's services.


It's back online; it was just a log file that grew too large.


...I guess that's a kind of DoS? Almost but I guess not completely joking.


It needs a bitcoin wallet or something hiding outside the sandbox


For the joy of hacking




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: