JSFuck
JSFuck is an esoteric programming language with a very limited set of characters: (
,)
, [
, ]
, +
, !
. While the name is derived from Brainfuck, the only similarity to Brainfuck is having a minimalistic alphabet. Very peculiar for an esoteric language, JSFuck is valid JavaScript code, and JSFuck programs can be run in any web browser or engine that interprets JavaScript.
The challenge in JSFuck lies in recreating the full set of JavaScript functions using only these six characters, which is made possible by two properties of JavaScript:
- It is a weakly typed programming language
- It allows the evaluation of any expression as any type.[1]
As an esoteric language, JSFuck was originally developed for educational purposes according to the description provided by the author.[2] It can be used to foil detection of malicious code submitted on websites, e.g. in cross-site scripting (XSS) attacks.[3] Another potential use of JSFuck lies in code obfuscation. An optimized version of JSFuck has been used to encode jQuery, the most used JavaScript library, in a fully functional equivalent version consisting of only six distinct characters.[4]
Encoding methods
JSFuck code is extremely "verbose": In JavaScript, the code alert("Hello World!")
, which causes a pop-up window to open, is 21 characters long. In JSFuck, the same code has a length of 22948 characters. Certain single characters require far more than 1000 characters when expanded as JSFuck. This section offers an overview of how this expansion works.
Numbers
The number 0 is created by +[]
, where []
is the empty array and +
is the unary plus, used to convert the right side to a numeric value (zero here).
The number 1 is formed as +!![]
or +!+[]
, where the boolean value true
(expressed as !![]
or !+[]
in JSFuck) is converted into the numeric value 1 by the prepended plus sign.
The digits 2 to 9 are formed by summing true
$n$ times. E.g. in JavaScript true + true
= 2 and true
= !![]
= !+[]
, hence 2 can be written as !![]+!![]
or !+[]+!+[]
. Other digits follow a similar pattern.
Integers consisting of two or more digits are written, as a string, by concatenating 1-digit arrays with the plus operator.
For example, the string "10"
can be expressed in JavaScript as [1] + [0]
.
By replacing the digits with the respective JSFuck expansions, this yields to [+!+[]]+[+[]]
.
To get a numeric value instead of a string, one would enclose the previous expression in round or square brackets and prepend a plus, yielding to 10
= +([+!+[]]+[+[]])
.
Letters
Some letters can be obtained in JSFuck by accessing single characters in the string representations of simple boolean or numeric values like "false"
, "true"
, "NaN"
, "undefined"
with an indexer (a number in square brackets). Other tricks are needed to produce other letters - for example by casting the string 1e1000
into a number, which gives Infinity
, which in turn makes the letter y
accessible.[5]
The following is a list of primitive values used as building blocks to produce the most simple letters.
Value | JSFuck |
---|---|
false | ![] |
true | !![] or !+[] |
NaN | +[![]] |
undefined | [][[]] |
Infinity | +(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]]+[+[]]) |
Example: Creating the letter "a"
-
"a"
: Taken from the string"false"
. The second character of "false" is a, which can be accessed with -
"false"[1]
."false"
can be made fromfalse+[]
, i.e. the boolean constant false plus an empty array. -
(false+[])[1]
: We write false as![]
(negation applied to an empty array). -
(![]+[])[1]
: 1 is a number, we can write it as+true
. -
(![]+[])[+true]
: Since false is![]
, true is!![]
. -
(![]+[])[+!![]]
- which evaluates to "a".
Proof: In JavaScript, alert((![]+[])[+!![]])
does the same as alert("a")
.[6]
Other constructs
The Function
constructor can be used to trigger execution of JavaScript code contained in a string as if it were native JavaScript. So, for example, the statement alert(1)
is equivalent to Function("alert(1)")()
. The Function
constructor can be retrieved in JSFuck by accessing the "constructor property of a well known function, such as []["filter"]
(Array.prototype.filter
). And then alert(1)
becomes []["filter"]["constructor"]("alert(1)")()
.
Character table
The characters with the shortest JSFuck expansions are listed below. Other characters can be expressed as well but will generate considerably longer code.
Character | JSFuck |
---|---|
+ | (+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]])+[])[!+[]+!+[]] |
. | (+(+!+[]+[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+[!+[]+!+[]]+[+[]])+[])[+!+[]] |
0 | +[] |
1 | +!![] or +!+[] |
2 | !![]+!![] or !+[]+!+[] |
3 | !![]+!![]+!![] or !+[]+!+[]+!+[] |
4 | !![]+!![]+!![]+!![] or !+[]+!+[]+!+[]+!+[] |
5 | !![]+!![]+!![]+!![]+!![] or !+[]+!+[]+!+[]+!+[]+!+[] |
6 | !![]+!![]+!![]+!![]+!![]+!![] or !+[]+!+[]+!+[]+!+[]+!+[]+!+[] |
7 | !![]+!![]+!![]+!![]+!![]+!![]+!![] or !+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[] |
8 | !![]+!![]+!![]+!![]+!![]+!![]+!![]+!![] or !+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[] |
9 | !![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![] or !+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[] |
a | (![]+[])[+!+[]] |
d | ([][[]]+[])[!+[]+!+[]] |
e | (!![]+[])[!+[]+!+[]+!+[]] |
f | (![]+[])[+[]] |
i | ([![]]+[][[]])[+!+[]+[+[]]] |
I | (+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+(+!+[])+(+[])+(+[])+(+[]))+[])[+[]] |
l | (![]+[])[!+[]+!+[]] |
N | (+[![]]+[])[+[]] |
n | ([][[]]+[])[+!+[]] |
r | (!+[]+[])[+!+[]] |
s | (![]+[])[!+[]+!+[]+!+[]] |
t | (!+[]+[])[+[]] |
u | ([][[]]+[])[+[]] |
y | (+[![]]+[+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+(+!+[])+(+[])+(+[])+(+[]))])[+!+[]+[+[]]] |
Security
Lacking the distinct features of "usual" JavaScript, obfuscation techniques like JSFuck may assist malicious JavaScript code in bypassing intrusion prevention systems or content filters. For instance, the lack of alphanumeric characters in JSFuck on the one hand, and a flawed content filter on the other hand, allowed sellers to embed arbitrary JSFuck scripts in their eBay auction pages.
References
- ↑ Jane Bailey/The Daily WTF: "Bidding on Security". http://thedailywtf.com/articles/bidding-on-security
- ↑ http://www.jsfuck.com JSFuck is an esoteric and educational programming style based on the atomic parts of JavaScript. It uses only six different characters to write and execute code.
- ↑ http://arstechnica.com/security/2016/02/ebay-has-no-plans-to-fix-severe-bug-that-allows-malware-distribution/ Ars Technica: Ebay has no plans to fix severe bugs that allows malware distribution
- ↑ https://github.com/fasttime/jquery-screwed jQuery JavaScript library made of only six different characters: ! ( ) + [ ]
- ↑ http://patriciopalladino.com/blog/2012/08/09/non-alphanumeric-javascript.html "Brainfuck Beware: JavaScript is after you!"
- ↑ Adapted from: https://esolangs.org/wiki/JSFuck
- General
- JSFuck - Write any JavaScript with 6 Characters (with a JavaScript-to-JSFuck-converter)
- JavaScript code of the aforementioned converter