Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Un-redefining" Google Chrome's console Object

I'm dealing with a system where the following Javascript code (which is out of my control) is being executed early in the page

if (!("console" in window) || !("firebug" in console))
{
    var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
    "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
    window.console = {};
    for (var i = 0; i < names.length; ++i)
        window.console[names[i]] = function() {}
}

This code appears to be used to create a mock console object to prevent javascript errors in environments without a javascript console. This is great, except that it also prevents Google Chrome's console from running. The conditional explicatly checks for firebug, but that's it

    if (!("console" in window) || !("firebug" in console))

So, is there way to tell Chrome's debugger to re-initialize its console object? That is, in plain english, tell Chrome

Hey, you know when you load up a page and define a console object for me to use? Do that again so we can override what someone in user-space has done.

I realize I could do something like

console.firebug = "faketrue";

and have the conditional caught, but I'm restricted in the system and don't have a way to add javascript before the above console redefinition hits. Put another way, no, I can't just add a bit of javascript code right after the start of the head.

like image 622
Alan Storm Avatar asked May 25 '11 22:05

Alan Storm


3 Answers

I believe you could possibly do this with an iframe inject and then copy the iframe's console object:

<script type="text/javascript">
console = {};
try {
    console.log('1');
} catch(e){
    alert('No console');
}
</script>
<iframe id="text"></iframe>
<script type="text/javascript">
console = window.frames[0].console;
try {
    console.log('test');
} catch(e){
    alert('No console');
}
</script>

http://jsfiddle.net/nmY6k/

Note, this is just a demonstration that the concept should work.

EDIT

With a pure JS iframe:

<script type="text/javascript">
console = {};
try {
    console.log('1');
} catch(e){
    alert('No console');
}
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
console = window.frames[0].console;
try {
    console.log('test');
} catch(e){
    alert('No console');
}
</script>

http://jsfiddle.net/nmY6k/1/

EDIT

And of course, if you need to remove the iframe element afterwards:

<script type="text/javascript">
console = {};
try {
    console.log('1');
} catch(e){
    alert('No console');
}
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
console = window.frames[0].console;
try {
    console.log('test');
} catch(e){
    alert('No console');
}
console.log(typeof window.frames);
document.body.removeChild(iframe);
console.log(typeof window.frames);
</script>
like image 176
Jared Farrish Avatar answered Oct 16 '22 00:10

Jared Farrish


In Google Chrome, deleting the console object works:

<script>
window.console = {};
delete console;
console.log('still works');
</script>

However, this doesn't seem to work in Firefox 4. It's a start, though.

like image 44
digitalbath Avatar answered Oct 15 '22 23:10

digitalbath


This seems to work:

iframe = document.createElement('iframe');
document.body.appendChild(iframe);
console = iframe.contentWindow.console;

However it looks like you cannot remove the iframe

like image 22
jontro Avatar answered Oct 15 '22 23:10

jontro