# How uBlock Origin Dynamic Filtering Overrides Static Filter Lists

> Learn how uBlock Origin dynamic filtering overrides static filter lists. Gain session-specific control over network requests with granular allow rules.

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

---

**uBlock Origin's dynamic filtering engine evaluates rules after static filter lists and can override any static block with a user-defined allow rule, giving users granular, session-specific control over network requests.**

The `gorhill/uBlock` repository implements a two-layer filtering architecture where static filter lists are applied first, followed by dynamic filtering rules. Understanding how uBlock Origin dynamic filtering overrides static filter lists is essential for advanced users who need to create exceptions to built-in blocklists without modifying the underlying filter files.

## How Static and Dynamic Filtering Work Together in uBlock Origin

uBlock Origin processes network requests through two distinct engines that operate sequentially. The static engine runs first, followed by the dynamic engine, which has the final authority to override blocking decisions.

### The Static Filtering Engine (`staticNetFilteringEngine`)

The **static filtering engine** loads pre-compiled filter lists such as EasyList and uBlock Origin's own lists. These immutable rules are processed first for every network request. The engine is implemented in [`src/js/static-net-filtering.js`](https://github.com/gorhill/uBlock/blob/main/src/js/static-net-filtering.js) and provides the `matchRequest()` method to check URLs against compiled filters.

### The Dynamic Filtering Engines (`sessionURLFiltering` and `sessionFirewall`)

After static evaluation, uBlock Origin consults two dynamic filtering engines instantiated in [`src/js/filtering-engines.js`](https://github.com/gorhill/uBlock/blob/main/src/js/filtering-engines.js):

- **`sessionURLFiltering`**: Handles per-session URL-specific rules (e.g., `example.com * allow`) set via the Dynamic Filtering pane.
- **`sessionFirewall`**: Manages host-based dynamic rules that apply to specific domains or globally.

These engines are mutable for the duration of the browser session and are evaluated after every static match.

## Where Dynamic Filtering Overrides Static Blocks in the Source Code

The override logic is implemented at specific interception points in the codebase where the code explicitly checks dynamic rules after static filtering has occurred.

### CSP Injection Override in [`traffic.js`](https://github.com/gorhill/uBlock/blob/main/traffic.js)

In [`src/js/traffic.js`](https://github.com/gorhill/uBlock/blob/main/src/js/traffic.js) (lines 1090–1106), uBlock Origin checks dynamic allow rules before injecting Content Security Policy headers. If a dynamic allow rule exists, the CSP injection is skipped, effectively overriding the static filter that triggered it:

```javascript
// URL filtering `allow` rules override static filtering.
if ( cspSubsets.length !== 0 &&
     sessionURLFiltering.evaluateZ(fctxt.getTabHostname(),
                                   fctxt.url, 'csp') === 2 ) { … }

// Dynamic filtering `allow` rules override static filtering.
if ( cspSubsets.length !== 0 &&
     µb.userSettings.advancedUserEnabled &&
     sessionFirewall.evaluateCellZY(fctxt.getTabHostname(),
                                   fctxt.getTabHostname(),
                                   '*') === 2 ) { … }

```

The `evaluateZ()` and `evaluateCellZY()` methods return `2` when an allow rule matches, signaling the override.

### Popup Blocking Override in [`tab.js`](https://github.com/gorhill/uBlock/blob/main/tab.js)

In [`src/js/tab.js`](https://github.com/gorhill/uBlock/blob/main/src/js/tab.js) (lines 200–215), popup blocking follows the same pattern. After the static engine determines a popup should be blocked, the code checks `sessionFirewall` for an allow rule:

```javascript
result = sessionFirewall.evaluateCellZY(
    fctxt.getTabHostname(),
    fctxt.getHostname(),
    popupType);
if ( result === 2 ) {
    fctxt.filter = sessionFirewall.toLogData();
    return 2;                // dynamic allow wins
}

```

If `result === 2`, the popup is permitted despite any static filter match.

## Practical Examples of Dynamic Override

### Creating an Allow Rule in the UI

To override a static block using uBlock Origin's dynamic filtering:

1. Open the uBlock Origin dashboard (`Ctrl+Shift+U`).
2. Switch to **"Dynamic Filtering"**.
3. In the **"Allow"** column, type a hostname (e.g., `example.com`) and press **Enter**.

This creates the rule:

```text
example.com * allow

```

The rule is stored in `sessionFirewall` and will override any static block for `example.com` and its subdomains for the current browser session.

### Programmatically Checking the Override Logic

You can observe the override mechanism programmatically using the extension's internal APIs:

```javascript
// Assume we are on a page that requests a blocked resource.
let ctx = µb.filteringContext.fromWebrequestDetails({
    url: "https://ads.example.com/banner.js",
    tabId: browser.tabs.getCurrent().id,
    type: "script"
});

// Static engine result (normally 1 = block)
let staticResult = staticNetFilteringEngine.matchRequest(ctx, 0b0001);

// Dynamic URL allow (session rule added from UI)
let dynamicResult = sessionURLFiltering.evaluateZ(
    ctx.getTabHostname(),
    ctx.url,
    'script');   // returns 2 if an allow rule matches

console.log({ staticResult, dynamicResult });
// If dynamicResult === 2, the request will be allowed despite staticResult === 1.

```

When `dynamicResult === 2`, the dynamic allow rule takes precedence over the static block (`staticResult === 1`).

## Summary

- **Static filtering runs first**: The `staticNetFilteringEngine` in [`src/js/static-net-filtering.js`](https://github.com/gorhill/uBlock/blob/main/src/js/static-net-filtering.js) processes compiled filter lists like EasyList before any dynamic rules are considered.
- **Dynamic filtering overrides blocks**: The `sessionURLFiltering` and `sessionFirewall` engines in [`src/js/filtering-engines.js`](https://github.com/gorhill/uBlock/blob/main/src/js/filtering-engines.js) are consulted after static matching. When `evaluateZ()` or `evaluateCellZY()` returns `2` (allow), the static block is overridden.
- **Implementation locations**: Override logic is explicitly implemented in [`src/js/traffic.js`](https://github.com/gorhill/uBlock/blob/main/src/js/traffic.js) for CSP injection and [`src/js/tab.js`](https://github.com/gorhill/uBlock/blob/main/src/js/tab.js) for popup handling.
- **One-way override**: Only dynamic **allow** rules override static **block** rules. Dynamic block rules do not override static allow rules (exception filters).

## Frequently Asked Questions

### Can dynamic blocking rules override static allow rules?

No, dynamic blocking rules cannot override static allow rules. The override mechanism in uBlock Origin is unidirectional: dynamic **allow** rules (return value `2` from `evaluateZ()` or `evaluateCellZY()`) can supersede static blocks, but static allow rules (exception filters like `@@`) already permit requests and cannot be blocked by dynamic rules.

### Where are dynamic filtering rules stored?

Dynamic filtering rules are stored in memory for the duration of the browser session via two engine instances defined in [`src/js/filtering-engines.js`](https://github.com/gorhill/uBlock/blob/main/src/js/filtering-engines.js): `sessionURLFiltering` for URL-specific rules and `sessionFirewall` for host-based rules. These correspond to the rules you create in the Dynamic Filtering pane of the uBlock Origin dashboard.

### Does dynamic filtering affect cosmetic filters?

No, dynamic filtering only affects network requests (blocking or allowing URLs and hostnames). Cosmetic filters (element hiding rules) are handled by a separate cosmetic filtering engine and are not influenced by dynamic network filtering rules. Dynamic filtering operates on the network layer in [`traffic.js`](https://github.com/gorhill/uBlock/blob/main/traffic.js) and [`tab.js`](https://github.com/gorhill/uBlock/blob/main/tab.js), while cosmetic filtering operates on the DOM.

### How does uBlock Origin prioritize multiple dynamic rules?

uBlock Origin evaluates dynamic rules in a specific hierarchy. URL-specific rules in `sessionURLFiltering` are checked first using `evaluateZ()`. If no match is found, host-based rules in `sessionFirewall` are evaluated using `evaluateCellZY()`. The first matching rule determines the action, with allow rules (return value `2`) taking precedence over block rules when overriding static filters.