Opened on 09/18/2018 at 01:07:23 PM

Closed on 10/02/2018 at 12:09:00 PM

Last modified on 05/27/2019 at 04:07:18 PM

#6964 closed change (fixed)

Implement dir-string snippet

Reported by: mjethani Assignee: mjethani
Priority: P3 Milestone:
Module: Core Keywords: circumvention
Cc: hfiguiere, Ross, amrmak, BrentM, laura Blocked By:
Blocking: Platform: Unknown / Cross platform
Ready: yes Confidential: no
Tester: Ross Verified working: yes
Review URL(s):

https://codereview.adblockplus.org/29884562/

Description (last modified by mjethani)

Background

Some websites use a technique to detect that Chrome's DevTools is open and hide all their ads to prevent filter list authors from examining them and writing any filters for them.

The specific technique used is as follows:

let re = /foo/;
let n = 0;

re.toString = function()
{
  if (++n > 1)
  {
    // Detected: DevTools is open!
  }

  return "";
};

console.dir(re);

On Chrome, if DevTools is open, the toString method of the RegExp object re here is called twice; otherwise it's called only once.

This can be used to trick the site into believing that DevTools is open and hiding the ads itself, by wrapping the dir function of the console object and always calling the toString method of the first argument. Additionally, the snippet could take a parameter to call the toString method n times. This would allow it to work on Firefox as well, which doesn't call the toString method at all if DevTools is closed and calls it once if it's open.

What to change

Write a snippet with the following signature:

function dirString(times = "1")

It should wrap the console.dir API and call the first argument's toString method n times before forwarding the call to the original function.

Hints for testers

You could use the follow HTML document to test this snippet on Chrome:

<!-- test.html -->
<div>
  Lorem ipsum dolor sit amet, consectetur
  adipiscing elit, sed do eiusmod tempor
  incididunt ut labore et dolore magna aliqua.
</div>
<div class="atsy2tvyg9">Ad</div>
<script>
  setTimeout(() =>
  {
    let re = /foo/;
    let n = 0;

    re.toString = function()
    {
      if (++n > 1)
      {
        for (let element of document.getElementsByClassName("atsy2tvyg9"))
          element.parentElement.removeChild(element);

        delete re.toString;
      }

      return "";
    };

    console.dir(re);
  },
  500);
</script>

Follow these steps:

  1. Load the document: the element "Ad" will be visible.
  2. Open the DevTools console for the tab: now the element "Ad" will be hidden.
  3. Close the DevTools console, add the filter #$#dir-string, and reload the document: now the element "Ad" will be hidden even when DevTools is closed.

On Firefox, change ++n > 1 to ++n > 0 in the HTML document's source and try the same steps.

Attachments (0)

Change History (17)

comment:1 Changed on 09/18/2018 at 01:13:40 PM by mjethani

  • Cc hfiguiere Ross added

comment:2 Changed on 09/18/2018 at 01:31:04 PM by mjethani

  • Review URL(s) modified (diff)
  • Status changed from new to reviewing

comment:3 Changed on 09/18/2018 at 01:31:12 PM by mjethani

  • Owner set to mjethani

comment:4 Changed on 09/18/2018 at 01:31:21 PM by mjethani

  • Keywords circumvention added

comment:5 Changed on 09/18/2018 at 03:01:36 PM by amrmak

  • Cc amrmak added

comment:6 Changed on 09/21/2018 at 08:50:47 AM by abpbot

A commit referencing this issue has landed:
Issue 6964 - Implement dir-string snippet

comment:7 Changed on 09/24/2018 at 05:30:53 PM by abpbot

A commit referencing this issue has landed:
Issue 6964 - Implement dir-string snippet

comment:8 Changed on 09/24/2018 at 05:40:50 PM by mjethani

  • Description modified (diff)

comment:9 Changed on 10/02/2018 at 12:06:27 PM by mjethani

  • Description modified (diff)

comment:10 Changed on 10/02/2018 at 12:09:00 PM by mjethani

  • Description modified (diff)
  • Resolution set to fixed
  • Status changed from reviewing to closed

comment:11 Changed on 10/02/2018 at 12:09:23 PM by mjethani

  • Ready set

comment:12 Changed on 10/24/2018 at 08:53:02 AM by Ross

This seems to work in the latest browser versions but not in min supported versions. I'm guessing the detect devtools method does not work in past browser versions?

Does the following behaviour sound correct?

Chrome 69: Ad hidden when devtools are opened. Ad hidden with snippet (devtools closed)
Chrome 49: Ad not hidden when devtools are opened. Ad not hidden with snippet (devtools closed)
Firefox 62: Ad hidden when devtools->console is focused. Ad hidden with snippet (devtools closed)
Firefox 51: Ad not hidden with devtools open. Ad hidden with snippet (devtools closed)
Opera: Same as Chrome.

ABP 3.3.2.2175
Firefox 62 / 51 / Windows 10
Chrome 69 / 49 / Windows 10
Opera 56 / 36 / Windows 10

comment:13 Changed on 10/24/2018 at 03:05:48 PM by mjethani

It's possible that the DevTools detection technique described in the ticket doesn't work on older versions of the browsers. The console.dir API is experimental. If the ad is not hidden when DevTools is open, I would not expect it to be hidden with the snippet (since this is what the snippet simulates).

Last edited on 10/24/2018 at 03:06:06 PM by mjethani

comment:14 Changed on 10/25/2018 at 09:38:27 AM by Ross

  • Tester changed from Unknown to Ross
  • Verified working set

Ah okay. That makes sense. This looks fine then.

ABP 3.3.2.2175
Firefox 62 / 51 / Windows 10
Chrome 69 / 49 / Windows 10
Opera 56 / 36 / Windows 10

comment:15 Changed on 12/05/2018 at 11:59:27 PM by sebastian

  • Cc BrentM laura added

comment:16 Changed on 03/15/2019 at 11:09:35 AM by agiammarchi

Possibly irrelevant, and just for documentation sake, I'd like to add another way to know if the console is open:

console.log(
  Object.defineProperty(
    new Image,
    'id',
    {get() {
      requestAnimationFrame(console.clear);
      alert('console is open');
    }
  })
);

It'd be great to find out if there are sites using similar technique (we would need to patch Object.defineProperty upfront though).

comment:17 Changed on 05/27/2019 at 04:07:18 PM by mjethani

  • Sensitive unset

Add Comment

Modify Ticket

Change Properties
Action
as closed .
The resolution will be deleted. Next status will be 'reopened'.
to The owner will be changed from mjethani.
 
Note: See TracTickets for help on using tickets.