Brave should have its own User-Agent, but here is how you detect it anyway

The User-Agent string is the name that web browsers and other web clients send to web servers to identify their make and model to the server. This data is primarily used for statistical and troubleshooting purposes. The Brave web browser isn’t brave enough to have their own User-Agent and instead tries to camouflage as Google Chrome.

Brave is a very opinionated web browser. This makes it easy to reliably detect it even without a unique User-Agent, and I’ll spend most of the article advocating for why Brave should have their own User-Agent. You can skip to the last two sections if you’re only interested in the detection code.

Brave actually had a User-Agent of its own in the first few months of its existence, but removed it in . The history books (git commit logs) show that Brave removed the “Brave/Version” component from their User-Agent string to make it more difficult to fingerprint the browser.

Just days before the removal, Brave Software had attracted the ire of the Newspaper Association of America (NAA) and were understandably worried that publishers would begin targeting and blocking their User-Agent over Brave’s plans to replace publisher ads with their own ads. The Drum has the details on this.

It’s quite easy to detect ad blocking extensions, and few (if any?) publishers actively block visitors who use this type of software. There are several other niche web browsers that block ads by default and also set their own unique User-Agent. I’ve not found any indications of publishers actively blocking any of these browsers even on a small scale.

Detection methods

Brave may not have its own HTTP User-Agent request header, but even the order of Brave’s HTTP request headers are in themselves unique to Brave. No client side JavaScript required.

I’ve found over 40 easily detectable characteristics which are unique to Brave, and it only took me half an hour to discover and test these. I’m assuming there are many more methods.

Most of these unique characteristics stem from Brave’s efforts to make it harder to uniquely fingerprint individual users. Which I’m all for. I don’t believe there are any legitimate reason to fingerprint individual users. This, combined with behavior specific to Brave’s ad-blocking implementation, makes it easy to fingerprint the Brave browser itself.

It’s really difficult to design a browser that doesn’t allow for fingerprinting of its users while also not making itself uniquely distinct from its upstream browser. Just ask the Tor Browser project.

User-Agent is a free promotional tool

How are websites supposed to know that the Brave browser is popular and that they should consider signing up for the Brave Payments platform?

Many web publishers are in desperate need to diversify their income streams, and Brave can held them achieve that at practically no deployment cost to the publisher. However, why would they even bother to do so? When they check their access logs, they’ll see that Brave has 0 users.

Users of other web browsers are promoting that web browser and advocating for the website to test and ensure compatibility. Brave users fly under the radar as Google Chrome users, so websites might never realize that they’re popular among the Brave user community.

Brave Software asks web publishers to help promote their web browser but doesn’t provide the tools publishers require to run and measure an efficient promotional campaign for a web browser. You never see ads for the Google Chrome browser when you’re already using Google Chrome but users of any other web browser knows only too well that ads for Chrome are everywhere on the web.

Every browser should have its own User-Agent

The point of this article was really meant as an argument for Brave to adhere to the established etiquette and protocol among web browsers: use your own User-Agent!

There are no independent and verifiable counts of how many people use Brave. (Well, I count them — but my sample size is quite small.)

Brave should at the very least share their User-Agent with their verified publishers. These are the same websites Brave asks to help it promote the Brave browser. The Brave browser already knows how to identify websites that participate in Brave Payments as verified publishers. Brave could conditionally expose the Brave User-Agent to these websites to allow them to measure and analyze the success of Brave Payments.

Brave can also work around specific site blocking by hiding their User-Agent from any site that would target and negatively impacting their users using site-patching. Site-patching is a tool you’ll find in most web browsers were the browser vendor can run script snippets or change settings for specific websites to work around User-Agent discrimination and compatibility issues.

How to detect Brave?

Until Brave sets their own User-Agent, you can use the following JavaScript function to detect Brave. It will only return true when run in Brave with Brave Shield enabled (the default). I’ll explain how it works in the next section.

function detect_brave_browser() {
  // initial assertions
  if (!window.google_onload_fired &&
       navigator.userAgent &&
      !navigator.userAgent.includes('Chrome'))
    return false;

  // set up test
  var test = document.createElement('iframe');
  test.style.display = 'none';
  document.body.appendChild(test);

  // empty frames only have this attribute set in Brave Shield
  var is_brave = (test.contentWindow.google_onload_fired === true);

  // teardown test
  test.parentNode.removeChild(test);

  return is_brave;
}

This method was last verified with Brave for desktop version 0.23.19. Please use the report link at the bottom of this article to notify me if the detection function I shared above stops working, and I’ll share another detection method.

What’s going on here?

When Brave Shield is enabled, Brave sets the google_onload_fired attribute to true on every window object. This attribute is normally only used internally in some scripts from Google products. However, it’s never found in window objects where Google’s scripts haven’t run (like the empty frame that is created in the above detection script.)

This is weird behavior is left over code that addressed a site compatibility issue caused by Brave’s own ad-blocking on two specific websites in . You’d normally never see a web browser make a global change like this for just two websites, but Brave was still a young and inexperienced browser at the time and this work-around has been left in place ever since. Site specific problems are usually resolved with site-patching.

This type of fingerprinting is ridicules and it shouldn’t be necessary. I hope we’ll see Brave live up to its own name and follow with the web community consensus: every browser should have their own User-Agent.