Improve `prevent-xhr` — blob response, randomized responseText with given length
- [x] Blob response
- [x] Improve randomize
responseTextfunction - https://github.com/AdguardTeam/Scriptlets/issues/206#issuecomment-1158621281 (second part of the comment)
There is a website - https://www.kijk.nl/programmas/uefa-conference-league/FMLIrjHkfhXMWv which detects ad blockers if some xmlhttprequest are blocked.
Unfortunately, in this case, rule like this:
kijk.nl#%#//scriptlet('prevent-xhr', '/prebid/ad.gif')
breaks video player.
Screenshot

Anti adblock script:
case 0:
(n = document.getElementById(p)) && n.remove(),
(r = document.createElement("img")).setAttribute("id", p),
r.setAttribute("class", "pub_300x250 pub_300x250m pub_728x90 text-ad textAd text_ad text_ads text-ads text-ad-links ad-text adSense adBlock adContent adBanner"),
r.setAttribute("style", "width: 1px !important; height: 1px !important; position: absolute !important;"),
a = "".concat(c.a.getFeatureVariable(l.r.ADBLOCK_DETECTION, "baitURL") || "https://static.kijk.nl/prebid/ad.gif", "?user=").concat(f, "&slot=pre&ad-sense=1&adId=").concat(Date.now()),
(i = new XMLHttpRequest).onreadystatechange = function() {
if (4 === this.readyState && 200 === this.status) {
var e = window.URL || window.webkitURL;
return r.setAttribute("src", "function" === typeof(null === e || void 0 === e ? void 0 : e.createObjectURL) ? e.createObjectURL(this.response) : a),
document.body.appendChild(r),
t(!1)
}
if (4 === this.readyState)
return t(!0)
},
i.open("GET", a),
i.responseType = "blob",
i.send();
case 12:
case "end":
return e.stop()
}
As far as I understand, it's due to this part:
e.createObjectURL(this.response)
Maybe we could check XMLHttpRequest.responseType and if it's a blob, then we could return something like new Blob(), as value here:
https://github.com/AdguardTeam/Scriptlets/blob/9d4d2292aa249fbaf1e59a418dfffb7669088267/src/scriptlets/prevent-xhr.js#L131
Very good idea!
I think that it would be good idea to add something similar to prevent-fetch scriptlet.
For example, this website - https://il.investing.com/indices/nasdaq-composite is checking Response.type if it's equal to opaque, and if it's not then it display adblock notice.
Example rules:
investing.com#%#//scriptlet('prevent-fetch', 'pagead2.googlesyndication.com')
investing.com#%#//scriptlet('prevent-fetch', 'yandex.ru/ads/system/context.js')
Adding something like (as an additional option):
Object.defineProperty(response, 'type', { value: 'opaque', writable: false });
should fixes this issue (similar like in this case - https://github.com/AdguardTeam/Scriptlets/issues/216)
One more thing regarding prevent-xhr, related to this - https://github.com/AdguardTeam/Scriptlets/issues/199#issuecomment-1063271758
This website - https://streamingcommunity.press/watch/5190?e=37368 is checking length of responseText, something like:
a.get("https://thaudray.com/5/3523301")
.then(function (e) {
e.data.length < 2e4 && (t.adBlock = !0), s();
})
.catch(function (e) {
console.log(e), o.can("bypass.ads") ? s() : (t.adBlock = !0);
});
e.data.length < 2e4
Could randomize argument be improved, so we could manually set range of length of the responseText?