# Understanding the Three Levels of Blocking in uBlock Origin's Dynamic Filtering

> Discover uBlock Origin's three levels of blocking: master switch host bitmap rules and URL string patterns. Learn how they control network requests for enhanced privacy and security.

- Repository: [Raymond Hill/uBlock](https://github.com/gorhill/uBlock)
- Tags: deep-dive
- Published: 2026-03-05

---

**uBlock Origin implements a three-tiered dynamic filtering engine that operates through a master switch, host-level bitmap rules, and URL-level string patterns to determine whether network requests are blocked, allowed, or passed to static filters.**

The **levels of blocking in uBlock Origin's dynamic filtering** provide granular control over network traffic, allowing users to override static filter lists with custom rules. This architecture, implemented in the gorhill/uBlock repository, uses progressive evaluation layers that range from global on/off toggles to specific URL pattern matching.

## The Three-Tiered Dynamic Filtering Architecture

uBlock Origin's dynamic filtering system operates as a decision stack that evaluates network requests against three distinct rule layers. Each layer can independently return a **block**, **allow**, or **noop** (no operation) decision, with the engine stopping at the first definitive ruling.

The architecture is designed to prioritize user control: the master switch acts as a global circuit breaker, host-level rules provide efficient bitmap-based filtering for common scenarios, and URL-level rules handle complex exceptions that require pattern matching.

## Level 1: The Master Switch

The **master switch** serves as the global enable/disable control for the entire dynamic filtering engine. When disabled, uBlock Origin ignores all dynamic rules and relies solely on static filter lists.

In the source code at [`src/js/dynamic-net-filtering.js`](https://github.com/gorhill/uBlock/blob/main/src/js/dynamic-net-filtering.js), this is implemented as a Boolean flag accessed via `µb.sessionSwitch` or `µb.dynamicFilteringEnabled`. When the switch is off, the evaluation engine immediately returns "no decision," allowing static filters to process the request.

**UI Control:** The padlock button in the Dynamic Filtering pane of the dashboard toggles this switch, allowing users to temporarily disable all custom dynamic rules without deleting them.

## Level 2: Host-Level Rules

**Host-level rules** form the core of uBlock Origin's dynamic filtering, operating on the relationship between source hostnames, destination hostnames, and request types. These rules use a highly efficient bitmap storage system rather than string matching.

In [`src/js/dynamic-net-filtering.js`](https://github.com/gorhill/uBlock/blob/main/src/js/dynamic-net-filtering.js), each rule is represented as a bitmap where specific bit offsets determine the action for each request type. The `typeBitOffsets` table defines positions for types like `script`, `image`, `1p-script`, `3p-script`, `3p-frame`, and others.

### How Host-Level Evaluation Works

The evaluation function `DynamicHostRuleFiltering.evaluateCellZY()` processes rules in order of specificity:

1. Explicit rules matching source, destination, and type
2. Third-party and first-party shortcut rules
3. Generic `* *` wildcard rules

The function returns numeric codes: `1` for block, `2` for allow, and `3` for noop. This evaluation occurs in [`src/js/dynamic-net-filtering.js`](https://github.com/gorhill/uBlock/blob/main/src/js/dynamic-net-filtering.js) between lines 35-44 for the type table and lines 71-80 for the evaluation flow.

### Common Host-Level Rule Patterns

- `* * 3p-script block` — Blocks all third-party scripts globally
- `example.com * script block` — Blocks all scripts on example.com regardless of destination
- `* tracker.com * block` — Blocks all requests to tracker.com from any source

## Level 3: URL-Level Rules

**URL-level rules** provide the finest granularity, matching full URL patterns including wildcards rather than just hostnames. These rules are essential for exceptions that cannot be expressed through host-only logic, such as allowing a specific image from a CDN while blocking other resources from the same domain.

These rules are stored as plain strings in `µb.permanentFirewall` and parsed by [`src/js/url-net-filtering.js`](https://github.com/gorhill/uBlock/blob/main/src/js/url-net-filtering.js) (specifically around line 239). Unlike the bitmap-based host rules, URL rules use pattern matching similar to static filter syntax, supporting wildcards like `||example.com/ads/*.js$script,third-party`.

**UI Control:** The text area at the bottom of the Dynamic Filtering pane allows direct entry and removal of URL-level rules.

## Evaluation Precedence and Flow

When uBlock Origin processes a network request, the **levels of blocking in uBlock Origin's dynamic filtering** are evaluated in strict order:

1. **Master Switch Check** — If `µb.sessionSwitch` is disabled, the engine returns "no decision" immediately and static filters handle the request.
2. **Host-Level Evaluation** — `DynamicHostRuleFiltering.evaluateCellZY()` checks bitmap rules from most specific to least specific. If it returns block (1) or allow (2), the decision is final.
3. **URL-Level Firewall** — If host-level returns noop (3), the engine consults `µb.permanentFirewall` and [`src/js/url-net-filtering.js`](https://github.com/gorhill/uBlock/blob/main/src/js/url-net-filtering.js) for pattern matches.

This cascade ensures that broad rules can be overridden by specific exceptions, and that users can disable the entire system without affecting static filter operation.

## Practical Implementation Examples

The following code examples demonstrate how to interact with the three blocking levels programmatically:

```javascript
// Level 1: Toggle the master switch
µb.sessionSwitch = true;   // Enable dynamic filtering
µb.sessionSwitch = false;  // Disable all dynamic rules

// Level 2: Add a host-level rule (block all 3rd-party scripts)
µb.dynamicFilteringDefault.push('* * 3p-script block');
µb.permanentFirewall.fromString(
    µb.dynamicFilteringDefault.join('\n')
);

// Level 3: Add a URL-level rule (allow specific tracker)
const urlRule = '||tracker.example.com/collect.js$script,allow';
µb.permanentFirewall.fromString(urlRule, true);  // true = append

// Debug: Inspect current rule set
console.log(µb.dynamicFilteringDefault.join('\n'));

```

## Summary

- **Master Switch**: The global Boolean (`µb.sessionSwitch`) that enables or disables the entire dynamic filtering engine in [`src/js/dynamic-net-filtering.js`](https://github.com/gorhill/uBlock/blob/main/src/js/dynamic-net-filtering.js).
- **Host-Level Rules**: Bitmap-based filtering using `DynamicHostRuleFiltering.evaluateCellZY()` to match source/destination hostnames and request types with numeric return codes (1=block, 2=allow, 3=noop).
- **URL-Level Rules**: Pattern-matched string rules stored in `µb.permanentFirewall` and parsed by [`src/js/url-net-filtering.js`](https://github.com/gorhill/uBlock/blob/main/src/js/url-net-filtering.js) for exceptions requiring full URL wildcards.
- **Evaluation Order**: Master switch → Host-level bitmap → URL-level patterns, with early termination when a definitive block or allow decision is reached.

## Frequently Asked Questions

### What is the difference between host-level and URL-level dynamic filtering?

Host-level rules operate on domain names and request types using an efficient bitmap system in [`src/js/dynamic-net-filtering.js`](https://github.com/gorhill/uBlock/blob/main/src/js/dynamic-net-filtering.js), making them fast for broad policies like blocking all third-party scripts. URL-level rules match full URL patterns including wildcards via [`src/js/url-net-filtering.js`](https://github.com/gorhill/uBlock/blob/main/src/js/url-net-filtering.js), providing precision for exceptions like allowing a specific image from a blocked domain. Host rules are evaluated before URL rules, so URL rules can override host-level "noop" decisions but not explicit host-level blocks or allows.

### How does the master switch affect static filter lists?

The master switch (`µb.sessionSwitch`) only controls the dynamic filtering engine defined in [`src/js/dynamic-net-filtering.js`](https://github.com/gorhill/uBlock/blob/main/src/js/dynamic-net-filtering.js). When disabled, uBlock Origin ignores all dynamic host and URL rules, falling back entirely to static filter lists (EasyList, EasyPrivacy, etc.). Static filters operate independently and continue blocking content based on their own syntax and rules regardless of the dynamic filtering master switch state.

### Can dynamic filtering rules override static filter decisions?

Yes, but only when dynamic filtering returns a definitive **allow** (2) or **block** (1) decision. According to the evaluation flow in `DynamicHostRuleFiltering.evaluateCellZY()`, if dynamic filtering returns "noop" (3), the decision passes to static filters. An explicit "allow" from dynamic filtering (particularly at the URL level) can unblock a request that static filters would otherwise block. Conversely, a dynamic "block" prevents the request regardless of static filter allow rules.

### What request types are supported in host-level dynamic filtering?

Host-level rules support granular request types defined in the `typeBitOffsets` table within [`src/js/dynamic-net-filtering.js`](https://github.com/gorhill/uBlock/blob/main/src/js/dynamic-net-filtering.js). These include `script`, `image`, `stylesheet`, `object`, `xmlhttprequest`, `subdocument`, `ping`, `websocket`, `other`, as well as composite types like `1p-script` (first-party script), `3p-script` (third-party script), `3p-frame` (third-party frame), and `3p` (all third-party requests). Each type occupies specific bit positions in the rule bitmap to enable efficient evaluation.