Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect when "Inspect Element" is open

Tags:

javascript

Samy Kamkar's website, http://samy.pl, knows when the console is being opened and wipes the source/console when it does open.

enter image description here

How does this work?

like image 293
Gala Avatar asked Feb 12 '17 21:02

Gala


People also ask

How do you detect if inspect element is opened?

If the devtools are closed, console. log is a no-op. That's the key that lets you detect if the devtools are open: detecting if the log operation is a no-op. In the process of writing element to the console, it gets the id of the element.

How do I check if a script is inspect element?

Under Chrome's Elements view, try Inspect-ing an element (right-click, Inspect); then, on the right side of the developer view, scroll down to Event Listeners. Here you can view what code files have hooked up an event.

Does inspect element make permanent changes?

Permanent Inspect Element. This extension lets you save the changes you make to a static web page using Inspect Element to remain there even after you refresh the page.


1 Answers

This took some digging. samy.pl has several levels of indirection and obfuscation on top of this code. It uses a different version of the detection code than the GitHub repository found by JohanP. The code in samy.pl, unlike the GitHub repository, can detect the devtools when they are not docked.

It does so by using a short script that executes differently depending on whether devtools is open or closed.

Example script

Here's a self-contained example; open it in a browser and notice how the output changes as the devtools are opened and closed (whether it is docked or not):

<!DOCTYPE html> <html>     <body>         <pre id="output"></pre>         <script type="text/javascript">             var element = new Image;             var devtoolsOpen = false;             element.__defineGetter__("id", function() {                 devtoolsOpen = true; // This only executes when devtools is open.             });             setInterval(function() {                 devtoolsOpen = false;                 console.log(element);                 document.getElementById('output').innerHTML += (devtoolsOpen ? "dev tools is open\n" : "dev tools is closed\n");             }, 1000);         </script>     </body> </html> 

How it works

The setInterval is executed every second. console.log always executes, whether the devtools are open or closed: The console object is always defined. However, the log method only writes output to the console when the devtools are open. If the devtools are closed, console.log is a no-op. That's the key that lets you detect if the devtools are open: detecting if the log operation is a no-op.

In the process of writing element to the console, it gets the id of the element. That calls the function attached with __defineGetter__. Therefore, console.log(element) only calls that function when the devtools are open and console.log is not a no-op. The flag is set in that function, giving us an updated view of the devtools state every second.

samy.pl uses some additional tricks to hide this: the console is also cleared every second, and this code is obfuscated with a whitespace (!) encoding.

like image 182
kevingessner Avatar answered Sep 21 '22 18:09

kevingessner