4 ms·
The accepted answer teases that this is not enough: Object.defineProperty(console, '_commandLineAPI', { get : function() { throw 'Nooo!' } }) But why isn
by gibybo 13y ago
The accepted answer teases that this is not enough:
Object.defineProperty(console, '_commandLineAPI',
{ get : function() { throw 'Nooo!' } })
But why isn't it enough?
- tshadwell 13y agoBecause it is possible to get around with just code: http://escape.alf.nu/20 http://escape.alf.nu/20 (which I have done, under another username)
- gibybo 13y agoSo how do you get around it? Or, I suppose more importantly, what else do you have to do to prevent people from getting around it?
- girvo 13y agoIt seems he's routing calls to print the code into console.log and eval-ing that string, which is quite interesting.
- gibybo 13y agoEh? Who is "he"? What do you mean routing calls?
- ewoodrich 13y agoIn the snippet posted by tshadwell. The code outputs a string into the console via console.log(), then executes the snippet from the console via eval(). Presumably to avoid to avoid Facebook's protections against console copy\paste execution. Edit: I'm wrong. Need some sleep.
- gibybo 13y agotshadwell did not post a code snippet he wrote. He posted a link to a site that demonstrates the sandbox that Facebook uses (I believe the Facebook engineer that wrote the Facebook implementation also owns escape.alf.nu). This code does not break out of the sandbox, it creates it.
- ewoodrich 13y agoI never claimed tshadwell wrote it, but you are correct, my skimming of the code was incorrect. It redirects the evaluated output of an escaped version of a string to the console.
- deleted 13y ago[deleted]
- STRML 13y agoI spent a while looking at it last night and came up with a solution, I'll walk you through it. For reference, here's the code: function escape(s) { // Bonus level! Object.defineProperty(console, 'foo', { get : function() { throw 'nooo!' } }); var code = 'with(window.console && console.foo || {}) {\n\t'+s+'\n}'; console.log(code); try { console.log(eval(code)); } catch (e) { console.log(e); } } The idea is, you need to craft `s`, such that `s` can execute arbitrary code without throwing 'nooo!'. The interesting problem is, any access to `console.foo` with throw because the getter above is called. This includes the access inside the `with` statement. So the solution, if there is any, must somehow cause mutation of state before the `with` even executes. Now, what brought me to the solution was this thought: "What in Javascript allows you to execute code before a given statement?" Upon framing it in this way, the solution became immediately clear: function declarations are automatically hoisted! If you redefine `console` to be an object without the property 'foo', the `|| {}` part of the with predicate will instead be passed as the scope, and you have free reign to walk about the system. So the solution is: alert(1) } function console(){} { Which produces the statement: with(window.console && console.foo || {}) { alert(1) } function console(){} { }
- gibybo 13y agoAh, very clever, thanks :)
- pjob 13y agoAh, cool. That's a little shorter than the solution that I came up with: function window(){alert(1)}window() To those of you going for the code golf record, you can save a character in STRML's solution by redefining window instead. Furthermore, the last two braces can be omitted and whitespace removed for a total of 27 characters.