Thursday, April 17, 2014
 

IE – Disable JavaScript execution from console

In last post, I mentioned how to disable JavaScript execution from Chrome Developer Tools and now we’ll have a close look on how to achieve it for IE Developer toolbar.

Before getting into how to disable, let’s understand what goes under the hood when you type in JS code in console (or how it is understood by console and executed in the web application environment). Let’s assume that you are trying to execute the following code snippet in console

	var z = parseInt( '123', 10 );

How IE’ console shows it

IE - Console Messages

IE - Console Messages

When you type-in the above statement in IE’s console, it translate it into a full blown script statements and execute it as

document.__IE_DEVTOOLBAR_CONSOLE_EVAL_RESULT = undefined;
document.__IE_DEVTOOLBAR_CONSOLE_EVAL_ERROR = false;
try{
    document.__IE_DEVTOOLBAR_CONSOLE_EVAL_RESULT = eval( "var z = parseInt( '123', 10 );" );
}
catch(__IE_DEVTOOLBAR_CONSOLE_EVAL_ERROR){
    document.__IE_DEVTOOLBAR_CONSOLE_EVAL_RESULT =__IE_DEVTOOLBAR_CONSOLE_EVAL_ERROR.message;
    document.__IE_DEVTOOLBAR_CONSOLE_EVAL_ERROR = true;
}

Notice line no 4 where the code which typed in is exactly being passed to parameter to eval function in web application environment.

At this point, you could say – Aha, let me override eval function and discard any string which is being passed from console. Simple, isn’t it? But wait, you could do so if you are sure that eval is not being used in your application code. If it is, how would you differentiate when it is being executed from console or from the application code? (Phew, don’t remind of argument.callee and all!) that is exactly we are going to solve now.

Now, let’s revisit the code snippet generated by IE’s console. Notice that it sets a property “__IE_DEVTOOLBAR_CONSOLE_EVAL_ERROR” in document object as false before executing script and resets to true if there are any exception .

With the above knowledge, what we can do

• Create a watch property on “__IE_DEVTOOLBAR_CONSOLE_EVAL_ERROR” to understand when the value is being set to true/false.

• Set the watch property to true when the “__IE_DEVTOOLBAR_CONSOLE_EVAL_ERROR” property is set to false indicating that the next call to eval is definitely from console.

• Override eval function. Check whether the watched property is true and if so, throw exception which will be catched by code injected from console. Catch handler would reset “__IE_DEVTOOLBAR_CONSOLE_EVAL_ERROR” and accordingly our watch property. With this, we now are sure that if there are any call to eval from our application code would definitely be honored.

Now is the time to see the real code which I added to have the same functionality

(function(){
    var  _eval       = eval,
          evalError  = document.__IE_DEVTOOLBAR_CONSOLE_EVAL_ERROR,
          flag       = false;
 
    Object.defineProperty( document, "__IE_DEVTOOLBAR_CONSOLE_EVAL_ERROR", {
	get : function(){
		return evalError;
	},
	set : function(v){
		flag = !v;
                evalError = v;
	}
    });
 
    eval = function(){
	if( flag ){
		throw "";
        }
        return _eval.apply( this, arguments );
    };
})();

After adding the code, let’s see what IE’s console does –

IE - Console Disabled

IE - Console Disabled

Stay tuned for next post where I am going to describe how to handle it for Firebug console in Firefox. Don’t forget to leave comments if you have any.

 

Disable JavaScript execution from console

Most modern browser today offers developer tools either as part of browser engine (like Chrome Developer Tools in Google Chrome) or as extension mechanism (like firebug in Mozilla Firefox). These tools are certainly in a way responsible for making JavaScript a much matured language because they provide a powerful tool to debug through the script. Those shortcut keys (F8, F10, F11 etc), which use to work in powerful IDEs, was almost a privilege to other programming languages have finally arrived to JavaScript developers. Matter of no debate, powerful debugging tools is a mandate for any programming language to become mature enough to attract wide audience from developer community.

However as the debugging, which is open for all (remember, it is attached to browser and not to a particular IDE), gets more and more popular, anyone can write script snippet using console and get it executed in the host application environment (i.e., the web page which is being displayed in the browser). Obviously this cannot be considered as security threat since the user who is trying to execute any script snippet has execution permission. For example, if user has no permission to view account statement for other user, he/she cannot do so via executing script using console since the permission are governed by backing server code.

In certain cases, it is still possible that you may want to disable any kind of script execution via console for your web application due to business demands. For the practical reason, neither you can configure user’s browser to disable console nor ask them to stop using console (both won’t work, billions of user and why would they listen to you?)

In such case, the only practical possibility would be to host code in your web application which disallows any script execution via console. Wow! First question, is that even possible? How?

Yes, that’s kind of possible and which is what I am going to explain now. Let’s take example of Google Chrome Developer tools.

Chrome developer tools takes anything which is typed in to console as an input and simply passes it to evaluate function to run it in the host application environment. Before doing so, they create a property “_commandLineAPI” in console object and whole script gets executed in with block as

with ((window && window.console && window.console._commandLineAPI) || {}) {
// your script here.
}

Now seeing what we have above, it is very easy to say that the only way to stop execution of “script code typed in console” is to throw an exception before that.

A simplest way would be to save the console object in a function variable and define console property in window object with accessor/mutators (i.e., get/set). In get function, we could simply check if the property attached by chrome developer tool exists and if yes, throw exception (obviously which is not handled by anyone and hence stops execution of further code).

Here’s the full code snippet

<script type="'text/javascript'">
(function(){
 
    var _z = console;
    Object.defineProperty( window, "console", {
	get : function(){
	    if( _z._commandLineAPI ){
		throw "Sorry, Can't exceute scripts!";
            }
	    return _z; 
	},
	set : function(val){
	    _z = val;
	}
    });
 
})();
</script>

With the above script added in your web application, try launching console and execute any script. You would notice the following message in console (and yes, typed in script in console did not get executed!)

Script Execution Using Chrome Developer Tools

Whoa!!!

 
 
 

 

Find Me!
View Kunal Kumar's profile on LinkedIn