Skip to content

Scriptlet injection on strict-CSP pages emits two CSP violations (inline + blob fallback) #4188

Open

Description

@santiagofn

Prerequisites

  • I verified that this is not a filter list issue. The wildcard rule in ublock-filters is only what makes the injection attempt happen here; the reported behaviour is in the scriptlet injector and reproduces for any matching scriptlet on any page whose CSP forbids inline scripts.
  • This is NOT a YouTube, Facebook or Twitch report.
  • This is not a support issue or a question.
  • I performed a cursory search of the issue tracker to avoid opening a duplicate issue.
  • The issue is not present after disabling uBO in the browser.
  • I checked the documentation to understand that the issue I am reporting is not normal behavior.

I tried to reproduce the issue when...

  • uBO uses default lists and settings. The triggering rule ships enabled in the default ublock-filters list; no custom filter is involved.

Description

On documents whose CSP has a script-src without 'unsafe-inline', a nonce or a hash, vAPI.scriptletsInjector (js/vapi-background-ext.js) makes two injection attempts for a scriptlet that can never execute on that document:

  1. inline <script> containing the sentinel assignment + scriptlet code. Blocked by the page CSP (script-src-elem).
  2. Because the sentinel check fails, the fallback runs: URL.createObjectURL(new Blob([details.scriptlets])) and <script src="blob:...">. Also blocked by the page CSP, since script-src does not allow blob:.

Result: two CSP violations per page load. They are harmless, but they look like a real CSP problem and cannot be told apart from one.

The rule that makes this hit arbitrary sites is in ublock-filters:

*,~edu,~edu.cn,~127.0.0.1,~adobe.com,...,~cloudflare.com,...,~www.digitalocean.com##+js(prevent-clipboard-write, ...)

Any host outside that exclusion list that sends a strict CSP gets the violations, so this is not site-specific — the URL below is simply an example I maintain.

A specific URL where the issue occurs

https://futbol-domingos.netlify.app/

Response header served with the document:

content-security-policy: default-src 'self'; script-src 'self' https://challenges.cloudflare.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https:; font-src 'self' data:; connect-src 'self' https://futbol-domings-backend.fly.dev https://futbol-domingos-backend-beta.fly.dev https://challenges.cloudflare.com; frame-src https://challenges.cloudflare.com; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; form-action 'self'; upgrade-insecure-requests

Steps to Reproduce

  1. Firefox 159.0 (Linux, snap) with uBO 1.75.2 and default lists/settings.
  2. Open https://futbol-domingos.netlify.app/
  3. Open DevTools console.

Console output (two separate violations):

Content-Security-Policy: The page’s settings blocked an inline script (script-src-elem) from being executed because it violates the following directive: “script-src 'self' https://challenges.cloudflare.com”. Consider using a hash ('sha256-…') or a nonce.
Content-Security-Policy: … blocked … blob:moz-extension://<uuid>/<uuid> … script-src …

Expected behavior

Either the scriptlet executes, or uBO does not attempt an injection it can determine will be blocked. In particular the blob fallback should not be attempted when the document CSP disallows blob: scripts, so a failed inline attempt does not produce a second violation.

Actual behavior

Two CSP violations are logged on every page load for a scriptlet that never runs. No functional impact.

Suggestion

uBO already reads (and can modify) Content-Security-Policy response headers for its own CSP filtering, so the document's effective script-src could be inspected once per frame and used to skip scriptlet injection — or at least the blob fallback — when inline and blob scripts are disallowed by the page.

Troubleshooting information

uBlock Origin: 1.75.2
Firefox: 159
filterset (summary):
 network: 245180
 cosmetic: 52390
 scriptlet: 36483
 html: 4271
listset (total-discarded, last-updated):
 added:
  spa-0: 3815-16, 10h.31m
  spa-1: 7340-294, 4d.21h.3m
 default:
  user-filters: 124-2, never
  ublock-filters: 55860-79, 31m Δ
  ublock-badware: 10611-17, 31m Δ
  ublock-privacy: 4172-2, 31m Δ
  ublock-unbreak: 2911-1, 31m Δ
  easylist: 84526-154, 31m Δ
  easyprivacy: 56984-48, 31m Δ
  urlhaus-1: 109579-2, 31m
  plowe-0: 3562-1053, 2d.22h.32m
  ublock-quick-fixes: 657-17, 31m Δ
filterset (user): [array of 124 redacted]
trustedset:
 added: [array of 22 redacted]
switchRuleset:
 added: [array of 1 redacted]
hostRuleset:
 added: [array of 1 redacted]
userSettings:
 cloudStorageEnabled: true
hiddenSettings: [none]
supportStats:
 allReadyAfter: 1000 ms (selfie)
 maxAssetCacheWait: 400 ms
 cacheBackend: indexedDB

Activity

  1. uBlock-user commented on Nov 3, 2026

    @uBlock-user
    Member

    gorhill/uBlock@9af8ef4c6b

    fixed in dev build

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions