Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Unix in the Browser Tab (browsix.org)
314 points by ezzato on Jan 6, 2022 | hide | past | favorite | 77 comments


I'm one of the authors - its so exciting to see continued interest here!

The biggest problem with Browsix today stems from Spectre mitigations: Shared Array Buffers aren't enabled by default in browsers, and static hosting sites like GitHub Pages don't let you set the right COOP/COEP ( https://web.dev/coop-coep/ ) headers to get them enabled AFAICT.

Additionally, Browsix hasn't been updated in a while, although I still believe the idea is sound. I don't have a lot of time for Browsix these days, but it would be straightforward to update Browsix with WASI support which would free us from having to use a modified Emscripten toolchain (and instantly enable running Rust binaries under Browsix).

[edit]: for additional context: we use Shared Array Buffers to give the kernel and program a shared view of a process's address space to enable fast system calls between Web Workers and the kernel (running in the main browser thread/context). Without them performance is unacceptably slow, as things like read/write system calls (a) require several memcpys and (b) create a bunch of JS garbage. Additionally, without them there isn't a good way to "block" handling a syscall in a WebWorker (which we need to do for non-event-loop C/C++/Rust programs).


Weirdly enough, I was complaining about this exact issue this week. You can setup COOP/COEP in Github pages but you are still restricted to same domain for all resources. Which may or may not work in your case.

I've been working on a modified Emscripten runtime that treats threads as separate "programs" with their own memory, etc. Not an optimal solution at all but sometimes you need to hack your way around a problem.


How did you get COOP/COEP in Github pages? A quick search just now suggested it might be possible with a Service Worker[0], with the caveat that it may only work on _second_ load.

0 - https://dev.to/stefnotch/enabling-coop-coep-without-touching...


That was basically it, not a great solution.


If I'm reading this right, it means Shared Array Buffers can get enabled by sites that are not GitHub Pages, eg, by spinning up one's preferred cloud hosting instance (DO AWS Azure etc). If yes, then this appears in my mind as not a huge problem.


Also at least for Chrome the limitations are delayed until Chrome 103 if I read this right. See update at the top of https://developer.chrome.com/blog/enabling-shared-array-buff...

Chrome stable is at 97 currently.


Yeah, 10 years later and all these Flash killers keep not having the tooling offered by it, while the workarounds to deal with security are so bothersome that in the end everyone ends up doing mobile native apps instead.


It said I needed Firefox Nightly, so I installed it, and it still doesn't work. How do I enable Shared Array Buffers? Google is no help..


Wow I'm literally implementing this right now!!

I was stuck at parents for xmas and I picked Tannenbaum “distributed systems” and “Modern operating systems”, which gave me an idea of running a "kernel" on a browser. It was more of an academic exercise than anything else, but my intention was to have a the following:

Being able to unload and reload javascript. The initial idea was to write the website inside the website, but at the core level it requires having something akin to process isolation for javascript. It also requires the dom to be isolated.

Implementing 9p2000, and share resources across browsers. I’ve been reading about the ideas of plan 9 and i would like to implement something that allows me to connect point to point to other browsers and mount their FS into mine so we can share resources.

One of the cool results that I got was that since the dom is not directly changed (each process/worker has its own partial dom and every time that it changes it a delta is sent back to the main thread for sync) it allows javascript to be running somewhere else (another browser, back end server) and sync’ed back (much like vadaain, but more agnostic).

Most of the code was inspired by the linux kernel (which gave me a reason to go learn its internals) and is kinda nasty at some points but is written in typescript as some of you have already mentioned. Someone might find it interesting even if just for the educational purpose of it

https://github.com/intigos/possimpible


Have you looked at running Inferno in the browser? Granted the OS is heavily bit rotted though there are still people poking at it.

Join a plan 9 community. Tons of resources and people doing what you want to do. Check my profile for links and channels.


I will take a look for sure. I didn't knew they actually got inferno running on a browser. Probably some of you can help me understand better on how to implement certain parts of the OS.


##9fans on discord, matrix and irc on oftc is a great start. Though due to a recent set of trolls the discord is invite only. I think there's a link on postnix.pw



Good rewatch - pandemic or war is close enough I guess


The browser is an operating system now. Chromebooks proved that a long time ago. Every single feature of a native app is implemented in the browser now. There's already multiple different versions of "apps in browsers" (PWAs, SPAs, etc). It's just taking the industry a very long time to come to grips with the fact that they are writing dynamically-downloaded-and-interpreted apps for an operating system in an operating system in a scripting language that uses assembly to implement another virtual machine. They can't come right out and say it because it's ridiculous. But that's what it is.

We failed at making network protocols, so every protocol improvement now goes over HTTPS. We failed at making universal virtual machine-based applications, so every new app is in the browser. We failed to bridge the gaps of client-based, server-based and p2p computing, so we build all 3 into one interface. None of academic computer science seems to reflect this, and we still write most of our code by hand like it's the 1970's. We use fixed-width text-based 80-character terminals embedded in 8K OLED displays. Our telephones have as much processing power, memory and storage as our desktop computers and use batteries that last for 2 days (and are 1/10th the size), but we haven't yet standardized on one way to create new lines in a text file.

We're farmers from the 17th century working at a biotech startup.


Past discussion: https://news.ycombinator.com/item?id=13151566 (2016, 124 comments)


Interesting, I'm assuming Browsix must have been rewritten in Typescript significantly later; TS must have been much more niche in 2016 (though wikipedia tells me it may be as old as 2012)


(one of the authors here) it was written in Typescript from the start! Typescript eliminated a bunch of type confusion errors when developing the kernel, although the need to marshal data across a MessagePort means we have to do some casting and lose some safety.


Since it is written in Typescript, can parts of Browsix get compiled to Wasm instead of JS via AssemblyScript? Then at some point Browsix could run inside of any compatible wasm env and not just a browser tab?

https://www.assemblyscript.org/


That's awesome!

I wouldn't say it's less compile-time type safety assuming you assert the type of the data as soon as you obtain it. Typescript doesn't give you runtime safety anyway, so I can't really imagine any better way short of adding types to the actual runtime and making the browser assert them across MessageEvent.


Thanks for the response! I don't know what the MessagePort is, but have dealt with the pains of marshaling/unmarshaling in a browser caching library I wrote that stores app data in localStorage (which is string-only)


Thanks! Also these little ones:

Run C, C++, Go and Node.js programs as processes in browsers - https://news.ycombinator.com/item?id=13108027 - Dec 2016 (1 comment)

Browsix: Unix in the browser tab - https://news.ycombinator.com/item?id=13063232 - Nov 2016 (5 comments)


Why not "stream" an image of an actual OS (say, linux) to the browser? Has anyone pulled that off yet? (Kind of like rendering services for example, the client is just for user interaction, everything else is streamed from server where all the computation happens)


There have been browser based Remote Desktop clients for a long time (becoming usable around the time Google asked Citrix to find a way to “run” Windows apps on Chrome OS). I’m not quite sure if that’s what you mean?

Guacamole is a good open source one.


I have a demo of this here [0] (all the software is in /opt/appfs/rkeene.org). It's using GoTTY [1] for presenting a Linux pty and terminal to your browser, and a simple sandbox.

[0] https://rkeene.dev/js-repl/?arg=bash

[1] https://github.com/yudai/gotty


https://guacamole.apache.org/

If I understood you correctly.


Xpra (see https://github.com/Xpra-org/xpra-html5) is very similar to Guacomole, except the backend Xpra server is written in Python (and Cython), whereas Guacomole's server is written in Java and C. Xpra native frontends, but also an html5 frontend that you can embed in web applications. For example, CoCalc provides a modified version of that html5 frontend to serve graphical X11 apps: https://cocalc.com/features/x11


Thanks! Checking it out


Both AWS and Azure provides this as a service with either Windows or Linux.

There's also a relatively new service called Mighty App, which streams just a browser with the idea that you can manage 100's of tabs with all the browser processing being done on the remote server.


Yes, I'm aware of this one, but it is using a cross-compiled TinyEMU, so it's a level of emulation away from what this is doing. https://bellard.org/jslinux/

[edit] Oh, I guess this isn't really what you were looking for. Whoops!


I really want to get this to work well, but haven't been able to. I have a small use case of customizing the image it presents and letting users be able to navigate/change/fix things on it. I've tried using containers and even VMs, but those are too heavy for what I need to do and I don't want to deal with snapshots to revert the image. Basically reloading the web page should do it.

Wish I could get jslinux to work for what I want with this!


https://copy.sh/v86/ is more modern but similar in spirit to jslinux. The archlinux demo at https://copy.sh/v86/ is particularly impressive.


Thanks for that! I will give that one a try.


There’s web vnc clients, so technically this shouldn’t be much problem. It’s much more a wrap it all together kind of thing.

I really prefer it being it local though.


gaikai was doing this in the early 2010s for zero-day game release demos. java in the browser, streaming video and audio from servers, relaying back game input events.


Before Gaikai was OnLive[1] which was a full platform with a game store and libraries and the ability to seamlessly and instantly spectate others' games. It worked fairly well if you had a great Internet connection. Of course nowadays Stadia does the same thing at presumably much lower latencies and higher quality.

[1] https://en.wikipedia.org/wiki/OnLive

EDIT: Technically Gaikai was founded a year before OnLive, but at the time OnLive was more accessible as Gaikai remained in a limited release up until Sony bought them to use for Playstation Now


Already done, X Windows, RDP, VNC,....


What is the use case this is solving?


(author here) Without something like Browsix you have to make a choice: find a JavaScript library or implement the functionality you want to run client side, or run existing Unix programs and libraries (that expect a filesystem, to be able to fork children, etc) server side. If you run software server side, now you have to worry about containerizing/security as well as horizontal scaling.

Browsix addresses this by letting you run Unix programs directly in the browser, taking advantage of the significant compute power on peoples laptops (and even phones nowadays!), eliminating a whole class of security issues (software explicitly will only have access to the current users data in the browser tab) and scaling concerns.


Why do we need a reason to do interesting, weird things?


Reading the explanation from the author above your comment makes it not sound weird at all.


I have a big problem with this: where is the link to try it? I just don't understand when I read something about an "x that works in the browser" and there is no demo link.



I'd like to see Node.js running on it. I know StackBlitz has "WebContainers" but I'm looking for something open source.


Er, why? You want to run a JS implementation on top of a JS implementation?

(I'm not super familiar with this ecosystem so I'm probably missing something obvious like libraries or something)


The ability to run code targetted to Node.js along with its own standard library within the browser, at least in a mostly accurate way. Writing Javascript on the web is fairly different than writing Javascript for Node.js, mainly (1) the APIs that are available to you and (2) the capabilities that are available to you. It's useful for developer tooling (Stackblitz does just this).

So it's not about running a JS implementation on top of a JS implementation per se, but being able to run JS code that uses things like CommonJS require(), Node builtin modules, etc


Also, StackBlitz reuses as much as possible the existing V8 runtime from the browser, rather than really running another node.js via WASM.


So emscripten is still the compiler, but this is an OS which can be targeted by emscripten? Am I understanding it right?


I don't think it's as a clean a separation as that. Emscripten supplies many things. Some libc-like, some os-like, including a filesystem api. This adds things like pipes, concurrent processes, signals and sockets, and makes the emscripten filesystem api shared across "processes" (web workers). It's borrowing from other code, too, like BrowserFS.


That's pretty right, with the addition that other things can target Browsix (like the gopherjs toolchain). Emscripten provides default implementations of a bunch of syscalls (and even a way to embed a file system), and we override those to instead do actual syscalls to a shared kernel (running in JS)


Based on how we see so many 'OS in the Browser' links here on HN, am I right to be underwhelmed by this one?


AFAICT, Browsix is meant to work more like Wine than like jslinux. The goal is to allow devs to deploy native executables to the web browser more seamlessly because it provides ways for standard javascript to interact with the program. JSLinux is a full system emulator and thus has more overhead and doesn't have a method to cleanly interact with the world outside of the emulator.

The latex editor example is the one that best demonstrates the concept. It is a standard JS frontend that is invoking an unmodified pdflatex for rendering. In all other 'OS in the Browser' projects I'm aware of it would have to be a desktop application that just happens to be getting rendered in the browser. With plain emscripten or webassembly you would need to modify pdflatex to support a method to accept jobs and return results while not relying on any OS level features.


This is different. What you usually see is mock-ups of graphical shells. This is a kernel.


Maybe I misunderstand, but didn't JSLinux[1][2] do system emulation running a proper kernel basically since 2012?

1: http://jslinux.org/

2: https://bellard.org/jslinux/tech.html


For sure, it's amazing to get a full kernel running; there's so much one could do. But an emulator and a full kernel is going to have a sizable footprint, be a significant amount to download, and performance is going to be mediocre. Yes there's a linux kernel running, but it's inside a virtualization layer; if you want to integrate & have the page interact with the kernel, you'd need to start hacking some pretty wild channels to punch through that virtualization layer.

Writing an operating system that directly targets the browser, that offers the expected/standard system calls ought to be smaller and faster, and more interestingly, it can potentially integrate with the rest of the page in interesting fashions, easily.


I did underappreciate this, thank you!


It's about building the UNIX abstractions using web primitives, like WebWorkers and transportable WHATWG Streams. Very cool stuff. I've seen a lot of these here and this one is not underwhelming to me at least- if anything it is inspiring for how one might architect an advanced resource intensive client-side web app.


As an alternative to maintaining an Emscripten fork, Browsix could be added as a new target to Zig.


I think there is a straightforward path to having Browsix generically support the WebAssembly WASI system interface[0] -- any toolchain that emitted binaries targeting that would then work in Browsix without e.g. Emscripting needing to know anything about Browsix.

0 - https://wasi.dev


Hmmm cool but cd is not implemented? Still awesome especially for an undergrad proj


Yeah the shell leaves something to be desired (see the backspace bug mentioned in /README). Makes me want to waste a weekend writing a proper shell for it :-D but I have too many side projects


This is amazing.

I’m imagining all the ways I could use this for offensive security tools.

If I had a way to import a js library that enabled running web servers, invoking OS commands, or running a reverse http proxy I’d be able to do so much damage to any target client.


It doesn't let you escape the browser sandbox.

> Sockets include support for TCP socket servers and clients, making it possible to run applications like databases and HTTP servers *together with their clients in the browser*.

Emphasis is mine. You need to run the server and the client within Browsix. Furthermore the "OS commands" are commands within the Browsix environment.


Ah thanks for pointing that out.

But nonetheless, this is useful technology for a malicious actor.

For example, a functioning http server would enable an http proxy that could intercept/modify requests made from the client no?

Now I can add headers to requests made by an html form submit. This might allow for more potent csrf attacks, or circumvention of controls like the HttpOnly cookie flag.

Can I use a victims browser as a c2 server now? I bet with some brainstorming we could come up with some creative offensive capabilities using this technology.


No, you can't start a web server within Browsix that can accept connections from outside Browsix.

Just like you can't do that in regular JavaScript in the browser.


I see. So an form submit POST request could not actually be sent to Browsix?


That's right, unless the form was running in Browsix, or I suppose at least the same browsing context (ie same origin on the same browser instance on the same computing device) since you could emulate submission across multiple tabs of the same website using something like the BroadcastChannel API[1]

[1] https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_C...

EDIT: To be clear, this would require effort (TM)- the form would need to have a Javascript onsubmit handler and use preventDefault to stop the browser itself from handling it in order to facilitate that


Neat! Thanks for working on this project and answering my questions.

Perhaps I need to look into it more but what you’re describing isn’t exactly far fetched.

With a csrf attack the victim has navigated to a malicious web app where the cross origin request does originate from the same browser instance where my hypothetical browsix http proxy is running.

Since I control the malicious app, I don’t see why I wouldn’t be able to have an onsubmit handler that proxies requests into browsix.

I’m not saying there’s guaranteed offensive use cases here…it’s just my intuition telling me it’s worth looking into for myself.

My comments aren’t intended as a criticism of your library. If I got a client to navigate to a web app I control there’s plenty of js-enabled damage to be caused without browsix.


Nah I don't work on this project, but I did stay at a Holiday Inn Express last night.


Does it handle copy paste?


Test


2 questions:

* why?

* security?


From the introduction "Compiling programs into JavaScript, asm.js, or WebAssembly with tools like Emscripten or GopherJS isn't enough to successfully run many programs client-side" it seems like the intent is to be able to port "Unmodified C, C++, Go, and Node.js programs" to the browser.

Big use case for this I would imagine is games


Security? As secure as any javascript programmed site is.

Why? Why not? (Just don't put it in production lol)


I think the parent poster thinks this is somehow breaking out of the JS sandbox (which it's not).

> (Just don't put it in production lol)

Why not? If you were to use multiple "processes" using Browsix in your app, it actually may be _more_ secure as Web Workers do not share state with each other and the main thread. (EDIT: Although for me I would at best take inspiration from this rather than use it for a real app)


It's because the code isn't mature or seems to be maintained anymore (last commit is april of 2019, pile of issues built up, etc.)

So it wouldn't be wise to rely on that from a business standpoint.


Oh sure. Was just wondering if there was something technical you'd seen. In any case I think this is just a student project right?




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

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

Search: