When the developers at BugReplay (an online service for recording browser videos alongside the JavaScript console) were evaluating different methods for capturing and analyzing network traffic in Chrome, they looked into the chrome.webRequest API. According to the documentation this API allowed analyzing and observing traffic and, best of all, intercepting, blocking, or modifying requests. But after investigating its behavior a little, they realized it had a major drawback: it did not allow analyzing WebSocket traffic.
They couldn't find anything in the documentation to suggest they were wrong, but what they did find was a 2012 bug report titled "chrome.webRequest.onBeforeRequest doesn't intercept WebSocket requests". In this report, users complained that this inability to block WebSockets would allow websites to ignore ad blockers (AdBlock and similar).
Ad blockers in Chrome use the webRequest API to block the loading of scripts and images based on certain rules that they update frequently. If WebSockets could not be blocked in any way, nothing would prevent a website from sending content inside a WebSocket to be displayed using JavaScript on the client.
Pornhub Bypasses Ad Blockers with WebSockets#
In August 2016, an employee of MindGeek (the company that owns Pornhub.com) started making arguments against adding WebSocket blocking to Chrome's API. If we visited MindGeek sites (Pornhub and other affiliated sites) we could see advertising provided by their own network (Traffic Junky) even with the ad blocker activated, so all indications were that they were aware of this small "loophole" in the API.

In the image you can see how Pornhub warns the user that they are using an ad blocker. However, the ad is still visible despite the blocker being active.
How They Do It#
When we visit Pornhub, the site tries to detect if we are using an ad blocker. If it detects one, it opens a WebSocket connection that acts as a backup mechanism for showing ads. If we watch this video we can see the requests blocked by AdBlock and marked as failed traffic with the error net::ERR_BLOCKED_BY_CLIENT. This error is what Chrome reports when a resource is blocked while loading.
To use the WebSocket to serve ads, Pornhub creates a WebSocket with information about the ad it is going to load. The information it contains is:
- Where the ad will be placed (zone_id).
- Type of ad, since it can be a video or an image (media_type).
- If it is an image, its base64 encoding using the data URI scheme.
- If it is an image, the image type (normally "image/jpeg").
Ad blockers work primarily with the webRequest API, so building and transmitting the ad using WebSockets is a very clever way to bypass this block.
Possible Solutions#
In October of that same year, someone wrote a patch adding the ability for WebSockets to be blocked by the webRequest API, although it had not yet been added to stable versions of Chrome. Blockers like Adblock Plus and uBlock Origin had already created some patches to account for this problem.
Adblock Plus, for example, creates a test request before WebSocket messages are sent/received. The extension recognizes these test requests as "representatives" of the WebSocket message. This way it can intercept them and block the WebSocket if any of them should be blocked. uBlock Origin, however, uses a CSP directive for this purpose.
Now it remains to be seen whether the Chrome development team approves the community patch so that its webRequest API is capable of blocking WebSockets.
