Blocking JavaScript on a per API basis

Posted on April 14, 2015 in Dev • 2 min read

JavaScript is widely used on the Internet, and living without it can be a real pain. However, JavaScript use raises some security concerns, in particular because some JavaScript APIs can be really sensitive. Indeed, WebRTC calls can be used to detect your real IP even the private one, on your network, JavaScript can interact with the clipboard, … Clipboard API can be blocked in about:config in Firefox for instance, but that is not the case for every such API. Hence, I wanted to have a look at what can be done to prevent the use of such sensitive APIs.

Plus, in my opinion, NoScript is not really usable, as it blocks way too much things and you end up clicking on “Allow this website” on basically every website to be able to use them. Then, the security benefit from using NoScript gets very low.

I found a way (most a PoC than a real usable thing) to selectively block some APIs, through NoScript surrogate scripts and Object.defineProperty. For instance, to block the WebRTC PoC previously linked, one can add

noscript.surrogate.test.replacement = Object.defineProperty(window, 'mozRTCPeerConnection', {get: function() { console.log('rtc'); return function() {}; }, set: function() {}});
noscript.surrogate.test.sources = @^(?!chrome:)[0-9A-Za-z-]+

in his about:config.

The Object.defineProperty syntax is a bit weird in this case, as I have to return a function in both the getter and the setter. I did not find any specific reason for doing it, and this is the only way I found to block this property. If you have any idea, please let me know, as I do not like to not understand this problem, and do not like much having something that could potentially break at any time. For the full discussion about this NoScript surrogate script, please refer to the NoScript forum.

Next steps would be to implement it as a standalone plugin, in order not to use NoScript and have a more user-friendly user interface (list all the sensitive APIs, one-click to enable / disable them and reload the page…), or better implement it as a Privoxy external filter so that this protection will not be in the browser itself, but in a different layer, to increase security. I will work on it as soon as I find some free time, but feel free to do something and share in the mean time if you are interested in the topic!