IMO, the approach taken by Chrome and other browsers is over restrictive, basically killing off the file:// protocol. Already now it's impossible to load wasm files in the file:// protocol in Chrome, and I think this also had implications on using wasm in electon.
Ultimately, file:// is a great, cloud free method of having web pages and applications and it should stay that way instead of forcing everything to be networked and reliant on third party computers or domain names.
There are so many reports, documents, etc that live as non-networked html files. E.g. rust documentation (cargo doc --open) is generated as html files on-disk and then just displayed without the need for a webserver. Starting a localhost webserver is in fact less secure than file because now every user on the computer has access instead of just the users with read-access to the files. This has thankfully been fixed in Chrome OS though.
Responsive web apps are not the solution as they still need "seeding" via the network. Maybe some kind of standardized format where you have a glorified zip file with some metadata and when you double click it, it opens in the web browser which starts a web server in the background that runs a specially designated js in that zip file and which can accept usual fetch requests and has read access to the entire zip file. The browser's "UI" would then communicate with the server via well-known protocols.
Learning web programming is amazing, since you can just start writing a .html file and open it in a browser. There is no need to learn how go set up a local http server. Chrome truly is killing that experience; you can't even load javascript modules without http involved now outside of Firefox.
I really hope Mozilla doesn't "fix" this "vulnerability" by destroying the experience of people learning web programming like Google did.
I started learning HTML at age eight. No one in my family had experience with programming or using a terminal (there was an HTML book on discount at the book store). I was able to get started because it was dead simple, and only used tools I was already familiar with: the web browser, Notepad, and regular files.
This. It's not only "open Notepad and save this text file, then open it in the browser".
Leave the complexity of learning what Python is, the 2 vs 3 issue, 32/64 bit versions, appending locations to your path, CLI, etc., for when the user is ready to start with dynamic web pages.
When I was about 13 I wanted to learn C++. I bought a book, installed the software from the CD and tried compiling the first example. It failed with a cryptic error about a file not being found. I gave up on programming for a number of years.
The book had failed to mention that I need to include the compiler in my PATH.
So what was I supposed to do with no expert on hand and no Internet? I went back to the bookshop and asked there. They didn't know either, so I returned the book.
I returned to programming when I learned about Quickbasic. That just worked and had an extensive help system that was suitable for self study.
I don't think that's very fair. Some people are extremely gifted mathematicians with incredible talent for algorithmic thinking, yet can be totally shut down by build configuration bullshit. It's a huge pain point in C-land.
Please note, python is not available out of the box on Windows machines as in macOS, most of Linux distros.
Personally, as a person who used python in my programming job, I don't remember when for last time or even I have ever typed mentioned by you command to start a local server.
As much as I prefer the file protocol, an other option would be:
$ busybox httpd -p 8080 -f
-p for port (also possible to bind to specific IP: -p 127.0.0.1:8080), -f for foreground, also optional -h for served directory (default is .).
But the difference between doing almost nothing, a double click once and then it stays there even between restarts, to giving a specific command in a terminal is monstrously huge.
And now you have:
php -S localhost:3000 -t ./
on mac
python -m http.server
on some versions of linux,
python -m SimpleHttpServer 8000
on others, and any of the above on windows.
How is that easier than putting file://path/to/foo.html into my browser window, as someone getting started in web development?
Why should I install Python, if I want to do a bit of JavaScript? That's not really the point. Of course it's not complicated to setup XAMPP, LAMPP or whatever.
If you run Linux, you won't have to install Python - it will be there by default in almost every distribution. It hink this is why GP chose this example - there's a multitude of other options to instantly start a web server.
Most people are running Windows. That means most people trying to learn how to program are running Windows. I wouldn't want to figure out how to set up a web server on Windows myself, and absolutely wouldn't expect someone learning to program on their own to be able to art it up without getting frustrated.
Even for people on Mac and Linux, having to start by learning the terminal is a pretty big and unnecessary obstacle to just getting to writing some JavaScript. Sure, you and I think it's easy, but it's a completely different paradigm which requires practice to get comfortable with.
Even if you can be there right by someone learning to program, and help them set up a web server, they will have to remember how to do that when they want to play with programming while you're not there. That's actually quite a lot to remember when you don't yet understand what the commands mean; you think of it as "go to the directory, start SimpleHTTPServer", but they have to memorize the text they have to type. Maybe you're the one who cd'd into the correct folder for them, and they remember to type `python -M SimpleHTTPServer` in the terminal you created; they will then have problems they don't know how to solve when they go home and open a terminal and type the command and it doesn't work because they weren't in the correct directory.
Absolutely, I don't think we are in disagreement at all. I just wanted to mention the availability of simple web servers (on Linux, as you rightly state).
On topic, I agree that this is throwing the baby out with the bathwater. A compromise would perhaps be an explicit whitelist of allowed directories to serve via the file:// protocol, set by the user (while disallowing traversal upwards of these, of course).
It ends up definitely being a tax on developer efficiency overall. It also makes web development more hostile to newbies because they have to figure out how to configure a server or hop into some third-party toolset on the web to start experimenting. With the tendency to ban use of new features on non-HTTPS origins (hi again, Chrome) a newbie developer will soon have to have both a server and a https cert before they can even start experimenting. If they host on a third-party https domain now third parties are responsible for malware that might get hosted there.
It would improve security, but ultimately as long as the file "enclave" can execute javascript, it has access to enough side channels to communicate any data it collects to the outside, so I guess the security concerns wouldn't be fully resolved.
One example: if two programs share the same CPU and have access to CPU resources, then one program could transmit information to another program by putting the CPU under load and removing the load again in some kind of morse code fashion. In computers with fans this would probably be noted by users but not every computer has fans. It's not a very high bandwidth way but enough to get ssh keys transmitted within a few hours of connection.
I think this summarizes the issue and is exactly the correct solution.
There's a lot of the comments along the lines of "just run python -m SimpleHTTPServer" - but doing that makes your computer just as vulnerable as allowing file:// in the first place, in theory. It's only the very awkwardness of doing that that makes it any safer. Instead of hiding this fundamental incompatibility between security and local accessibility behind a layer of inconvenience, better to drag it out into the open and label it and fully support it. While you're at it, you can slacken off some of the other restrictions in "local mode" as well.
A browser is the modern VM, for better or worse. It should function locally, standalone.
This case makes me wonder what if traditional filesystems would not separate files and directories. So that there would be just files which may have data and sub files. Then html file could include all js files etc. directly inside it so that we could give multi file permissions without leaking it to siblings.
The feature you are looking for already partially exists. Look for "extended attributes" (for most filesystems) or "alternate data streams" (for NTFS).
But in this case, it's much simpler to make a tar or a zip with the HTML and all necessary files. eg. that's how Python "eggs" work.
> I think this also had implications on using wasm in electon
It should not. Electron runtime is not a browser and developer can tweak its security settings.
I would suggest another idea for local files: grant access to folder whose name matches HTML file name, with suffix. For example: file some-page.html and directory some-page_files.
> I would suggest another idea for local files: grant access to folder whose name matches HTML file name, with suffix.
That would certainly help. It would restrict some multi-html-file projects a bit though that use shared resources. Probably can be helped by having a folder named html-fetchable-files or something.
Perhaps this should be addressed but the fact it requires the user to download and open a file means it's of limited use to attackers. If you can persuade a user to do that then you needn't bother with browser exploits to get access to a user's files.
Edit: but wait, it can only access the directory the file was downloaded to? So that's almost certainly restricted to the user's download folder. That makes even less useful.
The downloads folder is a perfect target actually. Lots of documents end up downloaded as pdfs, I certainly have enough documents to dox me. Anyone who does their e-mailing through a browser will most likely have a bunch of exciting attachments in their downloads folder.
You'll probably also find a bunch of installers in the downloads folder, I could imagine a sophisticated attacker looking for installer .msi's or .exe's for software which is known to have vulnerability.
Sure but you can get much more if you use a more exploitable file type in the first place. Why would you willing jump back into a browser's sandbox when you've just persuaded the user to bypass it entirely?
It's not so much why someone would choose this over that, as it is what attack vectors are added to which surface. Why wouldn't a bad actor be willing to jump back into a leaky sandbox?
Because you may of had zero access rather than some, for example a web dev who wouldn't click on an .exe but would open an .html file without a second thought. More access isn't necessarily always the end goal either.
Easy solution: Firefox gets two sandbox modes for file://;
If the directory is a subdirectory or top level to the default Download Directory or a recent "Save To.." location then the file will be sandboxed like in Chrome and show a warning.
If outside any such directories, it works as normal.
Yeah. The Downloads directory inevitably accumulates sensitive data over time, especially lacking automatic cleanup/expiration of files. For this reason alone, Firefox should follow the Chromium/Edge policy.
Running Firefox via snapcraft, I've come to realize that desktop Linux systems keep moving the problem around without fully solving it (though I'm quite grateful for the real security benefits of snaps).
Traditional users/permissions are ineffective because all your important data is readable by your ostensibly unprivileged user.
Then SELinux/AppArmor enforcement comes along, but it's of limited effectiveness because you end up with free-for-alls (for convenience's sake) like ~/Downloads.
I think SELinux/AppArmor is a good idea for services like web/ftp/irc/ssh servers, wayland compositors, notification daemons (like dunst), external devices managment daemons (like udiskie) etc. But it isn't a good solution for applications which a user could try to use to read or change arbitrary things in the system for no malicious reasons. But, as I understand it, the Flatpak model of having the application sandboxed and then only allowing it to access files which are selected by the user in the GTK dialog is a great solution. It's just that I haven't seen one for command line applications. E.g. how should we protect ourselves from someone exploiting a vulnerability in vim to access our private documents, which we could potentially want to edit with vim ourselves?
> Yeah. The Downloads directory inevitably accumulates sensitive data over time, especially lacking automatic cleanup/expiration of files. For this reason alone, Firefox should follow the Chromium/Edge policy.
> Then SELinux/AppArmor enforcement comes along, but it's of limited effectiveness because you end up with free-for-alls (for convenience's sake) like ~/Downloads.
I keep this clean when I am finished with a file I usually have a term up and will move it to somewhere in ~/ or ~/Documents
> E.g. how should we protect ourselves from someone exploiting a vulnerability in vim to access our private documents, which we could potentially want to edit with vim ourselves?
I think for me it would be about starting with high risk applications.
Compatible with spec and previously a feature. I agree that it should be patched but Chrome's policy has historically made local web development and testing a pain in the ass because now you have to configure a web server correctly and work around Chrome's broken cache-control policy (have fun ctrl-f5'ing all the time or opening devtools to disable cache, which deoptimizes your JS)
I struggled with this for years and opened multiple bugs about it. If you're trying to release software to end-users that requires them to configure a whole damn web server you get really tired of it.
Disabling content loading from file:// is one solution, but I feel like the 'this was loaded from the internet' flag already used for downloaded EXEs and DLLs is a perfectly reasonable alternative that would work just as well without breaking things for local development. (To be clear, you don't offer the option to bypass that, since it would only be a security vulnerability)
You need way more configuration than that, python's http server doesn't handle keepalive and threading correctly (or didn't when I last used it, maybe that's fixed in 3).
I historically had to use IIS or Apache, and at work we used a full Apache install. If you used python your performance was much worse if your application worked at all.
For C# apps you can at least just spin up a HTTPD directly in your app using system APIs, but it's also kind of flaky.
Killing javascript access to file:// would be annoying for quick experimenting.
Maybe denying network access to locally loaded JS, so that nothing could be transferred out is possible solution?
This is not something a kid learning basic html/js can do easily, since he probably uses windows, and doesn't even know how to navigate in the command prompt.
The "click on the html file on the desktop" just works(TM)
I am not a Web programmer, so what I suggest might be nonsense. Please correct constructively :)
The central statement seems to be:
> “Our implementation of the Same Origin Policy allows every file:// URL to get access to files in the same folder and subfolders.”
What about the following simple mitigations:
* Access by file:// URL to the root and user's home directory proper are forbidden by the browser implementation (Because all subdirectories of the home directory is always a bad idea, root even worse so) Hard-coded, error dialog, period, no way to override short of patching the browser or mounting trickeries.
* Access to any other subdirectories is allowed, but will cause a warning that by proceeding you grant access to the directory and all it's subdirectories. The warning cannot be suppressed by normal settings, but appears only once a day. An average user will not get it frequently, so there is a chance that they read it (and if they click OK without reading it's their problem). And for the Web developer clicking once per day is still easier than configuring an Apache. And ideally they know why they are clicking it.
It's easier to create a new user account and run firefox from it. Something like:
xhost +si:localuser:firefox && su - firefox -c 'DISPLAY=:0 HOME=/home/firefox firefox 2>/dev/null' && xhost -
To avoid this, I use Firejail [1] with a custom rule set to limit the browser's access only to Downloads and its own profile folder. Does anybody know of anything similar for MacOS?
From the article, access is already limited to the directory in which the HTML file is located, so this wouldn't help.
Either it would be in the Downloads directory, where it already has access, or it would be in another directory and you wouldn't be able to open the file at all unless you disable your sandbox.
Mozilla's latest tactic appears to be to trash Chrome semi-weekly on HN and then try to bring in users to Firefox. Then, later that week a new vulnerability is discovered in Firefox.
This breaks the site guidelines by being flamebait, by insinuating astroturfing, and by using HN threads to fight some sort of pre-existing battle. You've done this before, and we've had to warn you before. If you keep doing it we're going to have to ban you, so please stop.
Ultimately, file:// is a great, cloud free method of having web pages and applications and it should stay that way instead of forcing everything to be networked and reliant on third party computers or domain names.
There are so many reports, documents, etc that live as non-networked html files. E.g. rust documentation (cargo doc --open) is generated as html files on-disk and then just displayed without the need for a webserver. Starting a localhost webserver is in fact less secure than file because now every user on the computer has access instead of just the users with read-access to the files. This has thankfully been fixed in Chrome OS though.
Responsive web apps are not the solution as they still need "seeding" via the network. Maybe some kind of standardized format where you have a glorified zip file with some metadata and when you double click it, it opens in the web browser which starts a web server in the background that runs a specially designated js in that zip file and which can accept usual fetch requests and has read access to the entire zip file. The browser's "UI" would then communicate with the server via well-known protocols.