Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Can declarativeNetRequest API interfere with the playing of youtube videos ?

233 views
Skip to first unread message

Kabir Singh

unread,
Jun 25, 2024, 4:30:05 AM6/25/24
to Chromium Extensions
Forgive me if you find this question nonsensical. But recently I was replacing blocking web request listeners  and I had to replace `webRequestBlocking` with declarativeNetRequest API.

Despite webRequest API remaining the same as it was in MV2, it needed webRequestBlocking permission. But now in MV3 we need DNR. I can't quite grasp the workflow of DNR,like we add relevant json to manifest and declare ruleset.json and that's it ? Like iif the rules are static , not dynamic , then this is the only thing to be done right ?

Reason for using DNR => to modify headers 

Issue : Youtube videos stop playing when the extension is active. Extension works fine but youtube videos dont play. They get stuck at the thumbnail.It can be because of the header I am modifying , but again how do I fix this ? The soln provided by gpt doesn't seem to work so ended up here. Here is what my rules.json looks like 

[
    {
        "id": 1,
        "priority": 1,
        "action": {
            "type": "modifyHeaders",
            "responseHeaders": [
                {
                    "header": "Content-Security-Policy",
                    "operation": "set",
                    "value": "media-src https://commons.wikimedia.org https://upload.wikimedia.org"
                }
            ]
        },
        "condition": {
            "urlFilter": "|https*",
            "resourceTypes": [
                "main_frame"
            ]
        }
    }
] Do correct me if I am wrong

woxxom

unread,
Jun 25, 2024, 5:21:35 AM6/25/24
to Chromium Extensions, Kabir Singh
This code overwrites CSP header of all sites and forbids any media sources except the one you've listed. It doesn't make much sense indeed. Show your original code that used webRequestBlocking listener, so we can advise on how to convert it to DNR.

Kabir Singh

unread,
Jun 25, 2024, 5:22:52 AM6/25/24
to Chromium Extensions, woxxom, Kabir Singh
browser.webRequest.onHeadersReceived.addListener(info => {
    const headers = info.responseHeaders; // original headers
    console.log(headers);
    for (let i=headers.length-1; i>=0; --i) {
        let header = headers[i].name.toLowerCase();
        if (header === "content-security-policy") { // csp header is found
            // modifying media-src; this implies that the directive is already present
            headers[i].value = headers[i].value.replace("media-src", "media-src https://commons.wikimedia.org https://upload.wikimedia.org");
        }
    }
    // return modified headers
    return {responseHeaders: headers};
}, {
    urls: [ "<all_urls>" ], // match all pages
    types: [ "main_frame" ] // to focus only the main document of a tab
}, ["blocking", "responseHeaders"]);

woxxom

unread,
Jun 25, 2024, 9:28:50 AM6/25/24
to Chromium Extensions, Kabir Singh, woxxom
Your old code was appending the two hosts to media-src in CSP header. This is not yet possible with DNR. You can open a new feature request in https://crbug.com to implement regexFind and regexReplace for responseHeaders. See also https://github.com/w3c/webextensions/issues/574

The only solution is to enable webRequestBlocking by installing the extension via ExtensionInstallForcelist policy or patching the Chrome binary.

A workaround, depending on what your extension does, may be to add these wikimedia resources as blobUrl or dataUrl in your content script, i.e. your background script will fetch the actual resource and encode it, then send to the content script. For blobUrl you can use the offscreen document (example). For dataUrl you can use FileReader in the background script:
  const blob = await (await fetch(url)).blob();
  const dataUrl = await new Promise(resolve => {
    const reader = new FileReader();
    reader.onload = () => resolve(reader.result);
    reader.readAsDataURL(blob);
  });

Kabir Singh

unread,
Jun 26, 2024, 3:20:09 AM6/26/24
to Chromium Extensions, woxxom, Kabir Singh
I read the github issue you shared , looks like can't play much with CSP header for now. I haven't implemented the approach you suggested ,yet. Although upon inspecting my codebase further I realzed that the components that require the above given URL seem to fetch the necessary data even without the support of CSP bypass header logic , so is there even a need to do all this ?

Kabir Singh

unread,
Jul 1, 2024, 2:17:06 PM7/1/24
to Chromium Extensions, Kabir Singh, woxxom
Not that things were never appending from my side to begin with , but like you said appending two hostst is not possible at the moment .But what if we modified the same header, in a different rule object ,something like down below , would work ?
[
    {
        "id": 1,
        "priority": 1,
        "action": {
            "type": "modifyHeaders",
            "responseHeaders": [
                {
                    "header": "Content-Security-Policy",
                    "operation": "append",
                    "value": "media-src https://upload.wikimedia.org"
                }
            ]
        },
        "condition": {
            "urlFilter": "*",
            "resourceTypes": [
                "main_frame"
            ]
        }
    },
    {
        "id": 2,
        "priority": 2,
        "action": {
            "type": "modifyHeaders",
            "responseHeaders": [
                {
                    "header": "Content-Security-Policy",
                    "operation": "append",
                    "value": "media-src https://commons.wikimedia.org"
                }
            ]
        },
        "condition": {
            "urlFilter": "*",
            "resourceTypes": [
                "main_frame"
            ]
        }
    }
]
As per rule prioritization , if we modify the same header , append operation is allowed, set and remove aren't

Kabir Singh

unread,
Jul 4, 2024, 7:07:52 AM7/4/24
to Chromium Extensions, Kabir Singh, woxxom
Hey woxxom , thank you for your opinion , it would have definitely worked if I was able to fetch the video file(download it) and then convert it into blob. Unfortunately I can't do so, the cors config of the server doesn't allow to do so,I just had the video url with me which I placed in src attribute. But I found a better alternative ! Since my videos relied on domains that weren't supported by the host sites' CSP media-src directive , I replaced my video tag with iframe .As the video is embedded in an iframe, which is not restricted by the parent page's CSP for media content. Again, thanks for your opinion , got to know a lot.
Reply all
Reply to author
Forward
0 new messages