Privacy Browser

Privacy Browser Will Never Monetize the Default Search Engine

This morning I received the following email.

Hi Soren,

I hope all is well. I’m Chris – CMO at Startpage and I came across your Privacy Browser as I was looking into F-Droid.

I saw Startpage on the screenshots on
I assume you’re a fan and wanted to reach out to hear what you think of Startpage and how it is currently integrated in Privacy Browser.
If possible I would like to help you in monetizing the searches coming to Startpage from Privacy Browser.

I look forward hearing from you.

All the best, Chris

Christiaan Solcer

Privacy Browser will never monetize the default search engine for the following two reasons.

If the search engine is monetized, decisions about the search engine are no longer made in the best interest of the users

I currently select the list of search engines included in the browser, and the default search engine and homepage, based on what I consider to be best for users. You can read the rational for switching to Startpage as part of the 3.2 release. As noted in that post, there are things I don’t like about Startpage, and it is likely I will switch to something else in the future if I can find something better.

But if I formed a financial relationship with Startpage, that would unduly influence any decision to switch to a different default search engine in the future. Instead of making the decision based on the best interests of the users, it would be made on which search engine offered the most money.

Once you monetize the search engine, there is a huge incentive to not block privacy invasions

Mozilla makes almost all their money by monetizing the default search engine in Firefox. In 2018 they made $435 million. Do you think search engines would be willing to pay them that much money if they couldn’t track what individual users are searching for? For example, if I responded to the email above expressing interest in receiving money for using Startpage as the default search engine, do you think they would be OK with me continuing to block their trackers?

Naughty, naughty.

My personal belief is that the primary reason why Mozilla only makes token attempts to protect user privacy is because they are financially tied to allowing the default search engine to track users. For example, they do not disable JavaScript by default. They have an exceptionally lose Referrer Policy. They don’t integrate an ad blocker into default installs.

This corrupt relationship between search engines and browsers is the primary reason why I started development of Privacy Browser. There is no chance that I will ever monetize the default search engine, no matter how much money they offer.

Financial Reports Privacy Browser

Liberapay Account

F-Droid turned me on to Liberapay, which is similar to Patreon, but with a focus on open source principles. As such, it is right up my alley.

I have created a Liberapay account and listed it on the Donations page.

Privacy Browser

New WordPress 2020 Theme

The theme for the website has been updated from WordPress Twenty Nineteen to Twenty Twenty. Overall I like the effect. The only downside I have seen so far is that the menu doesn’t work if JavaScript is disabled. Someday, if I have some free time, I might contribute to the WordPress project to fix that.

Privacy Browser

Mastodon Account

A while back a user suggested I setup a Mastodon account for Privacy Browser, but at the time I didn’t feel that I needed anything in addition to all the existing communication platforms I was using. But, as is typically the case, over time my perceptions have changed, and I thought it would be nice to have a platform where I could toot about Privacy Browser’s development as I work on features between releases. I expect I will use it similar to the blog posts I write after each release, but more focused on giving insights to each feature I am developing as things are shaping up for a new release.

The account is registered at

Privacy Browser

Privacy Browser 3.4.1

Privacy Browser 3.4.1 has been released. It contains an emergency fix for some Android 10 devices that couldn’t access the public directories even when the storage permission was granted. This caused denied errors when the storage permission was granted and the default download location was used on these devices.

Privacy Browser

Privacy Browser 3.4

Privacy Browser 3.4 has been released. It replaces the use of Android’s built-in download manager with a custom implementation. I didn’t start off trying to do this. Rather, I was building a feature to save a raw URL, and after I had done it I realized I could use it for all download purposes.

As I explain in the design guidelines, I attempt to reuse existing Android elements as much as possible. However, there are a couple of things about Android’s download manager that are unsatisfactory. First, it doesn’t provide a mechanism to specify a proxy. Second, it doesn’t work at all on Android 7.0 when a VPN is enabled. This was the reason that Privacy Browser added an option to download with an external program in version 2.14. With this release, that is no longer needed, so it has been removed.

Look at all that beautiful information.

There are a few things I really like about this implementation. First, the download URL is editable live. This is a feature that isn’t available on any other browser I have used, that, once I realized I could do it, tickled me pink. It isn’t something I would use often, but it doesn’t take any more space than displaying the URL, which is what I was originally going to do, and there are a few times I would like to modify a URL before download.

The file size is retrieved via an HTTP HEAD request whenever the URL is edited. This also indicates if a URL is invalid.

Not even Chuck Norris could download that URL.

The file name is populated using the new download location option combined with a file name extracted from the URL.

This was feature request 32. It is nice to finally get it done.

File locations in Android are complex, so they deserve a bit of explanation. The first aspect is that the naming structure has changed over time. In older version of Android, user files were located in /storage/sdcard. Beginning in Android Lollipop (version 5.0, API 21), the file location was changed to /storeage/emulated/0. The 0 indicates the first profile. If there are other profiles on the phone, they will have different numbers. Note that it is possible that OEM customizations to Android might change these locations.

In addition to the base location, beginning with Android Marshmallow (version 6.0, API 23) an apps ability to read and write files is restricted based on the storage permission. So, any app can read and write to its public directory, which is a subdirectory that includes the app’s ID. For the standard flavor of Privacy Browser it is /storage/emulated/0/Android/data/com.stoutner.privacybrowser.standard. Any files saved in this directory are deleted by Android if the app is uninstalled. Reading and writing to other public directories requires the storage permission.

Selecting auto for the download location automatically chooses an appropriate directory based on the version of Android and the status of the storage permission. For example, on my phone it selects /storage/emulated/0/Download if the storage permission has been granted and /storage/emulated/0/Android/data/com.stoutner.privacybrowser.standard/files if it hasn’t.

If custom is selected, the user can use the separate Download Custom Location preference to specify a location. It should be a user-writable path that doesn’t end in a /. If a user attempts to download a file to a public directory without enabling the storage permission a notice is displayed at the bottom of the save dialog. Before the file is saved, a dialog is presented requesting that the user grant the storage permission.

Amazingly, an app can check to see if a file exists in a directory where it neither has read nor write access!

As can be seen in the screenshots above, the save dialog now warns if a download will overwrite an existing file. Not only does the save dialog appear when a file is downloaded, but it can also be launched from the context and options menus.

When files have finished there is an option to open them displayed in a snackbar. Except for APK files on Android Oreo (version 8.1, APK 26) or newer, where the REQUEST_INSTALL_PACKAGES permission is required to install an APK.

Tabs are now reloaded when the proxy changes. I added a Bookmarks entry to the options menu so that the bookmarks drawer can be opened on devices using Android 10’s gesture navigation. And the options menu has been reordered to prevent accidental creation of domain settings.

The poor options menu rarely makes it through a release without a modification.

All the translations were updated with this release except for Turkish, which is currently looking for a translator. Under the hood, this release marks the beginning of the migration of the codebase from Java to Kotlin. The About View Source dialog was migrated in this release. Migrations should increase in future releases.

The next version of Privacy Browser will integrate with Android 10’s new day/night theme.

Privacy Browser


I received an email asking about implementing DNS over HTTPS (DoH) in Privacy Browser. As this is a fairly complex topic, and as there are likely to be other people with the same question, I thought it best to answer with this blog post.

First, a little background about the problem. When DNS (the Domain Name System) was originally designed, people hadn’t really thought through the security and privacy concerns that exist with the internet as we have it today. As such, the original protocol was designed to use UDP (on port 53). This has implications for DDoS amplification attacks, but more importantly for our purposes, it means that DNS traffic is not encrypted. Every time you make a request to view a website in a web browser, your device uses DNS to lookup the IP address of the server. Anyone who is able to listen to the packets leaving your system, like your ISP or the government of the country where you live, can read those DNS requests and, because they are not encrypted, can tell which websites you are visiting.

DoH is designed to address this problem by encrypting DNS traffic and sending it over the HTTPS protocol (which uses TCP instead of UDP and is encrypted). There has been a fair amount of discussion recently about DoH because both Firefox and Chrome have added experimental options to enable it in the browser. This sparked a bit of privacy theater in Europe, and has generally raised the consciousness of users about this topic. The purpose of this post is to explain what DoH is, why it isn’t the best solution to the problem, and why I don’t believe that DNS requests should be handled at the browser level.

  1. I am a big fan of encrypting everything that moves across the internet. I think running DNS over UDP is a poor idea. Most DNS servers now have the option of running a separate TCP interface, but it still often isn’t the default for either servers or clients. Moving to TCP, even unencrypted TCP (still on port 53), removes the problem of the DDoS amplification attacks, although at the cost of making DNS requests take a little more bandwidth and a little more time.
  2. But once you switch everything to use TCP for DNS, it is easy to encrypt that DNS traffic. This is known as DNS over TCP (DoT, which runs on port 853). This is the solution that everyone should be aiming for instead of DoH. While DoT is a little more bandwidth hungry than DNS over UDP, DoH is hugely more bandwidth hungry and much slower. This is because DoH must first setup a TCP connection, then it must setup a encrypted TCP session, then it must setup an entire HTTPS session (huge and bulky and overly complex) just to make a DNS request. So, the first part of the answer is that the solution we should be going for is DoT instead of DoH. Beginning with Android 9 Pie, the OS uses DoT by default as long as it is supported by the DNS server.
  3. Proponents of DoH point to scenarios where some type of ISP or government firewall blocks DoT traffic as a reason to use DoH (which runs on port 443 like normal HTTPS traffic). This is because DoH traffic looks a lot more like normal HTTPS traffic than DoT, so the argument is that it would be harder to block. While it is true that it would be marginally harder to block, it wouldn’t be that difficult to fingerprint it, because it doesn’t actually look that much like normal web browsing traffic. And the IP addresses DoH traffic is heading to are known DNS servers, so it would be fairly east to blacklist those IP addresses if one wanted to. However, the easiest solution to this problem is for all DoT servers to also run a DoH instance, and clients can downgrade from DoT to DoH instead of DNS over UDP if they cannot make a DoT connection.
  4. But this leads us to the next point, which is that even if all DNS traffic were encrypted with DoT or DoH, it would still be laughably easy for ISPs or governments to know exactly what websites you are visiting, so nothing has been gained from a privacy standpoint. This is why I call it privacy theater. Let me enumerate how they can do this in points 5-7 below.
  5. When your device makes an HTTPS request to a server for a website, it includes the server name in plaintext at the beginning of the encrypted packet. Let me slow down and say that again: every packet you send to a HTTPS server includes the unencrypted domain name of the server you want to speak with. This is called Server Name Indication (SNI). SNI exists to solve a very real problem: most servers host multiple domains on the same IP address. The server needs to know which certificate to use when it receives the first packet from your device. If it picks the wrong certificate, your device will show an SSL certificate error. So the packet contains the domain in plaintext to facilitate this. Anyone who could read your unencrypted DNS traffic can also read the SNI on your encrypted HTTPS traffic. So, until the SNI problem is fixed, encrypting DNS is meaningless from a privacy standpoint.
  6. There is some effort being made to encrypt SNI, which is included as an optional component of TLS 1.3. But implementing it is complicated and breaks things. I don’t see anything like this going mainstream until it is implemented as a core part of the TLS protocol and not as an optional component. Which means that we won’t see this until TLS 1.4 at the earliest. And it also means that it won’t work in the real world until the lowest protocol supported by either the server or the client is TLS 1.4, because otherwise the person who it attempting to sniff the domain name could just force a TLS downgrade to 1.3 to get the information. So, at a minimum I put that at 10 years.
  7. At face value the argument would then be that we should just get rid of SNI and have a 1:1 correlation between domain names and IP addresses. But this would make it even easier for ISPs and governments to track your web traffic, because there are companies who maintain lists of all the domain names on the internet and the IP addresses they are linked with. 95% of the websites you visit can be identified just by the list of IP addresses they use. Without SNI, that would be 100%. And the IP address, like the destination address on a letter, is one part of a packet that can’t be encrypted because otherwise the routers on the internet wouldn’t know where to send it.
  8. By now it should be apparent that DoT is the solution we are looking for to encrypt DNS, and that from a privacy standpoint it won’t mean anything until we also get encrypted SNI (and that even after both are encrypted it won’t mean very much). Which leads us to the question: what is Privacy Browser going to do about it. The answer is that Privacy Browser is going to do nothing. The reason I say that is not to be flippant, but because DNS is something I feel very strongly should not be dealt with at the browser level. It should be handled entirely by the OS. I have written a bit about this topic in relation to minimizing Privacy Browser’s attack surface. The idea is that, from a security perspective, the browser shouldn’t try to recreate core OS functions, like encryption or DNS. Not only does this introduce another attack surface that is unlikely to be as well audited as the functionality in the core OS, but it also overrides core OS networking settings at an app level, which leads to unexpected behavior, like not updating DNS servers to match the current network or VPN settings.
  9. This is the part of the conversation where we explain how DoH can actually decrease your privacy instead of merely doing nothing to increase it. During the normal course of the day, you probably connect to multiple DNS servers. When you wake up you probably use the DNS server provided by your home ISP (available over your home Wi-Fi). When you are commuting to work or school, you use your cell phone company’s DNS server. When you arrive at work or school, you connect to the DNS server provided through their Wi-Fi. Each of these DNS servers has a partial list of the the websites you visit throughout the day, but it would be hard to stitch them into a cohesive whole. However, if you use DoH as it is currently implemented in Chrome and Firefox, you would use one DNS server all the time. The two biggest servers that support DoH are run by Google and Cloudflare. Cloudflare promises they won’t do anything bad with that information. But you have no way of verifying that such is the case. And Google, they don’t even make any promises. There is a lot of additional information about this topic on a blog entitled Centralized DoH is bad for privacy, in 2019 and beyond.
  10. To round out this conversation, we should talk a little bit about DNSSEC (Domain Name System Security Extensions). The whole purpose of DoH is to encrypt traffic in transit while it is going between a DNS server and your device. The actual DNS data on the server is unencrypted, and, as a huge security problem, can be modified by that server before it is sent to you. DNSSEC digitally signs DNS information, so that only the owner of a DNS record can make changes. This verifies that the information DNS servers give you is what it is supposed to be. Because it is quite complex to implement, and because it dramatically increases the size of DNS responses, DNSSEC still hasn’t caught on as the default configuration in most cases. But we hopefully are a little closer than encrypted SNI.

Each of the points above represents almost a gross oversimplification of the complexities of these issues. And, because I am constantly learning more about these issues, the implication is that I do not yet know everything about them. As such, I am perfectly willing to change my mind about any of the above topics if I am presented with a persuasive argument to the contrary. I labeled each section above so that is it easy to reference them by number in the comments if you feel that there is anything I have missed.

Financial Reports Privacy Browser

2019 Financial Report


  • Google Play: $335.27
  • Amazon: $136.63
  • PayPal: $71.68
  • Patreon: $29.61

Total Revenue: $573.19

Google Play revenue comes from selling the standard flavor on Google Play. Amazon revenue comes from selling the standard flavor on the Amazon Appstore. PayPal revenue comes from selling the standard flavor on XDA Labs and also from donations. Google AdMob ad revenue only pays out when the balance exceeds $100.00. Currently the balance is $84.71. CEX.IO, the company I currently use to transfer Bitcoin into USD, requires a minimum transfer amount of $20.00. Currently there is a balance of $14.56.

Install Base

Google Play reports some fairly detailed statistics about installations. The other distribution methods (F-Droid, XDA-Labs, the Amazon Appstore, and direct downloads from either do not track this information or provide only vague information. The screenshot below shows the installs of the standard flavor on active devices, which is defined as the “Number of Android devices that have been active in the past 30 days with the application installed”.

The year started out with 408 installs, so the number has almost doubled.

Unsurprisingly, even though there are far more installs of the free flavor, there are fewer active devices. This is because most users either decide they don’t like Privacy Browser, or they switch to using the standard flavor.

The year started out with 165 installs, so there hasn’t been much of a change.
Privacy Browser

Privacy Browser 3.3

Privacy Browser 3.3 has been released. This release took a lot longer than I expected due to a sudden increase in the business of my day job combined with the time constraints of having another child.

There was a major reworking of the way Privacy Browser handles proxies. The underlying code was switched from using an undocumented and unsupported method of tricking WebView to use a proxy to the newly minted AndroidX ProxyController. Not only does this mean that, going forward, we won’t have problems with updates to WebView breaking the proxy, but this also enables the use of SOCKS proxies, which is the preferred way of connecting to Orbot. This removes the problem with HTTP not proxying correctly through recent versions of Orbot.

As part of this code refactoring, users can now set custom proxies. An entry for I2P was also added. I have written instructions on how to use the new custom proxy.

Choices are good.

In previous versions of Privacy Browser, the full name of the app was displayed in the launcher. Depending on the device and the font size, this could cause the displayed name to be truncated.

The launcher display name has now been shortened to one word. This only affects the launcher; the full name will be displayed in most other contexts.

Note that this is not a change I am fully comfortable with, and it might be further revised in the future. On devices where there is enough room for the full name, it is suboptimal to shorten it. There was some discussion about whether Privacy or Browser would be the better short name. And, when displayed in the app chooser, both names will be listed. This last problem can be worked around if intents from the launcher enter the app through a different activity than intents from other programs, but doing so would require refactoring the code and could introduce unintended consequences, so I am not sure I want to go that route.

In case there is any question about which option has the most privacy?

Privacy Browser is now removed from the recent apps list when it is closed via the back button. This brings the back button in line with Clear and Exit from the navigation menu and closing the app with the tab close button.

A bug was fixed that caused on-the-fly settings (the quick settings available in the options menu) to be reset if navigating history (using the forward or back buttons) even if the domain didn’t change. The intended behavior is for these setting to reset only when the domain changes.

Previous version of Privacy Browser had a preset list of font sizes. This has now been changed to a free-form text box that allows any size.

The better to see you with, my dear.

Privacy Browser can now save webpages as MHT archives. A navigation entry to open files has also been added. Privacy Browser can handle MHT files as well as images, text, and anything else that can be displayed in a browser.

There are now separate context menu entries for opening links in the foreground and the background.

Options are good.

Long pressing a link in the bookmarks drawer now opens it in a new tab in the background. This allows users to quickly open multiple bookmarks. Editing of bookmarks is available in the bookmarks activity.

The screen timeout is now explicitly disabled when playing videos in full screen mode. Previously, some videos, like those from YouTube would disable the screen timeout, while others wouldn’t.

HSTS (HTTP Strict Transport Security) is now disabled. The purpose of HSTS is to keep a list of websites that the browser should only connect to via HTTPS instead of HTTP. This has no benefit in Privacy Browser because every website is loaded via HTTPS unless the user explicitly connects via HTTP. And it has the negative downside of creating a de facto list of all the websites a user has visited in the past.

The new Sec-Fetch headers are now displayed in View Source.

Oh, Google. You’re looking a little pudgy. Time to lay off those headers.

The target API was bumped to 29 (Android 10). There is a new French translation provided by Kévin LE FLOHIC. The German translation was updated by Bernhard G. Keller, the Italian translation was updated by Francesco Buratti, and the Spanish translation was updated by Jose A. León. The Russian translation was also updated. I am currently looking for a new Turkish translator.

The next release of Privacy Browser will focus on working well with Android 10’s new gestures and incorporating Android 10’s new dark theme options.

Privacy Browser Security and Privacy Canary

2019 Security and Privacy Canary


During 2019, Stoutner received 0 requests from governments or organizations to insert backdoors into Privacy Browser.

During 2019, Stoutner inserted 0 backdoors into Privacy Browser.


During 2019, Stoutner received 0 requests from governments or organizations to weaken the privacy of Privacy Browser.

During 2019, Stoutner has made 0 changes to weaken the privacy of Privacy Browser.

Legal Requests for Information

During 2019, Stoutner receive 0 legal requests for information from government law enforcement organizations. These requests sought information about a total of 0 individuals.

During 2019, Stoutner provided information in response to 0 legal requests for information from government law enforcement organizations. These responses included information about a total of 0 individuals.

The types of information that Stoutner possesses and can disclose to legal requests from government law enforcement organizations are described in the privacy policy.