Native content blocking in Firefox without installing any extensions

Firefox lets you block permissions per domain for many things including the permission to load images and scripts. This can be used in lieu of a more advanced content- or ad-blocking extension when you only want to block a couple of specific domain names. I’ll walk you through how.

To follow along with this tutorial, you should already be a bit familiar with how the web is put together and how resource loading on the web work. I’ll try to explain along the way, but this tutorial may not be suited for people without any experiences in web development.

You may not want to install an ad-blocker but still want to block some of the more intellectually offensive types of advertisements. (I’m looking at you Outbrain, Taboola, and Revcontent!)

To block any type of content, you’ll need to know which domain it’s being loaded from. The Network Monitor in Firefox can show you where everything is coming from. Press Ctrl + Shift + E (or Command + Option + E on MacOS) to open the Network Monitor. You’ll need to reload the page after opening it for it to show you anything about the current page.

Let’s assume you want to block scripts originating from https://www.example.com from loading on any website for the purposes of this tutorial. Example domains have always annoyed me, so let’s stop any JavaScript from being loaded from that domain.

To block content from a domain, you need to inject a block rule in the site permissions store. You can’t do this from within Firefox, and you should quit Firefox before proceeding.

The site permission store is kept in an SQLite database called permissions.sqlite within your Firefox profile (you can find your Firefox profile folder by opening about:profiles in Firefox’s address field). You can use a graphical tool like DB Browser for SQLite, or the sqlite3 command-line interface.

I’ll explain all the changes you’ll be making in general terms, and then show it of with the SQL query statement as it would be used with the sqlite3 command-line interface (available on MacOS and most Linux variants by default).

Blocking a domain

First you’ll need to add a new row/record to the moz_perms table. Set the origin to the protocol plus the domain you want to block, e.g. https://www.example.com. Note that you’ve to add separate block rules for HTTP and HTTPS.

You then set the type to the type of content you want to block. For the most part, you’ll want to use either “image”, “script”, or “document”. You can find a full list of supported types in nsPermissionManager.cpp and PermissionUtils.cpp. Most ads are loaded over JavaScript, so revoking their domain’s ability to execute scripts effectively stops them dead in their tracks.

Now that you know what permission to block for which domain, proceed by editing the permissions.sqlite database file. In the moz_perms table, you’ll need to insert a new record. Set the value of origin to https://www.example.com, then set type to document, and finally set permission to 2 (which means “revoked.”) Commit the changes, and launch Firefox. The example website should no longer load!

Here is the same exact same process using the sqlite3 command-line interface:

sqlite3 ./permissions.sqlite "INSERT INTO 'moz_perms' (origin, type, permission) VALUES('https://www.example.com', 'script', '2');"

The above is one command without any line breaks.

So, this isn’t the most convenient technique to block content. However, it’s one of the fastest methods available and you don’t need to install any extensions that all add complexity, slow down the browser, and potentially even open up new avenues for attacking the we browser.

Back in ancient times, you could block these sorts of things from the user interface in Firefox itself. You can still block images this way, but unfortunately you can’t revoke permissions such as scripting permissions from the user interface anymore. This option in particular was removed in over fears that Firefox users were hurting themselves.

This technique may however be useful when deployed along with automated browser test suites for tests in environments where an API endpoint or other important resource needs to be simulated as being blocked. This technique can also be used to grant other user-prompted permissions without slowing down tests to interact with the user interface, for the purposes of testing.