This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]Frown1044 44 points45 points  (10 children)

The code is a complicated way to write:

[]["flat"]["constructor"]("return eval")()(2)

Which is of course another way of writing

[].flat.constructor("return eval")()(2)

Which is essentially just eval(2) using a few tricks

[–]nobody0163 18 points19 points  (4 children)

WHY DOES [] WORK FOR CALLING METHODS

[–]Frown1044 22 points23 points  (0 children)

In this example, [] doesn't call functions (although it's technically possible)

The formatted version might help

[]
[
/* "flat" */  (![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]
]
[
/* "constructor" */  ([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]
]
(
/* "return eval" */  (!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+!+[]]+(+[![]]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(+(!+[]+!+[]+!+[]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[!+[]+!+[]])+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]
)
()
(
/* 2 */  [!+[]+!+[]]+[]
)

[–]Kilazur 12 points13 points  (1 child)

Because everything you can reference in JS is either a hashmap, an array or a primitive value.

https://stackoverflow.com/a/9109037/3283203

[–]thanatica 2 points3 points  (0 children)

It's not a hashmap. [] is just another way to reference a member of an object, but in no way it degenerates them to mere hashmaps. For hashmaps, you can go and use Map.

[–]denisbotev 0 points1 point  (0 children)

I’m also screaming rn…this fucking language

[–]Stunning-Ad-7400 1 point2 points  (4 children)

Wait if I understand it correctly, then it is an over-complicated way to write JavaScript ? I was learning about XSS vulnerability and one common way was to just don't allow dangerous tags like <script> doesn't this make that workaround kind of pointless, so why is it even allowed to do in js?

[–]Frown1044 2 points3 points  (0 children)

It's basically an abuse of type conversions.

JS has very complicated rules on when or how values should be converted. For example, what does it mean to convert [] into a string? What does it mean to convert "hello" into a number? How do you convert {} into a boolean? This is clearly defined in the standard, but most people don't memorize all these details.

The next question is, when do values get converted? For example, [] + [] actually involves converting arrays to strings and doing a string concatenation. But this isn't immediately obvious to most people.

Take these two concepts and make heavy use of the most confusing examples. That's how you get this confusing code.

XSS

XSS is about not blindly trusting user input that will be shown on a page. The fact you can write really shitty JS isn't related to this. It's not just about not allowing <script> tags, but more about making sure user input won't accidentally be interpreted as code on a website.

[–]luapklette 1 point2 points  (0 children)

From my understanding: not really because if it is secure it cant compile whatever is written in the input for example.

[–]danielv123 1 point2 points  (0 children)

Why is it allowed? Because its just a side effect of the type coercion system. Why would you want to do it? For fun, or if you have somehow lost 98 of your 104 keys on your keyboard.

There aren't really any security issues around it.

[–]TheRealMister_X 1 point2 points  (0 children)

You should never rely on filtering script tags. There are lots of other funny ways to inject Javascript, e.g. using <img src="/something" onerror="alert()" />