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-xhr' — add missed events #414

Closed
AdamWr opened this issue Apr 2, 2024 · 0 comments
Closed

Improve 'prevent-xhr' — add missed events #414

AdamWr opened this issue Apr 2, 2024 · 0 comments

Comments

@AdamWr
Copy link
Member

AdamWr commented Apr 2, 2024

Related to AdguardTeam/AdguardFilters#175034 and AdguardTeam/AdguardFilters#174876

These websites use onreadystatechange to check if 4 events were fired and #%#//scriptlet('prevent-xhr', 'pagead2.googlesyndication.com') doesn't work because currently only 2 events are invoked.

Steps to reproduce:

  1. Add this rule:
example.org#%#//scriptlet('prevent-xhr', 'pagead2.googlesyndication.com')
  1. Go to - https://example.org/
  2. In browser console run:
(() => {
  const checkDection = (detected) => {
    if (detected) {
      alert('AdBlocker detected');
      return;
    }

    const allEventsPassed = xhrEvents.every((state) => state);
    if (!allEventsPassed) {
      alert('AdBlocker detected');
      return;
    }
    // No AdBlocker detected, do something
    console.log('No AdBlocker detected');
  };

  const url = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
  const xhrEvents = [false, false, false, false];
  const xhr = new XMLHttpRequest();

  xhr.onreadystatechange = function () {
    xhrEvents[xhr.readyState - 1] = true;
  
    if (xhr.readyState === 4) {
      checkDection();
    }
  };

  try {
    xhr.open("GET", url, true);
    xhr.send();
  } catch (ex) {
    checkDection(true);
  }
})();

Probably changing this part:

forgedRequest.addEventListener('readystatechange', () => {
if (forgedRequest.readyState !== 4) {
return;
}
const {
readyState,
responseURL,
responseXML,
statusText,
} = forgedRequest;
// Mock response object
Object.defineProperties(thisArg, {
// original values
readyState: { value: readyState, writable: false },
statusText: { value: statusText, writable: false },
// If the request is blocked, responseURL is an empty string
responseURL: { value: responseURL || thisArg.xhrData.url, writable: false },
responseXML: { value: responseXML, writable: false },
// modified values
status: { value: 200, writable: false },
response: { value: modifiedResponse, writable: false },
responseText: { value: modifiedResponseText, writable: false },
});
// Mock events
setTimeout(() => {
const stateEvent = new Event('readystatechange');
thisArg.dispatchEvent(stateEvent);
const loadEvent = new Event('load');
thisArg.dispatchEvent(loadEvent);
const loadEndEvent = new Event('loadend');
thisArg.dispatchEvent(loadEndEvent);
}, 1);
hit(source);
});

to something like:

Code:
forgedRequest.addEventListener('readystatechange', () => {
  Object.defineProperty(thisArg, 'readyState', { value: forgedRequest.readyState, writable: true }); // it seems that - thisArg.readyState = forgedRequest.readyState - doesn't work, but maybe I didn't check it correctly
  const stateEvent = new Event("readystatechange");
  switch (forgedRequest.readyState) {
    case 1:
      thisArg.dispatchEvent(stateEvent);
      const loadStartEvent = new Event("loadstart");
      thisArg.dispatchEvent(loadStartEvent);
      break;
    case 2:
      thisArg.dispatchEvent(stateEvent);
      const progressEvent = new Event("progress");
      thisArg.dispatchEvent(progressEvent);
      break;
    case 3:
      thisArg.dispatchEvent(stateEvent);
      const loadEvent = new Event("load");
      thisArg.dispatchEvent(loadEvent);
      break;
    case 4:
      const {
        readyState,
        responseURL,
        responseXML,
        statusText
      } = forgedRequest;

      // Mock response object
      Object.defineProperties(thisArg, {
        // original values
        readyState: {
          value: readyState,
          writable: false
        },
        statusText: {
          value: statusText,
          writable: false
        },
        // If the request is blocked, responseURL is an empty string
        responseURL: {
          value: responseURL || thisArg.xhrData.url,
          writable: false
        },
        responseXML: {
          value: responseXML,
          writable: false
        },
        // modified values
        status: {
          value: 200,
          writable: false
        },
        response: {
          value: modifiedResponse,
          writable: false
        },
        responseText: {
          value: modifiedResponseText,
          writable: false
        }
      });

      // Mock events
      setTimeout(() => {
        thisArg.dispatchEvent(stateEvent);
        const loadEndEvent = new Event('loadend');
        thisArg.dispatchEvent(loadEndEvent);
      }, 1);
  }
  hit(source);
});

should fixes it.

@slavaleleka slavaleleka added the enhancement Improvement of existent feature label Oct 4, 2024
@adguard-bot adguard-bot assigned jellizaveta and unassigned maximtop Oct 4, 2024
@adguard-bot adguard-bot changed the title Improve prevent-xhr — add missed events Improve 'prevent-xhr' — add missed events Oct 4, 2024
adguard pushed a commit that referenced this issue Oct 10, 2024
Squashed commit of the following:

commit 1656521
Merge: dcbf829 7e1c53d
Author: jellizaveta <[email protected]>
Date:   Thu Oct 10 12:44:16 2024 +0300

    merge master

commit dcbf829
Author: jellizaveta <[email protected]>
Date:   Wed Oct 9 14:49:23 2024 +0300

    update compatibility-table

commit 2f927e7
Author: jellizaveta <[email protected]>
Date:   Wed Oct 9 14:42:11 2024 +0300

    Load and loadend event simulation

commit 959076c
Author: jellizaveta <[email protected]>
Date:   Wed Oct 9 12:06:35 2024 +0300

    update comments

commit 0609abc
Author: jellizaveta <[email protected]>
Date:   Tue Oct 8 19:26:20 2024 +0300

    add events

commit ffda310
Author: jellizaveta <[email protected]>
Date:   Tue Oct 8 17:45:34 2024 +0300

    Fix Event

commit 8d09da3
Author: jellizaveta <[email protected]>
Date:   Tue Oct 8 17:00:06 2024 +0300

    speed up the definition of xhr.status

commit 236aa85
Author: jellizaveta <[email protected]>
Date:   Mon Oct 7 20:50:56 2024 +0300

    remove redundant comments

commit f63a197
Author: jellizaveta <[email protected]>
Date:   Mon Oct 7 20:33:48 2024 +0300

    Update changelog

commit 5820dce
Merge: 62d9c60 90eaf3d
Author: jellizaveta <[email protected]>
Date:   Mon Oct 7 20:32:52 2024 +0300

    Merge branch 'master' into fix/AG-31632

commit 62d9c60
Author: jellizaveta <[email protected]>
Date:   Mon Oct 7 20:27:42 2024 +0300

    AG-31632 Improve 'prevent-xhr' — add missed events. #414
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