Skip to content

Commit 4976606

Browse files
committed
refactor: consider Function("return this") as safe
1 parent 0b807a0 commit 4976606

File tree

3 files changed

+39
-1
lines changed

3 files changed

+39
-1
lines changed

src/probes/isUnsafeCallee.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ function validateNode(node) {
1515
function main(node, options) {
1616
const { analysis, data: calleeName } = options;
1717

18+
if (
19+
calleeName === "Function" &&
20+
node.callee.arguments.length > 0 &&
21+
node.callee.arguments[0].value === "return this"
22+
) {
23+
return ProbeSignals.Skip;
24+
}
1825
analysis.addWarning("unsafe-stmt", calleeName, node.loc);
1926

2027
return ProbeSignals.Skip;

test/probes/isUnsafeCallee.spec.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,19 @@ test("should detect eval", () => {
2121
assert.equal(result.value, "eval");
2222
});
2323

24-
test("should detect Function", () => {
24+
test("should not detect warnings for Function with return this", () => {
2525
const str = "Function(\"return this\")()";
2626

27+
const ast = parseScript(str);
28+
const sastAnalysis = getSastAnalysis(str, isUnsafeCallee)
29+
.execute(ast.body);
30+
31+
assert.strictEqual(sastAnalysis.warnings.length, 0);
32+
});
33+
34+
test("should detect for unsafe Function statement", () => {
35+
const str = "Function(\"anything in here\")()";
36+
2737
const ast = parseScript(str);
2838
const sastAnalysis = getSastAnalysis(str, isUnsafeCallee)
2939
.execute(ast.body);

test/runASTAnalysis.spec.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,27 @@ test("it should be capable to follow a malicious code with hexa computation and
9595
assert.deepEqual([...dependencies.keys()], ["./test/data"]);
9696
});
9797

98+
test.skip("it should be capable to follow a malicious code with return Function this", () => {
99+
const { warnings, dependencies } = runASTAnalysis(`
100+
function unhex(r) {
101+
return Buffer.from(r, "hex").toString();
102+
}
103+
104+
const g = freeGlobal || freeSelf || Function('return this')();
105+
const p = g["pro" + "cess"];
106+
107+
const evil = p["mainMod" + "ule"][unhex("72657175697265")];
108+
const work = evil(unhex("2e2f746573742f64617461"));
109+
`);
110+
111+
assert.deepEqual(getWarningKind(warnings), [
112+
"encoded-literal",
113+
"unsafe-import",
114+
"unsafe-stmt"
115+
].sort());
116+
assert.deepEqual([...dependencies.keys()], ["./test/data"]);
117+
});
118+
98119
test("it should throw a 'short-identifiers' warning for a code with only one-character identifiers", () => {
99120
const { warnings } = runASTAnalysis(`
100121
var a = 0, b, c, d;

0 commit comments

Comments
 (0)