# Block Javascript on specific sites

**URL:** <https://discourse.mozilla.org/t/block-javascript-on-specific-sites/19808>\
**Category:** Development\
**Created:** [October 1, 2017, 1:47pm UTC](https://discourse.mozilla.org/t/block-javascript-on-specific-sites/19808 "2017-10-01T13:47:57Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![log69](https://avatars.discourse-cdn.com/v4/letter/l/2acd7d/32.png) [@log69](https://discourse.mozilla.org/u/log69)\
**Post date:** [October 1, 2017, 1:47pm UTC](https://discourse.mozilla.org/t/block-javascript-on-specific-sites/19808/1 "2017-10-01T13:47:57Z")

</div>

H Everyone, could you kindly help me in the following?

I’d like to write an extension that blocks Javascript from running on specific sites. I was thinking I can use the onBeforeRequest event for this to catch the requestBody before the page loads and then remove every script tag from it. I cannot get it working. I have the following code so far:

manifest.json:  
{  
“description”: “just some test”,  
“manifest\_version”: 2,  
“name”: “testttt”,  
“version”: “1.0”,  
“icons”: {  
“48”: “icon.svg”  
},

```
"applications": {
	"gecko": {
		"id": "testttt@mozilla.org",
		"strict_min_version": "45.0"
	}
},

"permissions": [
	"webRequest", "webRequestBlocking"
],

"background": {
  "scripts": ["background.js"]
 },

"content_scripts": [
	{
		"matches": ["*://mydomain.com/*"],
		"js": ["test.js"]
	}
]

```

}

test.js:  
document.body.style.border = “20px solid orange”;

background.js:  
browser.webRequest.onBeforeRequest.addListener(  
function(requestDetails){  
console.log(“hello”);  
alert(22);  
},  
{urls: [“[https://mydomain.com/\*](https://mydomain.com/*)”]},  
[“requestBody”, “blocking”]  
);

test.js does work, however background.js does not. There is no log of “hello” in the log panel that I open up with key Ctrl+Shift+J. There is no popup box from alert either.

Could you tell me what’s wrong and how I could achive to block scripts on specific sites writing my own WebExtension?

I’m on FF 57 beta3 but I have the same reault on 55.0.3 too.

I’m testing my webext using the about:debugging#addons page and load it there using the reload button for changes.

Thanks.

---

<div class="post-metadata">

**Author:** ![Baptistou](https://avatars.discourse-cdn.com/v4/letter/b/94ad74/32.png) [@Baptistou](https://discourse.mozilla.org/u/Baptistou)\
**Post date:** [October 1, 2017, 7:14pm UTC](https://discourse.mozilla.org/t/block-javascript-on-specific-sites/19808/2 "2017-10-01T19:14:18Z")

</div>

Hello ! A background script cannot open alert dialog box because, as its name says, this script is executed in background, not within a web page. Then, if you want to see “hello” in the console, you must load a page with the url you specified in the filter ([https://mydomain.com/](https://mydomain.com/)) else the onBeforeRequest event is not triggered.  
Moreover, you must provide the permission “\*://mydomain.com/\*” in your manifest.json and for each domain you need to receive webRequest events (Read [Permissions on MDN](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/permissions)). I suggest you to use “\<all\_urls\>” and then do some actions on each url (don’t forget “\<all\_urls\>” permission too).

---

<div class="post-metadata">

**Author:** ![log69](https://avatars.discourse-cdn.com/v4/letter/l/2acd7d/32.png) [@log69](https://discourse.mozilla.org/u/log69)\
**Post date:** [October 1, 2017, 7:48pm UTC](https://discourse.mozilla.org/t/block-javascript-on-specific-sites/19808/3 "2017-10-01T19:48:24Z")

</div>

There is this extension example:

[https://gist.github.com/Ajnasz/fb7777184200504d4e47ad892583984a](https://gist.github.com/Ajnasz/fb7777184200504d4e47ad892583984a)

How can I block Javascript on a domain from background.js and load the page without any script?

Thanks.

---

<div class="post-metadata">

**Author:** ![Baptistou](https://avatars.discourse-cdn.com/v4/letter/b/94ad74/32.png) [@Baptistou](https://discourse.mozilla.org/u/Baptistou)\
**Post date:** [October 2, 2017, 8:25am UTC](https://discourse.mozilla.org/t/block-javascript-on-specific-sites/19808/4 "2017-10-02T08:25:38Z")

</div>

You can simply block script loading by adding the filter `types: ["script"]` and return `{cancel: true}` in the callback if url matches. Here is an example :

```

browser.webRequest.onBeforeRequest.addListener(
   function(details){
      var url = details.originUrl || details.url;
      return {cancel: (url.search("your url regex here")>=0)};
   },
   {urls: ["<all_urls>"], types: ["script"]},
   [“blocking”]
);

```

You have also some examples about blocking image loading on [https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/webRequest/onBeforeRequest](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/webRequest/onBeforeRequest).

---

<div class="post-metadata">

**Author:** ![log69](https://avatars.discourse-cdn.com/v4/letter/l/2acd7d/32.png) [@log69](https://discourse.mozilla.org/u/log69)\
**Post date:** [October 2, 2017, 8:57am UTC](https://discourse.mozilla.org/t/block-javascript-on-specific-sites/19808/5 "2017-10-02T08:57:20Z")

</div>

Hi, unfortunately it doesn’t work. I’m testing the script you provided on a simple page like this:

[http://paste.ubuntu.com/25659651/](http://paste.ubuntu.com/25659651/)

I’m expecting the popup message box from alert NOT to show up, but it does. No matter how I specify or don’t specify the regex to match my domain. With all\_url or with a specific one. However if I replace the “script” with “image” then it does work as expected.

So I assume that it has something to do with the “script” parameter. Thanks.

> [Baptistou](https://discourse.mozilla.org/u/baptistou) [Baptiste Thémine](https://discourse.mozilla.org/u/baptistou)  
> October 2  
> You can simply block script loading by adding the filter `types: ["script"]` and return false in the callback if url matches. Here is an example :

```auto
> 
> browser.webRequest.onBeforeRequest.addListener( function(details){ var url = details.originUrl || details.url; return (url.search("your url regex here")>=0); }, {urls: ["<all_urls>"], types: ["script"]}, [“blocking”]
> );

```

---

<div class="post-metadata">

**Author:** ![Baptistou](https://avatars.discourse-cdn.com/v4/letter/b/94ad74/32.png) [@Baptistou](https://discourse.mozilla.org/u/Baptistou)\
**Post date:** [October 2, 2017, 11:24am UTC](https://discourse.mozilla.org/t/block-javascript-on-specific-sites/19808/6 "2017-10-02T11:24:00Z")

</div>

Ah ok I understand now. The fact is that onBeforeRequest is triggered when a script is loaded within a page with `<script type="text/javascript" src="script.js"></script>`. But what you are trying to do is to remove also inline scripts, so you need to include a content script at document start and then remove every script tags `<script></script>` and script attributes `onload="alert(42)"`, `onclick="alert(42)"`, `onhover="alert(42)"` etc.

---

<div class="post-metadata">

**Author:** ![log69](https://avatars.discourse-cdn.com/v4/letter/l/2acd7d/32.png) [@log69](https://discourse.mozilla.org/u/log69)\
**Post date:** [October 2, 2017, 11:29am UTC](https://discourse.mozilla.org/t/block-javascript-on-specific-sites/19808/7 "2017-10-02T11:29:20Z")

</div>

I’d gladly program it if I could make it work in the first place for a very simple example, but I cannot do that either. Why doesn’t the type of “script” work where “image” does?

---

<div class="post-metadata">

**Author:** ![Baptistou](https://avatars.discourse-cdn.com/v4/letter/b/94ad74/32.png) [@Baptistou](https://discourse.mozilla.org/u/Baptistou)\
**Post date:** [October 2, 2017, 11:38am UTC](https://discourse.mozilla.org/t/block-javascript-on-specific-sites/19808/8 "2017-10-02T11:38:05Z")

</div>

webRequest API concerns any web requests such as HTTP, FTP… It works with `<img src="image.png">` because of the src attribute i.e. the page triggers a GET HTTP request to get image. It works also with `<script type="text/javascript" src="script.js">` because the page triggers a GET HTTP request to get javascript file. Inline scripts are not included in this.

---

<div class="post-metadata">

**Author:** ![Baptistou](https://avatars.discourse-cdn.com/v4/letter/b/94ad74/32.png) [@Baptistou](https://discourse.mozilla.org/u/Baptistou)\
**Post date:** [October 2, 2017, 11:50am UTC](https://discourse.mozilla.org/t/block-javascript-on-specific-sites/19808/9 "2017-10-02T11:50:34Z")

</div>

You could write a simple content script like below in order to remove inline scripts :

```

//Removes script tags
document.querySelectorAll("script").forEach(function(element){
    element.textContent = "";
    //OR
    element.parentNode.removeChild(element);
});

//Removes some script attributes
document.querySelectorAll("[onload], [onclick], [onhover]").forEach(function(element){
    element.removeAttribute("onload");
    element.removeAttribute("onclick");
    element.removeAttribute("onhover");
    //...
});

```

---

<div class="post-metadata">

**Author:** ![log69](https://avatars.discourse-cdn.com/v4/letter/l/2acd7d/32.png) [@log69](https://discourse.mozilla.org/u/log69)\
**Post date:** [October 2, 2017, 2:02pm UTC](https://discourse.mozilla.org/t/block-javascript-on-specific-sites/19808/10 "2017-10-02T14:02:39Z")

</div>

Actually it doesn’t work for me with “”, the script runs and the alert box appears. This is my problem. I understand your concern about the onload etc other ways of embedding scripts, but I can’t even block the script tags.

About your other offer, do you think the content script could be run before the page’s scrips get initiated?

Thank you for your help.

---

<div class="post-metadata">

**Author:** ![log69](https://avatars.discourse-cdn.com/v4/letter/l/2acd7d/32.png) [@log69](https://discourse.mozilla.org/u/log69)\
**Post date:** [October 2, 2017, 2:11pm UTC](https://discourse.mozilla.org/t/block-javascript-on-specific-sites/19808/11 "2017-10-02T14:11:21Z")

</div>

I tested your content script but unfortunately the page’s script runs first. Do you have any idea how I could make the content script be the first to run? Thx.

> [Baptistou](https://discourse.mozilla.org/u/baptistou) [Baptiste Thémine](https://discourse.mozilla.org/u/baptistou)  
> October 2  
> You could write a simple content script like below in order to remove inline scripts :

```auto
> 
> //Removes script tags
> document.querySelectorAll("script").forEach(function(element){ element.parentNode.removeChild(element);
> }); //Removes some script attributes
> document.querySelectorAll("[onload], [onclick], [onhover]").forEach(function(element){ element.removeAttribute("onload"); element.removeAttribute("onclick"); element.removeAttribute("onhover"); //...
> });

```

---

<div class="post-metadata">

**Author:** ![NilkasG](https://avatars.discourse-cdn.com/v4/letter/n/0ea827/32.png) [@NilkasG](https://discourse.mozilla.org/u/NilkasG)\
**Post date:** [October 2, 2017, 2:13pm UTC](https://discourse.mozilla.org/t/block-javascript-on-specific-sites/19808/12 "2017-10-02T14:13:51Z")

</div>

I havn’t read all your comments above, but the easiest and most robust way to do what you described in the first post is to add a CSP header with the directive `script-src 'none'` to the headers. That will prevent all scripts from running on that page.

---

<div class="post-metadata">

**Author:** ![Baptistou](https://avatars.discourse-cdn.com/v4/letter/b/94ad74/32.png) [@Baptistou](https://discourse.mozilla.org/u/Baptistou)\
**Post date:** [October 2, 2017, 3:41pm UTC](https://discourse.mozilla.org/t/block-javascript-on-specific-sites/19808/13 "2017-10-02T15:41:49Z")

</div>

Yeah, I haven’t thought about CSP 😉 Instead of using a content script, you could use browser.webRequest.onBeforeSendHeaders and add the Content Security Policy to avoid every scripts.

```

browser.webRequest.onBeforeSendHeaders.addListener(
   function(details){
      if(details.url.search("your url regex here")>=0)
         //Here you return the modified HTTP headers with CSP
   },
   {urls: ["<all_urls>"]},
   [“blocking”, "requestHeaders"]
);

```

See examples on [https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/webRequest/onBeforeSendHeaders](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/webRequest/onBeforeSendHeaders) and [https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy).

---

<div class="post-metadata">

**Author:** ![log69](https://avatars.discourse-cdn.com/v4/letter/l/2acd7d/32.png) [@log69](https://discourse.mozilla.org/u/log69)\
**Post date:** [October 2, 2017, 7:18pm UTC](https://discourse.mozilla.org/t/block-javascript-on-specific-sites/19808/14 "2017-10-02T19:18:27Z")

</div>

As I see, CSP is for something else. If I’m correct, It is to put limit to how the WebExtension can operate and not how the loaded page.

> [Baptistou](https://discourse.mozilla.org/u/baptistou) [Baptiste Thémine](https://discourse.mozilla.org/u/baptistou)  
> October 2  
> Yeah, I haven’t thought about CSP Instead of using a content script, you could use browser.webRequest.onBeforeSendHeaders and add the Content Security Policy to avoid every scripts.

```auto
> 
> browser.webRequest.onBeforeSendHeaders.addListener( function(details){ if(details.url.search("your url regex here")>=0) //Here you return the modified HTTP headers with CSP }, {urls: ["<all_urls>"]}, [“blocking”, "requestHeaders"]
> );

```

---

<div class="post-metadata">

**Author:** ![NilkasG](https://avatars.discourse-cdn.com/v4/letter/n/0ea827/32.png) [@NilkasG](https://discourse.mozilla.org/u/NilkasG)\
**Post date:** [October 2, 2017, 7:58pm UTC](https://discourse.mozilla.org/t/block-javascript-on-specific-sites/19808/15 "2017-10-02T19:58:06Z")

</div>

A CSPs `script-src 'none'` is _exactly_ what you want. It instructs the browser to execute scripts from no source whatsoever.

You are correct though that CSPs are _meant_ to be set by website developers / admins, not browser add-ons. But it is still possible and will have the desired effect!

What you have to do in your case is **add** a header `{ name: 'Content-Security-Policy', value: "script-src 'none'", }` to the return `responseHeaders` (don’t remove / change any CSP headers).

---

<div class="post-metadata">

**Author:** ![log69](https://avatars.discourse-cdn.com/v4/letter/l/2acd7d/32.png) [@log69](https://discourse.mozilla.org/u/log69)\
**Post date:** [October 2, 2017, 8:34pm UTC](https://discourse.mozilla.org/t/block-javascript-on-specific-sites/19808/16 "2017-10-02T20:34:04Z")

</div>

Based on your directions guys, I’ve finally made it work. Instead of “onBeforeSendHeaders” I had to use “onHeadersReceived” and instead of “requestHeaders” I had to use “responseHeaders”.

Thank you so much for your efforts in helping Baptiste and finally Niklas. The working code is below:

[http://paste.ubuntu.com/25662841/](http://paste.ubuntu.com/25662841/)

browser.webRequest.onHeadersReceived.addListener(  
function(details){  
[//console.log](https://console.log)(details);  
// include the original response header too merging the two arrays here  
var rh = details.responseHeaders.concat([{name: “Content-Security-Policy”, value: “script-src ‘none’”}]);  
return {responseHeaders: rh};  
},  
{urls: ["_://local.frontfoo.com/_"]},  
[“blocking”, “responseHeaders”]  
);

---

<div class="post-metadata">

**Author:** ![NilkasG](https://avatars.discourse-cdn.com/v4/letter/n/0ea827/32.png) [@NilkasG](https://discourse.mozilla.org/u/NilkasG)\
**Post date:** [October 2, 2017, 8:43pm UTC](https://discourse.mozilla.org/t/block-javascript-on-specific-sites/19808/17 "2017-10-02T20:43:06Z")

</div>

You are welcome!

But please include the original response headers in your new headers. There can be important security stuff in there (and the `"script-src 'none'"` works either way):

```auto
browser.webRequest.onHeadersReceived.addListener(details => {
    // console.log("before web request", details);
    return { responseHeaders: [...details.responseHeaders, {name: 'Content-Security-Policy', value: "script-src 'none'", },], };
}, {urls: ["*://[mydomain.com/*](http://mydomain.com/*)"]}, ["blocking", "responseHeaders"]);

```

---

<div class="post-metadata">

**Author:** ![log69](https://avatars.discourse-cdn.com/v4/letter/l/2acd7d/32.png) [@log69](https://discourse.mozilla.org/u/log69)\
**Post date:** [October 2, 2017, 9:04pm UTC](https://discourse.mozilla.org/t/block-javascript-on-specific-sites/19808/18 "2017-10-02T21:04:06Z")

</div>

Right, thanks. So for clarification, I include the full code here again:

[http://paste.ubuntu.com/25662977/](http://paste.ubuntu.com/25662977/)

```auto
// https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
browser.webRequest.onHeadersReceived.addListener(
	function(details){
		//console.log(details);
		// include the original response header too merging the two arrays here
		var rh = details.responseHeaders.concat([{name: "Content-Security-Policy", value: "script-src 'none'"}]);
		return {responseHeaders: rh};
	},
	{urls: ["*://mydomain.com/*"]},
	["blocking", "responseHeaders"]
);
```

---

<div class="post-metadata">

**Author:** ![NilkasG](https://avatars.discourse-cdn.com/v4/letter/n/0ea827/32.png) [@NilkasG](https://discourse.mozilla.org/u/NilkasG)\
**Post date:** [October 2, 2017, 9:19pm UTC](https://discourse.mozilla.org/t/block-javascript-on-specific-sites/19808/19 "2017-10-02T21:19:06Z")

</div>

Yepp. That looks good.

---

<div class="post-metadata">

**Author:** ![Baptistou](https://avatars.discourse-cdn.com/v4/letter/b/94ad74/32.png) [@Baptistou](https://discourse.mozilla.org/u/Baptistou)\
**Post date:** [October 2, 2017, 9:24pm UTC](https://discourse.mozilla.org/t/block-javascript-on-specific-sites/19808/20 "2017-10-02T21:24:30Z")

</div>

You’re welcome ! Good job 👍
