A web browser that provides reasonably privacy from common tracking employed by for-profit corporations.
A big inspiration is this blog post: https://theperplexingpariah.co.uk/my-firefox.html
Having used things like request block and self destructing cookies in firefox, I have some ideas for some simple changes to how the browser works that would aleviate a lot of the usability problems that those plugins have.
The end goal is to have something that provides a reasonable user experience, but always favors safety over low learning curve.
The UI is probably just as important as security specifics. It should make it easy to have good password hygene. It should not train you to type you master password repeatedly into easily spoofed dialogue boxes (damn it, firefox!).
The core of this project is segmentation. Modern web browsers share all sorts of data between browsing contexts that can be used to track you. Segmenting browsing contexts off into “universes” (a collection of domains considered to be a coherent group + 3rd parties where its ok to make requests to) would go a long way to provide resonable privacy from tracking.
For example, say there are two websites that both have a 3rd party advertising partner and a shared CDN. The two websites would be in different universes, and would have different user agent strings + other browsing context differents that would result in different fingerprints. Requests in either context to the allowed CDN would be fingerprinted differently depending on which universe they originated. The advertising partner would be filtered out.
Chatted a bit with @TheTarquin about pitfalls that he ran into while working on Silk web browser for Amazon.
Basic take-away seems to be:
- Don’t do clever things with webkit etc or it will break in fantastically terrible ways.
- Modify webkit, and you’ll be stuck forever drinking from the firehose of reintegration.
The requests layer intercepts all traffic from the webkit layer. This is primarily serves the following purposes:
- rewriting the http requests and responses
- routing all traffic through, say, tor
This layer would probably be best written in python if it makes sense to do so, and is probably exposed to the layer above by creating a socks proxy that the webkit subprocesses are hardcoded to use.
In addition to sanitizing http requests, this layer would also be responsible for filtering the content (ad removal, enforcing domain restrictions, rewriting links to trigger new universe processes to be opened, etc). Beautiful soup is a natural choice for this, assuming python again.
Another mark in favor of python is ease of automated testing, as well as being harder to make openssl-level-of-bad vulnerabilies.
It is possible that the requests layer and the compositing layer could be in the same process, which would ease some coordination aspects. There might also be a good argument against putting them in the same processing context if possible.
In the event that the compositing layer is in a separate context, then the requests layer would be spawned by it, and os the compositing layer would be responsible for handling encryption of local user data, etc.
The webkit subprocess would be a pretty minimal single-page webkit browser. It might be written in C++ though it might be best to write it in python.
Webkitgtk might be best to use because it will provide some boiler plate over webkit, and therefor API drift might not be as bad. It also provides gobject bindings, so it is possible that I could write the entire browser in python, which is another win for rapid prototyping.
The only specific requirements for this layer are:
- Reasonable configuration defaults re security, in as much as they can be configured easily or otherwise not possible in the requets layer. Eg, having webgl be off by default.
- Provide custom javascript. For example, location api that gives universe-specific random coordinates, or feeding controlled information as output to non-essential apis that are usable for fingerprinting eg the battery api.
- Spoof the UA to the javascript context.
- All communication goes through the proxy provided by the requests layer. Something like unix sockets would be preferred when available, but idk how possible that is to do without modifying webkit.
- One page per process to start with. It might be expanded to let the process manage all of the tabs in its universe later, so that they can exist in the same execution context. This will be needed for things like keeping persistent logins between tabs in the same universe. Running these as simple, discrete browsers will also make it really simple to keep things like 3rd party cookies from one universe from showing up in another.
- Possible for another process to stitch the browser processes together into a coherent interface.
This might start as a simple GTK browser, and use gtk socket widgets (if that is still a thing and is reasonably cross platform) to stitch together the browser processes.
This layer should be limited to mostly UI related tasks, however it is necessary that it be able to coordinate with the browser layer instances and the requests layer.
For example, color coding tabs per universe. URL bar. Exposing overrides per-universe. “UX”.
Later on I want to be able to composit image data from the browser windows in this layer. For example, providing zsnes-style “ripple under the mouse cursor” effects when being asked for things like unlock passwords, since this would be hard to spoof for phishing purposes as webgl would be off by default on most pages. But in the short term, this isn’t necessary.
Some things where I’m not sure at the moment where they fit:
- Persistent universe-specific settings
- Crash recovery?
- Automatic updating?
- For the sake of separation of concerns, anything that should be locally encrypted (bookmarks, passwords, etc) probably shouldn’t be in the frontend layer (besides the UI-relevant parts)…? I’m not sure where they should be though.
These are things that don’t necessarily fit in the prototype for this browser but are things I would like:
- force domains to be sandboxed browser “universes”, kind of like requestblock
- tor and https everywhere by default?
- easy to enable/disable js per universe
- eg, off by default, but makes it easy to turn on or toggle
- combining domains into universes (eg, needed by thingiverse)
- list of common user agent strings that can be used to cheese fingerprinting, random per universe
- store common js libraries locally both to speed things up as well as to limit tracking
- filtering to remove ads, uncessary scripts even if stored locally (eg, piwik)
- randomize dns provider?
- maybe see if there is some way to integrate inboxen to make it easy to generate new identities
- password manager w/ different privilege levels eg unlock social media without unlocking your bank
- bookmark manager w/ different privilege levels eg keep your secrets safe
- all local storage encrypted, accessible with basic unlock password
- no stored browsing history, encourage use of bookmarks for important things
- always clear the referrer info (eg, google images)
- scrub urls from social media indicators?
- “reader mode” to bypass browser rendering engine, either use gtk to render, or send the text to your favorite editor (org-mode or markdown formatting)