Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve 'prevent-fetch' — add 'cors' responseType #394

Closed
Yuki2718 opened this issue Jan 3, 2024 · 8 comments
Closed

Improve 'prevent-fetch' — add 'cors' responseType #394

Yuki2718 opened this issue Jan 3, 2024 · 8 comments

Comments

@Yuki2718
Copy link

Yuki2718 commented Jan 3, 2024

prevent-fetch has to set responseType cors to fix AdguardTeam/AdguardFilters#153796. I confirmed it works on uBO 1.54.1 rc2 gorhill/uBlock@e1ae17e However, on AG extension 4.2.241 rekidai-info.github.io#%#//scriptlet('prevent-fetch', 'pagead2.googlesyndication.com') doesn't even prevent the fetch request on my end.

@adguard-bot adguard-bot assigned slavaleleka and unassigned maximtop Mar 22, 2024
@adguard-bot adguard-bot changed the title Improve prevent-fetch scriptlet Improve prevent-fetch — add 'cors' responseType Mar 22, 2024
@adguard-bot adguard-bot changed the title Improve prevent-fetch — add 'cors' responseType Improve 'prevent-fetch' — add 'cors' responseType Mar 22, 2024
adguard pushed a commit that referenced this issue Mar 27, 2024
Squashed commit of the following:

commit 5402872
Author: Adam Wróblewski <adam@adguard.com>
Date:   Wed Mar 27 08:37:24 2024 +0100

    Change to multiline comment

commit 940f0a0
Author: Adam Wróblewski <adam@adguard.com>
Date:   Tue Mar 26 17:37:38 2024 +0100

    Change Response to Request
    Return undefined instead of empty string

commit f318db9
Author: Adam Wróblewski <adam@adguard.com>
Date:   Tue Mar 26 12:37:09 2024 +0100

    Add a better comment

commit 4cda1e0
Author: Adam Wróblewski <adam@adguard.com>
Date:   Tue Mar 26 11:32:40 2024 +0100

    Attempt to fix tests

commit d200317
Author: Adam Wróblewski <adam@adguard.com>
Date:   Tue Mar 26 10:39:03 2024 +0100

    Update changelog

commit 19bb68a
Author: Adam Wróblewski <adam@adguard.com>
Date:   Tue Mar 26 10:23:42 2024 +0100

    Improve prevent-fetch
@Yuki2718
Copy link
Author

Yuki2718 commented Apr 1, 2024

Here https://h5games.success-corp.co.jp/game/play/su-300-mss success-corp.co.jp#%#//scriptlet('prevent-fetch', 'pagead2.googlesyndication.com') doesn't work on extension 4.3.35. It works on uBO though.

@slavaleleka
Copy link
Contributor

it is not included into the extension 4.3.35

@Yuki2718
Copy link
Author

Yuki2718 commented Apr 1, 2024

I'm not sure if this is the same issue. The rule doesn't prevent fetch request and let anti-adb to appear after you click GAME START. Same on beta too.

Screenshot

anti-adb

@AdamWr
Copy link
Member

AdamWr commented Apr 1, 2024

This is a scriptlet with latest changes converted to JavaScript rule:

rekidai-info.github.io,success-corp.co.jp#%#!function(e,t){function r(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"emptyObj",i=arguments.length>3?arguments[3]:void 0;if("undefined"!=typeof fetch&&"undefined"!=typeof Proxy&&"undefined"!=typeof Response){var u,s=Request.prototype.clone;if(""===r||"emptyObj"===r)u="{}";else if("emptyArr"===r)u="[]";else{if("emptyStr"!==r)return void c(e,"Invalid responseBody parameter: '".concat(r,"'"));u=""}if(!(void 0!==i)||function(e){return["basic","cors","opaque"].includes(e)}(i)){var l={apply:async function(r,l,f){var d,v=function(e,t){var r,n,o={},c=e[0];if(c instanceof Request){var a=t.call(c),i=(u=a,s=["url","method","headers","body","credentials","cache","redirect","referrer","referrerPolicy","integrity","keepalive","signal","mode"].map((function(e){return[e,u[e]]})),Object.fromEntries(s));r=i.url,n=i}else r=c,n=e[1];var u,s;if(o.url=r,n instanceof Object){Object.keys(n).forEach((function(e){o[e]=n[e]}))}return o}(f,s);if(void 0===t)return c(e,"fetch( ".concat(o(v)," )"),!0),n(e),Reflect.apply(r,l,f);if(d=function(e,t,r){if(""===t||"*"===t)return!0;var n,o=(a=t,i=" ",u=":",s=function(e){return["url","method","headers","body","credentials","cache","redirect","referrer","referrerPolicy","integrity","keepalive","signal","mode"].includes(e)},l={},a.split(i).forEach((function(e){var t=e.indexOf(u),r=e.slice(0,t);if(s(r)){var n=e.slice(t+1);l[r]=n}else l.url=e})),l);var a,i,u,s,l;if(d=o,Object.values(d).every((function(e){return function(e){var t,r="/",n=function(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}(e);e[0]===r&&e[e.length-1]===r&&(n=e.slice(1,-1));try{t=new RegExp(n),t=!0}catch(e){t=!1}return t}(e)}))){var f=function(e){var t={},r=Object.keys(e);return r.forEach((function(r){t[r]=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=".?",r="/";if(""===e)return new RegExp(t);var n=e.lastIndexOf(r),o=e.substring(n+1),c=e.substring(0,n+1),a=function(e){if(!e)return!1;try{return new RegExp("",e),!0}catch(e){return!1}},i=(u=c,s=o,u.startsWith(r)&&u.endsWith(r)&&!u.endsWith("\\/")&&a(s)?s:"");var u,s;if(e.startsWith(r)&&e.endsWith(r)||i){return new RegExp((i?c:e).slice(1,-1),i)}var l=e.replace(/\\'/g,"'").replace(/\\"/g,'"').replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(l)}(e[r])})),t}(o);n=Object.keys(f).every((function(e){var t=f[e],n=r[e];return Object.prototype.hasOwnProperty.call(r,e)&&"string"==typeof n&&(null==t?void 0:t.test(n))}))}else c(e,"Invalid parameter: ".concat(t)),n=!1;var d;return n}(e,t,v),d){var p;n(e);try{p=i||function(t){try{var r=t.mode;if(void 0===r||"cors"===r||"no-cors"===r)return new URL(t.url).origin===document.location.origin?"basic":"no-cors"===r?"opaque":"cors"}catch(t){c(e,"Could not determine response type: ".concat(t))}}(v);var y=await Reflect.apply(r,l,f);return y.ok?function(e){var t,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{body:"{}"},n={};null==e||null===(t=e.headers)||void 0===t||t.forEach((function(e,t){n[t]=e}));var o=new Response(r.body,{status:e.status,statusText:e.statusText,headers:n});return Object.defineProperties(o,{url:{value:e.url},type:{value:r.type||e.type}}),o}(y,{body:u,type:p}):a(u,v.url,p)}catch(e){return a(u,v.url,p)}}return Reflect.apply(r,l,f)}};fetch=new Proxy(fetch,l)}else c(e,"Invalid responseType parameter: '".concat(i,"'"))}}function n(e){if(!0===e.verbose){try{var t=console.log.bind(console),r=console.trace.bind(console),n=e.ruleText||"";if(e.domainName){var o,c="#%#//",a="##+js";e.ruleText.includes(c)?o=e.ruleText.indexOf(c):e.ruleText.includes(a)&&(o=e.ruleText.indexOf(a));var i=e.ruleText.slice(o);n="".concat(e.domainName).concat(i)}t("".concat(n," trace start")),r&&r(),t("".concat(n," trace end"))}catch(e){}"function"==typeof window.__debug&&window.__debug(e)}}function o(e){return e&&"object"==typeof e?function(e){return 0===Object.keys(e).length&&!e.prototype}(e)?"{}":Object.entries(e).map((function(e){var t=e[0],r=e[1],n=r;return r instanceof Object&&(n="{ ".concat(o(r)," }")),"".concat(t,':"').concat(n,'"')})).join(" "):String(e)}function c(e,t){var r=arguments.length>2&&void 0!==arguments[2]&&arguments[2],n=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],o=e.name,c=e.verbose;if(r||c){var a=console.log;n?a("".concat(o,": ").concat(t)):a("".concat(o,":"),t)}}function a(){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"basic";if("undefined"!=typeof Response){var r=new Response(arguments.length>0&&void 0!==arguments[0]?arguments[0]:"{}",{status:200,statusText:"OK"});return"opaque"===t?Object.defineProperties(r,{body:{value:null},status:{value:0},statusText:{value:""},url:{value:""},type:{value:t}}):Object.defineProperties(r,{url:{value:e},type:{value:t}}),Promise.resolve(r)}}var i=t?[].concat(e).concat(t):[e];try{r.apply(this,i)}catch(e){console.log(e)}}({name:"prevent-fetch",args:["adsbygoogle","emptyStr"],verbose:!0},["adsbygoogle","emptyStr"]);

and it seems that it works fine on my end.

Please note that in network panel, a network request still will be visible as blocked if it's blocked by extension/app (or unblocked if there is no blocking rule), that's how it works in current implementation and it's not an issue.


Regarding rekidai-info.github.io, in addition to prevent-fetch (or script above) this rule is also needed:

rekidai-info.github.io#%#window.adsbygoogle = { loaded: true, push: (a)=>{if(!a) { throw new Error('called with no parameters'); }} };

@Yuki2718
Copy link
Author

Yuki2718 commented Apr 1, 2024

Confirmed the JS rule works. Yeah, rekidai-info.github.io script is updated.

@Yuki2718
Copy link
Author

Current code of rekidai-info.github.io

async function ti() {
    try {
        const y = "https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?_=" + Date.now()
          , t = await fetch(y, {
            cache: "no-store",
            redirect: "error"
        });
        if (t.type !== "cors" || t.url !== y || t.body == null || t.redirected || t.status !== 200)
            throw Error("Ad blocker detected.")
    } catch {
        throw Error("Ad blocker detected.")
    }
    try {
        const y = "https://pagead2.googlesyndication.com/a.js?_=" + Date.now()
          , t = await fetch(y, {
            cache: "no-store"
        });
        if (t.type !== "cors" || t.url !== y || t.body == null || t.redirected || t.status !== 200)
            throw Error("Ad blocker detected.")
    } catch (y) {
        if (y.toString().indexOf("Ad blocker detected.") >= 0)
            throw y
    }
    if (window.adsbygoogle == null || window.adsbygoogle.push == null || typeof window.adsbygoogle.push != "function")
        throw Error("Ad blocker detected.");
    (function() {
        let y = !1;
        if (["p", "q"].forEach(t=>{
            Array(26).fill(1).map((r,n)=>String.fromCharCode(65 + n) + t).concat(Array(26).fill(1).map((r,n)=>String.fromCharCode(97 + n) + t)).forEach(r=>{
                if (window[r] != null || window.adsbygoogle[r] != null)
                    throw Error("Ad blocker detected.");
                if (!y) {
                    let n = window.adsbygoogle.push.toString();
                    RegExp(`^[a-z]=>\\{${r}\\([a-z],[a-z],[a-z]\\)\\}$`, "g").test(n) && (y = !0)
                }
            }
            )
        }
        ),
        !y)
            throw Error("Ad blocker detected.")
    }
    )();
    try {
        window.adsbygoogle.push()
    } catch {
        try {
            window.adsbygoogle.push(!0)
        } catch {
            const r = await fetch("rekidai.min.json", {
                method: "GET",
                mode: "same-origin",
                cache: "no-cache",
                credentials: "same-origin"
            })
              , n = await r.json();
            if (r.ok)
                return n.filter(f=>f.music !== "罪過の聖堂");
            throw Error("Error Loading Rekidai Data.")
        }
    }
    throw Error("Ad blocker detected.")
}

for uBO fixed with rekidai-info.github.io##+js(prevent-fetch, /a(dsbygoogle)?\.js/, war:googlesyndication_adsbygoogle.js, '{ "type": "cors" }') which I don't think AG has the counterpart. war was added by gorhill/uBlock@6aeab2a

@AdamWr
Copy link
Member

AdamWr commented Jul 16, 2024

I think that the problem is that website overrides Object.defineProperties which is used by prevent-fetch.
These rules:

@@||pagead2.googlesyndication.com^$xmlhttprequest,domain=rekidai-info.github.io,badfilter
@@||pagead2.googlesyndication.com/pagead/js/adsbygoogle.js$domain=rekidai-info.github.io,badfilter
rekidai-info.github.io#%#//scriptlet('prevent-fetch', 'googlesyndication')
rekidai-info.github.io#%#(()=>{const k={};const f=[];const qq=function(m,k,f){if(!m||m===!0)throw new Error("called with no parameters");};window.adsbygoogle={loaded:true,push:m=>{qq(m,k,f)}}})();
rekidai-info.github.io#%#!function(){const e={set:(e,t,n,o)=>!(!t||"defineProperties"!==t)||Reflect.set(e,t,n,o)};window.Object=new Proxy(window.Object,e)}();

seem to work fine.

@Yuki2718
Copy link
Author

Confirmed, working!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants