assembly-official:

eggshellsareneat:

eggshellsareneat:

i-love-linux-and-need-cat-ears:

i-love-linux-and-need-cat-ears:

WTF is this language

EVEN WORSE

Ah, I never pass up an opportunity to bring up JSFuck.

The idea is simple: how many keys do you really need? Do you really need an entire keyboard just to code in JavaScript? How many letters can we remove, pry away from your IDE, and still write a valid program?

The answer is a few too many.

Let’s start with the empty array [ ], it’s as good a place as any. The unary plus +[ ] converts it to the number 0. But why stop there? Empty arrays are truthy (everything in javascript is truthy unless it’s one of the seven hard-coded falsy values), and so we can make booleans:

![] === false
!![] === true
+!![] === 1

(Don’t get ahead of yourself though, the expression [ ] == false still evaluates to true)

We can form any number, we just need to keep adding 1 until we get there. Luckily, there’s a better way. I mean don’t get me wrong,

!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]

absolutely does equal 10 and you should absolutely put it in production, but it’s a bit unwieldy. Wouldn’t it be easier to just write a 1 and a 0 next to eachother?

Good news! Using the plus operator on arrays concatenates their contents. So we can just write [1] + [0] to get “10” (yes, as a string, adding arrays outputs strings). And our old friend the unary plus turns this into a number, like so:

+([1]+[0]) === 10
+([+!+[]]+[+[]]) === 10

Much more space efficient. Much more practical. JavaScript is begging us to stop. We will not.

“Eggshells!” I hear you cry, “we don’t have any letters! How do I write an if statement without any letters!”

Good question! By only using the six characters [ ] ( ) ! +, what can we do that will return a letter?

Well, the answer’s been in front of us the whole time, hasn’t it? Doesn’t ![ ] evaluate to false? That’s five perfectly good letters right there

“false”[1] === ‘a’
(false+[])[1] === 'a’ // adding things to arrays returns strings, remember?
(![]+[])[+!![]] === 'a’

We’ve got a couple gimmies: false, true, NaN, undefined, and Infinity are all easily reachable. For more complex letters, we can index the string “function at() { [native code] }” that we get from [ ]+[ ][“at”]. Nothing can hold us back.

And all of this, the fucked up typing and indexing booleans and all of this brings us to our end goal. Our white whale. How do we turn a string into runnable code?

The answer is the Function constructor. Takes a string like “alert(1)”, returns that string as the runnable function alert(1). Since it’s the constructor of every function, all we need is to get any function within reach, and get its constructor. And since we can get Array.prototype.at()…

[][“at”][“constructor”](“alert(1)”)()

This is valid code. It will run alert(1) in your browser. All it takes is a couple square brackets, a couple parentheses, and some letters. And we have all the letters we need. Using only the six characters [ ] ( ) ! + we can write any piece of code we want.

So I leave you with this: a piece of code–valid JavaScript code–that you can run in the console of any modern browser:

[][(![]+[])[+!![]]+(!![]+[])[+[]]][([]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+(!![]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+([][[]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+(+[![]]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+!![]]]+(![]+[])[+!![]]+(![]+[])[!![]+!![]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]])()([][(![]+[])[+!![]]+(!![]+[])[+[]]][([]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+(!![]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+([][[]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+(+[![]]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+!![]]]+([]+[][(!![]+[])[!![]+!![]+!![]]+([][[]]+[])[+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([![]]+[][[]])[+!![]+[+[]]]+(!![]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]]())[!![]+!![]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+(![]+[])[+!![]])()(!![])[+!![]]+(!![]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]]+(![]+[])[!![]+!![]]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]][([]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+(![]+[])[+!![]]+(![]+[])[!![]+!![]]+(![]+[])[!![]+!![]]]((!![]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+(+[![]]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+!![]]])+([]+[][(![]+[])[+!![]]+(!![]+[])[+[]]][([]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+(!![]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+([][[]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+(+[![]]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+!![]]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]]+(![]+[])[+[]])())[+!![]+[!![]+!![]+!![]]]+(!![]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+(!![]+[])[+!![]]+(![]+[])[!![]+!![]]+([][[]]+[])[!![]+!![]]+[][(![]+[])[+!![]]+(!![]+[])[+[]]][([]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+(!![]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+([][[]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+(+[![]]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+!![]]]+(![]+[])[+!![]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+([]+[][(!![]+[])[!![]+!![]+!![]]+([][[]]+[])[+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([![]]+[][[]])[+!![]+[+[]]]+(!![]+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]]())[!![]+!![]])()((+(+!![]+(!![]+[])[!![]+!![]+!![]]+(+!![])+(+[])+(+[])+(+[]))+[])[+[]]+![])[+[]])

which, of course, will alert

Hello, World!

This language is insane

(I made the above snippit with jscrew.it. Go try it!)

Oh yeah, reblog this version instead:

You can run this in the console of your browser. In practice, you really shouldn’t. If you want to, open a new tab and run it there.

The reason being is that even though I say this code alerts “Hello World” (and it does), I could easily be lying. This code could also just as easily steal your Tumblr authorization, and either a) post from your account, or without 2fa b) steal your account.

This is an extremely common scam, called a “self-XSS”, and most browsers warn you to not paste code you don’t know. Heed that warning! I wouldn’t recommend running the above code unless you really want to.

You can use a VM or Sandboxed browser (which is a browser running in a VM on someone else’s server) to run untrusted code. https://www.browserling.com/browser-sandbox has limited free sandboxed browsers. If you want to be extra safe you’d have to run your own isolated system (like a VM).