Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions test/astdeps.spec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// Require Third-party Dependencies
import is from "@slimio/is";

// Import Third-party Dependencies
import test from "tape";

// Require Internal Dependencies
Expand Down
4 changes: 2 additions & 2 deletions test/obfuscated.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Import Node.js Dependencies
import { readFileSync } from "fs";
import { fileURLToPath } from "url";
import { readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";

// Import Third-party Dependencies
import test from "tape";
Expand Down
14 changes: 8 additions & 6 deletions test/probes/isAssignmentExpression.spec.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
// Require Internal Dependencies
// Import Third-party dependencies
import test from "tape";

// Import Internal Dependencies
import { getSastAnalysis, parseScript } from "../utils/index.js";
import isAssignmentExpression from "../../src/probes/isAssignmentExpression.js";

// Require Third-party dependencies
import test from "tape";

test("should detect 1 assignment expression", (tape) => {
const str = "obj = { foo: 1 }";
const ast = parseScript(str);
const analysis = getSastAnalysis(str, ast.body, isAssignmentExpression);
const { analysis } = getSastAnalysis(str, isAssignmentExpression)
.execute(ast.body);

tape.equal(analysis.idtypes.assignExpr, 1);

Expand All @@ -18,7 +19,8 @@ test("should detect 1 assignment expression", (tape) => {
test("should detect 0 assignment expression", (tape) => {
const str = "Object.assign(obj, { foo: 1 })";
const ast = parseScript(str);
const analysis = getSastAnalysis(str, ast.body, isAssignmentExpression);
const { analysis } = getSastAnalysis(str, isAssignmentExpression)
.execute(ast.body);

tape.equal(analysis.idtypes.assignExpr, 0);

Expand Down
12 changes: 7 additions & 5 deletions test/probes/isBinaryExpression.spec.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
// Import Third-party dependencies
import test from "tape";

// Import Internal Dependencies
import { getSastAnalysis, parseScript } from "../utils/index.js";
import isBinaryExpression from "../../src/probes/isBinaryExpression.js";

// Import Third-party dependencies
import test from "tape";

test("should detect 1 deep binary expression", (tape) => {
const str = "0x1*-0x12df+-0x1fb9*-0x1+0x2*-0x66d";
const ast = parseScript(str);
const analysis = getSastAnalysis(str, ast.body, isBinaryExpression);
const { analysis } = getSastAnalysis(str, isBinaryExpression)
.execute(ast.body);

tape.equal(analysis.counter.deepBinaryExpr, 1);

Expand All @@ -18,7 +19,8 @@ test("should detect 1 deep binary expression", (tape) => {
test("should not detect deep binary expression", (tape) => {
const str = "10 + 5 - (10)";
const ast = parseScript(str);
const analysis = getSastAnalysis(str, ast.body, isBinaryExpression);
const { analysis } = getSastAnalysis(str, isBinaryExpression)
.execute(ast.body);

tape.equal(analysis.counter.deepBinaryExpr, 0);

Expand Down
17 changes: 10 additions & 7 deletions test/probes/isClassDeclaration.spec.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
// Require Internal Dependencies
// Import Third-party dependencies
import test from "tape";

// Import Internal Dependencies
import { getSastAnalysis, parseScript } from "../utils/index.js";
import isClassDeclaration from "../../src/probes/isClassDeclaration.js";

// Require Third-party dependencies
import test from "tape";

test("should detect two identifiers (class name and superClass name A.K.A extends)", (tape) => {
const str = "class File extends Blob {}";
const ast = parseScript(str);
const analysis = getSastAnalysis(str, ast.body, isClassDeclaration);
const { analysis } = getSastAnalysis(str, isClassDeclaration)
.execute(ast.body);

tape.deepEqual(analysis.identifiersName, [
{ name: "File", type: "class" },
Expand All @@ -21,7 +22,8 @@ test("should detect two identifiers (class name and superClass name A.K.A extend
test("should detect one identifier because there is no superClass (extension)", (tape) => {
const str = "class File {}";
const ast = parseScript(str);
const analysis = getSastAnalysis(str, ast.body, isClassDeclaration);
const { analysis } = getSastAnalysis(str, isClassDeclaration)
.execute(ast.body);

tape.deepEqual(analysis.identifiersName, [
{ name: "File", type: "class" }
Expand All @@ -33,7 +35,8 @@ test("should detect one identifier because there is no superClass (extension)",
test("should detect one identifier because superClass is not an Identifier but a CallExpression", (tape) => {
const str = "class File extends (foo()) {}";
const ast = parseScript(str);
const analysis = getSastAnalysis(str, ast.body, isClassDeclaration);
const { analysis } = getSastAnalysis(str, isClassDeclaration)
.execute(ast.body);

tape.deepEqual(analysis.identifiersName, [
{ name: "File", type: "class" }
Expand Down
14 changes: 8 additions & 6 deletions test/probes/isFunctionDeclaration.spec.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
// Require Internal Dependencies
// Import Third-party dependencies
import test from "tape";

// Import Internal Dependencies
import { getSastAnalysis, parseScript } from "../utils/index.js";
import isFunctionDeclaration from "../../src/probes/isFunctionDeclaration.js";

// Require Third-party dependencies
import test from "tape";

test("should detect 1 function declaration", (tape) => {
const str = "function foo() {}";
const ast = parseScript(str);
const analysis = getSastAnalysis(str, ast.body, isFunctionDeclaration);
const { analysis } = getSastAnalysis(str, isFunctionDeclaration)
.execute(ast.body);

tape.equal(analysis.idtypes.functionDeclaration, 1);

Expand All @@ -18,7 +19,8 @@ test("should detect 1 function declaration", (tape) => {
test("should detect 0 function declaration", (tape) => {
const str = "foo()";
const ast = parseScript(str);
const analysis = getSastAnalysis(str, ast.body, isFunctionDeclaration);
const { analysis } = getSastAnalysis(str, isFunctionDeclaration)
.execute(ast.body);

tape.equal(analysis.idtypes.functionDeclaration, 0);

Expand Down
29 changes: 16 additions & 13 deletions test/probes/isImportDeclaration.spec.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
// Require Internal Dependencies
// Import Third-party dependencies
import test from "tape";

// Import Internal Dependencies
import { getSastAnalysis, parseScript } from "../utils/index.js";
import isImportDeclaration from "../../src/probes/isImportDeclaration.js";

// Require Third-party dependencies
import test from "tape";

test("should detect 1 dependency for an ImportNamespaceSpecifier", (tape) => {
const str = "import * as foo from \"bar\"";
const ast = parseScript(str);
const analysis = getSastAnalysis(str, ast.body, isImportDeclaration);
const { analysis } = getSastAnalysis(str, isImportDeclaration)
.execute(ast.body);

const { dependencies } = analysis.dependencies;
tape.strictEqual("bar" in dependencies, true);
Expand All @@ -19,7 +20,8 @@ test("should detect 1 dependency for an ImportNamespaceSpecifier", (tape) => {
test("should detect 1 dependency for an ImportDefaultSpecifier", (tape) => {
const str = "import foo from \"bar\"";
const ast = parseScript(str);
const analysis = getSastAnalysis(str, ast.body, isImportDeclaration);
const { analysis } = getSastAnalysis(str, isImportDeclaration)
.execute(ast.body);

const { dependencies } = analysis.dependencies;
tape.strictEqual("bar" in dependencies, true);
Expand All @@ -30,7 +32,8 @@ test("should detect 1 dependency for an ImportDefaultSpecifier", (tape) => {
test("should detect 1 dependency for an ImportSpecifier", (tape) => {
const str = "import { xd } from \"bar\"";
const ast = parseScript(str);
const analysis = getSastAnalysis(str, ast.body, isImportDeclaration);
const { analysis } = getSastAnalysis(str, isImportDeclaration)
.execute(ast.body);

const { dependencies } = analysis.dependencies;
tape.strictEqual("bar" in dependencies, true);
Expand All @@ -41,7 +44,8 @@ test("should detect 1 dependency for an ImportSpecifier", (tape) => {
test("should detect 1 dependency with no specificiers", (tape) => {
const str = "import \"bar\"";
const ast = parseScript(str);
const analysis = getSastAnalysis(str, ast.body, isImportDeclaration);
const { analysis } = getSastAnalysis(str, isImportDeclaration)
.execute(ast.body);

const { dependencies } = analysis.dependencies;
tape.strictEqual("bar" in dependencies, true);
Expand All @@ -54,13 +58,12 @@ test("should detect an unsafe import using data:text/javascript and throw a unsa
const str = `import '${expectedValue}';`;

const ast = parseScript(str);
const analysis = getSastAnalysis(str, ast.body, isImportDeclaration);
const sastAnalysis = getSastAnalysis(str, isImportDeclaration)
.execute(ast.body);

const { warnings } = analysis;
tape.strictEqual(warnings.length, 1);
tape.strictEqual(sastAnalysis.warnings().length, 1);

const [unsafeImport] = warnings;
tape.strictEqual(unsafeImport.kind, "unsafe-import");
const unsafeImport = sastAnalysis.getWarning("unsafe-import");
tape.strictEqual(unsafeImport.value, expectedValue);

tape.end();
Expand Down
88 changes: 88 additions & 0 deletions test/probes/isLiteral.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Import Third-party dependencies
import test from "tape";

// Import Internal Dependencies
import { getSastAnalysis, parseScript, mockedFunction } from "../utils/index.js";
import isLiteral from "../../src/probes/isLiteral.js";

test("should throw an unsafe-import because the hexadecimal string is equal to the core 'http' dependency", (tape) => {
const str = "const foo = '68747470'";
const ast = parseScript(str);

const analyzeStringMock = mockedFunction();
const sastAnalysis = getSastAnalysis(str, isLiteral);
sastAnalysis.analysis.analyzeString = analyzeStringMock.callback.bind(analyzeStringMock);
sastAnalysis.execute(ast.body);

tape.strictEqual(sastAnalysis.warnings().length, 1);
const warning = sastAnalysis.getWarning("unsafe-import");
tape.strictEqual(warning.kind, "unsafe-import");

tape.true("http" in sastAnalysis.dependencies(), true);
tape.true(analyzeStringMock.haveBeenCalledTimes(1));
tape.true(analyzeStringMock.haveBeenCalledWith("http"));

tape.end();
});

test("should throw an encoded-literal warning because the hexadecimal value is equal to 'require'", (tape) => {
const str = "const _t = globalThis['72657175697265']";
const ast = parseScript(str);

const analyzeStringMock = mockedFunction();
const sastAnalysis = getSastAnalysis(str, isLiteral);
sastAnalysis.analysis.analyzeString = analyzeStringMock.callback.bind(analyzeStringMock);
sastAnalysis.execute(ast.body);

tape.strictEqual(sastAnalysis.warnings().length, 1);
const warning = sastAnalysis.getWarning("encoded-literal");
tape.strictEqual(warning.value, "72657175697265");

tape.true(analyzeStringMock.haveBeenCalledTimes(1));
tape.true(analyzeStringMock.haveBeenCalledWith("require"));

tape.end();
});

test("should not throw an encoded-literal warning because hexadecimal value is safe", (tape) => {
const str = "const foo = '123456789'";
const ast = parseScript(str);
const sastAnalysis = getSastAnalysis(str, isLiteral)
.execute(ast.body);

tape.strictEqual(sastAnalysis.warnings().length, 0);

tape.end();
});

test("should throw an encoded-literal warning because hexadecimal value is not safe", (tape) => {
// Note: hexadecimal equal 'hello world'
const str = "const foo = '68656c6c6f20776f726c64'";
const ast = parseScript(str);
const sastAnalysis = getSastAnalysis(str, isLiteral)
.execute(ast.body);

tape.strictEqual(sastAnalysis.warnings().length, 1);
const warning = sastAnalysis.getWarning("encoded-literal");
tape.strictEqual(warning.value, "68656c6c6f20776f726c64");

tape.end();
});

test("should not throw any warnings without hexadecimal value (and should call analyzeLiteral of Analysis class)", (tape) => {
const str = "const foo = 'hello world!'";
const ast = parseScript(str);

const analyzeLiteralMock = mockedFunction();
const sastAnalysis = getSastAnalysis(str, isLiteral);
sastAnalysis.analysis.analyzeLiteral = analyzeLiteralMock.callback.bind(analyzeLiteralMock);
sastAnalysis.execute(ast.body);

tape.strictEqual(sastAnalysis.warnings().length, 0);
tape.true(analyzeLiteralMock.haveBeenCalledTimes(1));

const astNode = analyzeLiteralMock.args[0];
tape.strictEqual(astNode.value, "hello world!");

tape.end();
});
19 changes: 10 additions & 9 deletions test/probes/isLiteralRegex.spec.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
// Require Internal Dependencies
import { getSastAnalysis, parseScript, getWarningOnAnalysisResult } from "../utils/index.js";
import isLiteralRegex from "../../src/probes/isLiteralRegex.js";

// Require Third-party dependencies
// Import Third-party dependencies
import test from "tape";

// Import Internal Dependencies
import { getSastAnalysis, parseScript } from "../utils/index.js";
import isLiteralRegex from "../../src/probes/isLiteralRegex.js";

test("should throw a 'unsafe-regex' warning because the given RegExp Literal is unsafe", (tape) => {
const str = "const foo = /(a+){10}/g;";
const ast = parseScript(str);
const analysis = getSastAnalysis(str, ast.body, isLiteralRegex);
const sastAnalysis = getSastAnalysis(str, isLiteralRegex)
.execute(ast.body);

tape.equal(analysis.warnings.length, 1);
const result = getWarningOnAnalysisResult(analysis, "unsafe-regex");
tape.equal(result.value, "(a+){10}");
tape.strictEqual(sastAnalysis.warnings().length, 1);
const result = sastAnalysis.getWarning("unsafe-regex");
tape.strictEqual(result.value, "(a+){10}");

tape.end();
});
20 changes: 12 additions & 8 deletions test/probes/isMemberExpression.spec.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
// Require Internal Dependencies
// Import Third-party dependencies
import test from "tape";

// Import Internal Dependencies
import { getSastAnalysis, parseScript } from "../utils/index.js";
import isMemberExpression from "../../src/probes/isMemberExpression.js";

// Require Third-party dependencies
import test from "tape";

test("should detect 1 member expression", (tape) => {
const str = "process.mainModule";
const ast = parseScript(str);
const analysis = getSastAnalysis(str, ast.body, isMemberExpression);
const { analysis } = getSastAnalysis(str, isMemberExpression)
.execute(ast.body);

tape.equal(analysis.counter.memberExpr, 1);

Expand All @@ -18,7 +19,8 @@ test("should detect 1 member expression", (tape) => {
test("should detect 2 members expressions", (tape) => {
const str = "process.mainModule.foo";
const ast = parseScript(str);
const analysis = getSastAnalysis(str, ast.body, isMemberExpression);
const { analysis } = getSastAnalysis(str, isMemberExpression)
.execute(ast.body);

tape.equal(analysis.counter.memberExpr, 2);

Expand All @@ -28,7 +30,8 @@ test("should detect 2 members expressions", (tape) => {
test("should detect 1 member expression and 2 nodes", (tape) => {
const str = "process.mainModule['foo']['bar']";
const ast = parseScript(str);
const analysis = getSastAnalysis(str, ast.body, isMemberExpression);
const { analysis } = getSastAnalysis(str, isMemberExpression)
.execute(ast.body);

tape.equal(analysis.counter.memberExpr, 1);
tape.equal(analysis.counter.computedMemberExpr, 2);
Expand All @@ -39,7 +42,8 @@ test("should detect 1 member expression and 2 nodes", (tape) => {
test("should detect 0 member expression", (tape) => {
const str = "process";
const ast = parseScript(str);
const analysis = getSastAnalysis(str, ast.body, isMemberExpression);
const { analysis } = getSastAnalysis(str, isMemberExpression)
.execute(ast.body);

tape.equal(analysis.counter.memberExpr, 0);

Expand Down
Loading