6

Ad blockers block all new tabs opened if the content is a blob. I assume there's some reason behind this, but I can't figure it out. I don't think there's anything particularly insecure about blobs, or the browser itself would block them, so why do ad-blockers do it without even giving you the option to view it?

Here's a fiddle since it doesn't work right using Stack Overflows code snippet:

https://jsfiddle.net/Pharylon/dqjtha81/32/

const myString = "Hello World!";
const blob = new Blob([myString], {
  type: 'text/plain'
});
const fileURL = URL.createObjectURL(blob);
const myLink = document.getElementById("blob-link");
myLink.setAttribute("href", fileURL);
myLink.style.display = "block";

document.getElementById("my-div").innerText = myLink;
<p>
  The following won't open if you have an adblocker:
</p>

<a style="display: none" id="blob-link" href="" target="_blank">Click Me!</a>

<p>
  But you can manually copy/paste this and it'll work:
</p>

<div id="my-div"></div>

https://jsfiddle.net/Pharylon/dqjtha81/32/

Again, my question is why blockers do this. Thanks!

Barmar
  • 741,623
  • 53
  • 500
  • 612
Pharylon
  • 9,796
  • 3
  • 35
  • 59
  • guessing someone is using blobs to get around ad filters.... – epascarello Jul 10 '18 at 19:34
  • 2
    I guess this is so that advertisers can't get around the ad blocker by using Javascript that displays a blob. – Barmar Jul 10 '18 at 19:34
  • I have this vague memory of a recent question that involved browsers moving to block data URLs in top-level windows generally. – Pointy Jul 10 '18 at 19:35
  • @epascarello But if the link is something that's not a blob, they at least give you the option to view them. So why not allow that with blobs? – Pharylon Jul 10 '18 at 19:35
  • 1
    @Pointy Blobs and Data URLs are different things. – Pharylon Jul 10 '18 at 19:37
  • 1
    @Pharylon You act like people of stackoverflow have any control over it... We can only assume.... – epascarello Jul 10 '18 at 19:39
  • @epascarello I'm just figuring someone knows why. You said you were guessing they were used to get around filters, I'm pointing out that the blob URL still contains the host address, so they wouldn't get around filters at all. – Pharylon Jul 10 '18 at 19:40
  • 1
    The rules used by adblockers border on complete voodoo. – tadman Jul 10 '18 at 19:40
  • @Pharylon sure but if somebody thinks a data URL is bad it seems like a blob URL would fall under the same scrutiny. – Pointy Jul 10 '18 at 19:44
  • Someone wrote a rule that blocks it. The person that wrote the generic rule knows a reason why. Just like how one day all my content on sites disappeared because they added a filter for a class name that had nothing to do with ads. Why they did it? Guessing someone used it for ads and they blocked it causing issues for anyone else. Rules are nothing more than pattern matching, so something in it matched a pattern they saw and they block it. I am sure there are plenty of complaints on the adblock forums. – epascarello Jul 10 '18 at 19:45

1 Answers1

3

That is the explanation in easylist.txt, a popular blocklist:

! Used with many websites to generate multiple popups
|blob:$popup
|data:text$popup
|dddata:text$popup

This is also referred to in the output of uBlock Origin, which uses easylist (among others):

enter image description here


For a concrete example, where blobs where used in combination with WebSockets to bypass all adblockers at that time, see the code snippet from the uBlock Origin issue (reformatted only):

AdDelivery.prototype.createWW = function() {
    var b = "self.onmessage=function(a){
    self.debug = " + this.debug + ';self.wsurl="
    ' + this.websocketURL + '
    ";self.initWS=

    function(b) {
        self.ws = new WebSocket(b);
        self.ws.onerror = function(c) {
            self.log(
                "Websocket error: " + c);
            postMessage(null)
        };
        self.ws.onopen = function(c) {
            self.log("Websocket connected")
        };
        self.ws.onmessage = function(c) {
            self.log("Websocket received msg.");
            postMessage(c.data)
        }
    };
    self.requestAds = function(b) {
        if (self.ws.readyState !== 1) {
            setTimeout(function() {
                self.log("Waiting for connection");
                self.requestAds(b)
            }, 100)
        } else {
            ws.send(b)
        }
    };
    self.log = function(b) {
        if (self.debug) {
            console.log(b)
        }
    };
    if (!self.ws) {
        self.initWS(self.wsurl);
        self.log("Initializing websocket")
    } else {
        self.log("Websocket already connected")
    }
    self.requestAds(a.data)
};
';
this.blob = new Blob([b], { type: "application/javascript" });
this.ww = new Worker(URL.createObjectURL(this.blob)); return };
Philipp Claßen
  • 41,306
  • 31
  • 146
  • 239