@nodesecure/js-x-ray 4.5.0 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,8 +1,6 @@
1
1
  # js-x-ray
2
2
  ![version](https://img.shields.io/badge/dynamic/json.svg?url=https://raw.githubusercontent.com/NodeSecure/js-x-ray/master/package.json&query=$.version&label=Version)
3
3
  [![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://github.com/NodeSecure/js-x-ray/commit-activity)
4
- [![Security Responsible Disclosure](https://img.shields.io/badge/Security-Responsible%20Disclosure-yellow.svg)](https://github.com/nodejs/security-wg/blob/master/processes/responsible_disclosure_template.md
5
- )
6
4
  [![mit](https://img.shields.io/github/license/Naereen/StrapDown.js.svg)](https://github.com/NodeSecure/js-x-ray/blob/master/LICENSE)
7
5
  ![build](https://img.shields.io/github/workflow/status/NodeSecure/js-x-ray/Node.js%20CI)
8
6
 
@@ -77,24 +75,23 @@ The analysis will return: `http` (in try), `crypto`, `util` and `fs`.
77
75
 
78
76
  This section describes how use `warnings` export.
79
77
 
80
- The structure of the `warnings` is as follows:
81
- ```js
82
- /**
83
- * @property {object} warnings - The default values for Constants.
84
- * @property {string} warnings[name] - The default warning name (parsingError, unsafeImport etc...).
85
- * @property {string} warnings[name].i18n - i18n token.
86
- * @property {string} warnings[name].code - Used to perform unit tests.
87
- * @property {string} warnings[name].severity - Warning severity.
88
- */
89
-
90
- export const warnings = Object.freeze({
91
- parsingError: {
92
- i18n: "sast_warnings.ast_error"
93
- code: "ast-error",
94
- severity: "Information"
95
- },
96
- ...otherWarnings
97
- });
78
+ ```ts
79
+ type WarningName = "parsing-error"
80
+ | "encoded-literal"
81
+ | "unsafe-regex"
82
+ | "unsafe-stmt"
83
+ | "unsafe-assign"
84
+ | "short-identifiers"
85
+ | "suspicious-literal"
86
+ | "obfuscated-code"
87
+ | "weak-crypto"
88
+ | "unsafe-import";
89
+
90
+ declare const warnings: Record<WarningName, {
91
+ i18n: string;
92
+ severity: "Information" | "Warning" | "Critical";
93
+ experimental?: boolean;
94
+ }>;
98
95
  ```
99
96
 
100
97
  We make a call to `i18n` through the package `NodeSecure/i18n` to get the translation.
@@ -103,7 +100,7 @@ We make a call to `i18n` through the package `NodeSecure/i18n` to get the transl
103
100
  import * as jsxray from "@nodesecure/js-x-ray";
104
101
  import * as i18n from "@nodesecure/i18n";
105
102
 
106
- console.log(i18n.getToken(jsxray.warnings.parsingError.i18n));
103
+ console.log(i18n.getToken(jsxray.warnings["parsing-error"].i18n));
107
104
  ```
108
105
 
109
106
  ## Warnings Legends
@@ -142,7 +139,7 @@ The method take a first argument which is the code you want to analyse. It will
142
139
  ```ts
143
140
  interface Report {
144
141
  dependencies: ASTDeps;
145
- warnings: Warning<BaseWarning>[];
142
+ warnings: Warning[];
146
143
  idsLengthAvg: number;
147
144
  stringScore: number;
148
145
  isOneLineRequire: boolean;
@@ -166,12 +163,12 @@ Run the SAST scanner on a given JavaScript file.
166
163
  ```ts
167
164
  export type ReportOnFile = {
168
165
  ok: true,
169
- warnings: Warning<BaseWarning>[];
166
+ warnings: Warning[];
170
167
  dependencies: ASTDeps;
171
168
  isMinified: boolean;
172
169
  } | {
173
170
  ok: false,
174
- warnings: Warning<BaseWarning>[];
171
+ warnings: Warning[];
175
172
  }
176
173
  ```
177
174
 
@@ -181,7 +178,7 @@ export type ReportOnFile = {
181
178
  ## Contributors ✨
182
179
 
183
180
  <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
184
- [![All Contributors](https://img.shields.io/badge/all_contributors-6-orange.svg?style=flat-square)](#contributors-)
181
+ [![All Contributors](https://img.shields.io/badge/all_contributors-8-orange.svg?style=flat-square)](#contributors-)
185
182
  <!-- ALL-CONTRIBUTORS-BADGE:END -->
186
183
 
187
184
  Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
@@ -197,6 +194,10 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
197
194
  <td align="center"><a href="https://github.com/Mathieuka"><img src="https://avatars.githubusercontent.com/u/34446722?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mathieu</b></sub></a><br /><a href="https://github.com/NodeSecure/js-x-ray/commits?author=Mathieuka" title="Code">💻</a></td>
198
195
  <td align="center"><a href="https://github.com/Kawacrepe"><img src="https://avatars.githubusercontent.com/u/40260517?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Vincent Dhennin</b></sub></a><br /><a href="https://github.com/NodeSecure/js-x-ray/commits?author=Kawacrepe" title="Code">💻</a> <a href="https://github.com/NodeSecure/js-x-ray/commits?author=Kawacrepe" title="Tests">⚠️</a></td>
199
196
  <td align="center"><a href="http://tonygo.dev"><img src="https://avatars.githubusercontent.com/u/22824417?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tony Gorez</b></sub></a><br /><a href="https://github.com/NodeSecure/js-x-ray/commits?author=tony-go" title="Code">💻</a> <a href="https://github.com/NodeSecure/js-x-ray/commits?author=tony-go" title="Documentation">📖</a> <a href="https://github.com/NodeSecure/js-x-ray/commits?author=tony-go" title="Tests">⚠️</a></td>
197
+ <td align="center"><a href="https://github.com/PierreDemailly"><img src="https://avatars.githubusercontent.com/u/39910767?v=4?s=100" width="100px;" alt=""/><br /><sub><b>PierreD</b></sub></a><br /><a href="https://github.com/NodeSecure/js-x-ray/commits?author=PierreDemailly" title="Tests">⚠️</a></td>
198
+ </tr>
199
+ <tr>
200
+ <td align="center"><a href="https://www.linkedin.com/in/franck-hallaert/"><img src="https://avatars.githubusercontent.com/u/110826655?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Franck Hallaert</b></sub></a><br /><a href="https://github.com/NodeSecure/js-x-ray/commits?author=Aekk0" title="Code">💻</a></td>
200
201
  </tr>
201
202
  </table>
202
203
 
package/index.d.ts CHANGED
@@ -1,140 +1,35 @@
1
- declare class ASTDeps {
2
- constructor();
3
- removeByName(name: string): void;
4
- add(depName: string): void;
5
- getDependenciesInTryStatement(): IterableIterator<string>;
6
-
7
- public isInTryStmt: boolean;
8
- public dependencies: Record<string, JSXRay.Dependency>;
9
- public readonly size: number;
10
- }
11
-
12
- declare namespace JSXRay {
13
- type kindWithValue = "parsing-error"
14
- | "encoded-literal"
15
- | "unsafe-regex"
16
- | "unsafe-stmt"
17
- | "unsafe-assign"
18
- | "short-identifiers"
19
- | "suspicious-literal"
20
- | "obfuscated-code"
21
- | "weak-crypto";
22
-
23
- type WarningLocation = [[number, number], [number, number]];
24
- interface BaseWarning {
25
- kind: "unsafe-import" | kindWithValue;
26
- file?: string;
27
- value: string;
28
- location: WarningLocation | WarningLocation[];
29
- }
30
-
31
- type Warning<T extends BaseWarning> = T extends { kind: kindWithValue } ? T : Omit<T, "value">;
32
-
33
- interface Report {
34
- dependencies: ASTDeps;
35
- warnings: Warning<BaseWarning>[];
36
- idsLengthAvg: number;
37
- stringScore: number;
38
- isOneLineRequire: boolean;
39
- }
40
-
41
- interface SourceLocation {
42
- start: {
43
- line: number;
44
- column: number;
45
- };
46
- end: {
47
- line: number;
48
- column: number;
49
- }
50
- }
51
-
52
- interface Dependency {
53
- unsafe: boolean;
54
- inTry: boolean;
55
- location?: SourceLocation;
56
- }
57
-
58
- interface WarningsNames {
59
- parsingError: {
60
- code: "ast-error",
61
- i18n: "sast_warnings.ast_error",
62
- severity: "Information"
63
- },
64
- unsafeImport: {
65
- code: "unsafe-import",
66
- i18n: "sast_warnings.unsafe_import",
67
- severity: "Warning"
68
- },
69
- unsafeRegex: {
70
- code: "unsafe-regex",
71
- i18n: "sast_warnings.unsafe_regex",
72
- severity: "Warning"
73
- },
74
- unsafeStmt: {
75
- code: "unsafe-stmt",
76
- i18n: "sast_warnings.unsafe_stmt",
77
- severity: "Warning"
78
- },
79
- unsafeAssign: {
80
- code: "unsafe-assign",
81
- i18n: "sast_warnings.unsafe_assign",
82
- severity: "Warning"
83
- },
84
- encodedLiteral: {
85
- code: "encoded-literal",
86
- i18n: "sast_warnings.encoded_literal",
87
- severity: "Information"
88
- },
89
- shortIdentifiers: {
90
- code: "short-identifiers",
91
- i18n: "sast_warnings.short_identifiers",
92
- severity: "Warning"
93
- },
94
- suspiciousLiteral: {
95
- code: "suspicious-literal",
96
- i18n: "sast_warnings.suspicious_literal",
97
- severity: "Warning"
98
- },
99
- obfuscatedCode: {
100
- code: "obfuscated-code",
101
- i18n: "sast_warnings.obfuscated_code",
102
- severity: "Critical"
103
- },
104
- weakCrypto: {
105
- code: "weak-crypto",
106
- i18n: "sast_warnings.weak_crypto",
107
- severity: "Information",
108
- experimental: true
109
- }
110
- }
111
-
112
- interface RuntimeOptions {
113
- module?: boolean;
114
- isMinified?: boolean;
115
- }
116
-
117
- export function runASTAnalysis(str: string, options?: RuntimeOptions): Report;
118
-
119
- export type ReportOnFile = {
120
- ok: true,
121
- warnings: Warning<BaseWarning>[];
122
- dependencies: ASTDeps;
123
- isMinified: boolean;
124
- } | {
125
- ok: false,
126
- warnings: Warning<BaseWarning>[];
127
- }
128
-
129
- export interface RuntimeFileOptions {
130
- packageName?: string;
131
- module?: boolean;
132
- }
133
-
134
- export function runASTAnalysisOnFile(pathToFile: string, options?: RuntimeFileOptions): Promise<ReportOnFile>;
135
-
136
- export const warnings: WarningsNames;
137
- }
138
-
139
- export = JSXRay;
140
- export as namespace JSXRay;
1
+ import {
2
+ runASTAnalysis,
3
+ runASTAnalysisOnFile,
4
+ Report,
5
+ ReportOnFile,
6
+ RuntimeFileOptions,
7
+ RuntimeOptions
8
+ } from "./types/api";
9
+ import {
10
+ Warning,
11
+ WarningDefault,
12
+ WarningLocation,
13
+ WarningName,
14
+ WarningNameWithValue
15
+ } from "./types/warnings";
16
+ import { ASTDeps, Dependency } from "./types/astdeps";
17
+
18
+ declare const warnings: Record<WarningName, Pick<WarningDefault, "experimental" | "i18n" | "severity">>;
19
+
20
+ export {
21
+ warnings,
22
+ runASTAnalysis,
23
+ runASTAnalysisOnFile,
24
+ Report,
25
+ ReportOnFile,
26
+ RuntimeFileOptions,
27
+ RuntimeOptions,
28
+ ASTDeps,
29
+ Dependency,
30
+ Warning,
31
+ WarningDefault,
32
+ WarningLocation,
33
+ WarningName,
34
+ WarningNameWithValue
35
+ }
package/index.js CHANGED
@@ -9,6 +9,7 @@ import isMinified from "is-minified-code";
9
9
 
10
10
  // Import Internal Dependencies
11
11
  import Analysis from "./src/Analysis.js";
12
+ import { warnings } from "./src/warnings.js";
12
13
 
13
14
  export function runASTAnalysis(str, options = Object.create(null)) {
14
15
  const { module = true, isMinified = false } = options;
@@ -83,59 +84,4 @@ export async function runASTAnalysisOnFile(pathToFile, options = {}) {
83
84
  }
84
85
  }
85
86
 
86
- export const warnings = Object.freeze({
87
- parsingError: {
88
- code: "ast-error",
89
- i18n: "sast_warnings.ast_error",
90
- severity: "Information"
91
- },
92
- unsafeImport: {
93
- code: "unsafe-import",
94
- i18n: "sast_warnings.unsafe_import",
95
- severity: "Warning"
96
- },
97
- unsafeRegex: {
98
- code: "unsafe-regex",
99
- i18n: "sast_warnings.unsafe_regex",
100
- severity: "Warning"
101
- },
102
- unsafeStmt: {
103
- code: "unsafe-stmt",
104
- i18n: "sast_warnings.unsafe_stmt",
105
- severity: "Warning"
106
- },
107
- unsafeAssign: {
108
- code: "unsafe-assign",
109
- i18n: "sast_warnings.unsafe_assign",
110
- severity: "Warning"
111
- },
112
- encodedLiteral: {
113
- code: "encoded-literal",
114
- i18n: "sast_warnings.encoded_literal",
115
- severity: "Information"
116
- },
117
- shortIdentifiers: {
118
- code: "short-identifiers",
119
- i18n: "sast_warnings.short_identifiers",
120
- severity: "Warning"
121
- },
122
- suspiciousLiteral: {
123
- code: "suspicious-literal",
124
- i18n: "sast_warnings.suspicious_literal",
125
- severity: "Warning"
126
- },
127
- obfuscatedCode: {
128
- code: "obfuscated-code",
129
- i18n: "sast_warnings.obfuscated_code",
130
- severity: "Critical",
131
- experimental: true
132
- },
133
- weakCrypto: {
134
- code: "weak-crypto",
135
- i18n: "sast_warnings.weak_crypto",
136
- severity: "Information",
137
- experimental: true
138
- }
139
- });
140
-
141
-
87
+ export { warnings };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nodesecure/js-x-ray",
3
- "version": "4.5.0",
3
+ "version": "5.1.0",
4
4
  "description": "JavaScript AST XRay analysis",
5
5
  "type": "module",
6
6
  "exports": "./index.js",
@@ -27,6 +27,7 @@
27
27
  ],
28
28
  "files": [
29
29
  "src",
30
+ "types",
30
31
  "index.js",
31
32
  "index.d.ts"
32
33
  ],
@@ -40,18 +41,18 @@
40
41
  "@nodesecure/sec-literal": "^1.1.0",
41
42
  "estree-walker": "^3.0.1",
42
43
  "is-minified-code": "^2.0.0",
43
- "meriyah": "^4.2.1",
44
+ "meriyah": "^4.3.0",
44
45
  "safe-regex": "^2.1.1"
45
46
  },
46
47
  "devDependencies": {
47
- "@nodesecure/eslint-config": "^1.4.1",
48
+ "@nodesecure/eslint-config": "^1.5.0",
48
49
  "@slimio/is": "^1.5.1",
49
50
  "@small-tech/esm-tape-runner": "^2.0.0",
50
51
  "@small-tech/tap-monkey": "^1.4.0",
51
- "@types/node": "^17.0.42",
52
+ "@types/node": "^18.7.13",
52
53
  "cross-env": "^7.0.3",
53
- "eslint": "^8.17.0",
54
+ "eslint": "^8.23.0",
54
55
  "pkg-ok": "^3.0.0",
55
- "tape": "^5.5.3"
56
+ "tape": "^5.6.0"
56
57
  }
57
58
  }
package/src/Analysis.js CHANGED
@@ -2,8 +2,9 @@
2
2
  import { Utils, Literal } from "@nodesecure/sec-literal";
3
3
 
4
4
  // Import Internal Dependencies
5
- import { rootLocation, toArrayLocation, generateWarning } from "./utils.js";
6
- import { warnings as _warnings, processMainModuleRequire } from "./constants.js";
5
+ import { rootLocation, toArrayLocation } from "./utils.js";
6
+ import { generateWarning } from "./warnings.js";
7
+ import { processMainModuleRequire } from "./constants.js";
7
8
  import ASTDeps from "./ASTDeps.js";
8
9
  import { isObfuscatedCode, hasTrojanSource } from "./obfuscators/index.js";
9
10
  import { runOnProbes } from "./probes/index.js";
@@ -15,19 +16,6 @@ const kDictionaryStrParts = [
15
16
  "0123456789"
16
17
  ];
17
18
 
18
- const kWarningsNameStr = Object.freeze({
19
- [_warnings.parsingError]: "parsing-error",
20
- [_warnings.unsafeImport]: "unsafe-import",
21
- [_warnings.unsafeRegex]: "unsafe-regex",
22
- [_warnings.unsafeStmt]: "unsafe-stmt",
23
- [_warnings.unsafeAssign]: "unsafe-assign",
24
- [_warnings.encodedLiteral]: "encoded-literal",
25
- [_warnings.shortIdentifiers]: "short-identifiers",
26
- [_warnings.suspiciousLiteral]: "suspicious-literal",
27
- [_warnings.obfuscatedCode]: "obfuscated-code",
28
- [_warnings.weakCrypto]: "weak-crypto"
29
- });
30
-
31
19
  export default class Analysis {
32
20
  hasDictionaryString = false;
33
21
  hasPrefixedIdentifiers = false;
@@ -56,23 +44,24 @@ export default class Analysis {
56
44
  this.literalScores = [];
57
45
  }
58
46
 
59
- addWarning(symbol, value, location = rootLocation()) {
60
- if (symbol === _warnings.encodedLiteral && this.handledEncodedLiteralValues.has(value)) {
47
+ addWarning(name, value, location = rootLocation()) {
48
+ const isEncodedLiteral = name === "encoded-literal";
49
+ if (isEncodedLiteral && this.handledEncodedLiteralValues.has(value)) {
61
50
  const index = this.handledEncodedLiteralValues.get(value);
62
51
  this.warnings[index].location.push(toArrayLocation(location));
63
52
 
64
53
  return;
65
54
  }
66
- const warningName = kWarningsNameStr[symbol];
67
- this.warnings.push(generateWarning(warningName, { value, location }));
68
- if (symbol === _warnings.encodedLiteral) {
55
+
56
+ this.warnings.push(generateWarning(name, { value, location }));
57
+ if (isEncodedLiteral) {
69
58
  this.handledEncodedLiteralValues.set(value, this.warnings.length - 1);
70
59
  }
71
60
  }
72
61
 
73
62
  analyzeSourceString(sourceString) {
74
63
  if (hasTrojanSource(sourceString)) {
75
- this.addWarning(_warnings.obfuscatedCode, "trojan-source");
64
+ this.addWarning("obfuscated-code", "trojan-source");
76
65
  }
77
66
  }
78
67
 
@@ -107,7 +96,7 @@ export default class Analysis {
107
96
  this.counter.encodedArrayValue++;
108
97
  }
109
98
  else {
110
- this.addWarning(_warnings.encodedLiteral, node.value, node.loc);
99
+ this.addWarning("encoded-literal", node.value, node.loc);
111
100
  }
112
101
  }
113
102
  }
@@ -116,7 +105,7 @@ export default class Analysis {
116
105
  this.counter.identifiers = this.identifiersName.length;
117
106
  const [isObfuscated, kind] = isObfuscatedCode(this);
118
107
  if (isObfuscated) {
119
- this.addWarning(_warnings.obfuscatedCode, kind || "unknown");
108
+ this.addWarning("obfuscated-code", kind || "unknown");
120
109
  }
121
110
 
122
111
  const identifiersLengthArr = this.identifiersName
@@ -124,10 +113,10 @@ export default class Analysis {
124
113
 
125
114
  const [idsLengthAvg, stringScore] = [sum(identifiersLengthArr), sum(this.literalScores)];
126
115
  if (!isMinified && identifiersLengthArr.length > 5 && idsLengthAvg <= 1.5) {
127
- this.addWarning(_warnings.shortIdentifiers, idsLengthAvg);
116
+ this.addWarning("short-identifiers", idsLengthAvg);
128
117
  }
129
118
  if (stringScore >= 3) {
130
- this.addWarning(_warnings.suspiciousLiteral, stringScore);
119
+ this.addWarning("suspicious-literal", stringScore);
131
120
  }
132
121
 
133
122
  return { idsLengthAvg, stringScore, warnings: this.warnings };
@@ -149,5 +138,3 @@ export default class Analysis {
149
138
  function sum(arr = []) {
150
139
  return arr.length === 0 ? 0 : (arr.reduce((prev, curr) => prev + curr, 0) / arr.length);
151
140
  }
152
-
153
- Analysis.Warnings = _warnings;
package/src/constants.js CHANGED
@@ -33,16 +33,3 @@ export const unsafeUnicodeControlCharacters = [
33
33
  "\u200F",
34
34
  "\u061C"
35
35
  ];
36
-
37
- export const warnings = Object.freeze({
38
- parsingError: Symbol("ParsingError"),
39
- unsafeImport: Symbol("UnsafeImport"),
40
- unsafeRegex: Symbol("UnsafeRegex"),
41
- unsafeStmt: Symbol("UnsafeStmt"),
42
- unsafeAssign: Symbol("UnsafeAssign"),
43
- encodedLiteral: Symbol("EncodedLiteral"),
44
- shortIdentifiers: Symbol("ShortIdentifiers"),
45
- suspiciousLiteral: Symbol("SuspiciousLiteral"),
46
- obfuscatedCode: Symbol("ObfuscatedCode"),
47
- weakCrypto: Symbol("WeakCrypto")
48
- });
@@ -1,68 +1,68 @@
1
- // Import all the probes
2
- import isUnsafeCallee from "./isUnsafeCallee.js";
3
- import isLiteral from "./isLiteral.js";
4
- import isLiteralRegex from "./isLiteralRegex.js";
5
- import isRegexObject from "./isRegexObject.js";
6
- import isVariableDeclaration from "./isVariableDeclaration.js";
7
- import isAssignmentExprOrMemberExpr from "./isAssignmentExprOrMemberExpr.js";
8
- import isRequire from "./isRequire.js";
9
- import isImportDeclaration from "./isImportDeclaration.js";
10
- import isMemberExpression from "./isMemberExpression.js";
11
- import isArrayExpression from "./isArrayExpression.js";
12
- import isFunctionDeclaration from "./isFunctionDeclaration.js";
13
- import isAssignmentExpression from "./isAssignmentExpression.js";
14
- import isObjectExpression from "./isObjectExpression.js";
15
- import isUnaryExpression from "./isUnaryExpression.js";
16
- import isWeakCrypto from "./isWeakCrypto.js";
17
-
18
- // CONSTANTS
19
- const kListOfProbes = [
20
- isUnsafeCallee,
21
- isLiteral,
22
- isLiteralRegex,
23
- isRegexObject,
24
- isVariableDeclaration,
25
- isAssignmentExprOrMemberExpr,
26
- isRequire,
27
- isImportDeclaration,
28
- isMemberExpression,
29
- isAssignmentExpression,
30
- isObjectExpression,
31
- isArrayExpression,
32
- isFunctionDeclaration,
33
- isUnaryExpression,
34
- isWeakCrypto
35
- ];
36
-
37
- const kSymBreak = Symbol.for("breakWalk");
38
- const kSymSkip = Symbol.for("skipWalk");
39
-
40
- export function runOnProbes(node, analysis) {
41
- const breakedGroups = new Set();
42
-
43
- for (const probe of kListOfProbes) {
44
- if (breakedGroups.has(probe.breakGroup)) {
45
- continue;
46
- }
47
-
48
- const [isMatching, data = null] = probe.validateNode(node, analysis);
49
- if (isMatching) {
50
- const result = probe.main(node, { analysis, data });
51
-
52
- if (result === kSymSkip) {
53
- return "skip";
54
- }
55
- if (result === kSymBreak || probe.breakOnMatch) {
56
- const breakGroup = probe.breakGroup || null;
57
- if (breakGroup === null) {
58
- break;
59
- }
60
- else {
61
- breakedGroups.add(breakGroup);
62
- }
63
- }
64
- }
65
- }
66
-
67
- return null;
68
- }
1
+ // Import all the probes
2
+ import isUnsafeCallee from "./isUnsafeCallee.js";
3
+ import isLiteral from "./isLiteral.js";
4
+ import isLiteralRegex from "./isLiteralRegex.js";
5
+ import isRegexObject from "./isRegexObject.js";
6
+ import isVariableDeclaration from "./isVariableDeclaration.js";
7
+ import isAssignmentExprOrMemberExpr from "./isAssignmentExprOrMemberExpr.js";
8
+ import isRequire from "./isRequire.js";
9
+ import isImportDeclaration from "./isImportDeclaration.js";
10
+ import isMemberExpression from "./isMemberExpression.js";
11
+ import isArrayExpression from "./isArrayExpression.js";
12
+ import isFunctionDeclaration from "./isFunctionDeclaration.js";
13
+ import isAssignmentExpression from "./isAssignmentExpression.js";
14
+ import isObjectExpression from "./isObjectExpression.js";
15
+ import isUnaryExpression from "./isUnaryExpression.js";
16
+ import isWeakCrypto from "./isWeakCrypto.js";
17
+
18
+ // CONSTANTS
19
+ const kListOfProbes = [
20
+ isUnsafeCallee,
21
+ isLiteral,
22
+ isLiteralRegex,
23
+ isRegexObject,
24
+ isVariableDeclaration,
25
+ isAssignmentExprOrMemberExpr,
26
+ isRequire,
27
+ isImportDeclaration,
28
+ isMemberExpression,
29
+ isAssignmentExpression,
30
+ isObjectExpression,
31
+ isArrayExpression,
32
+ isFunctionDeclaration,
33
+ isUnaryExpression,
34
+ isWeakCrypto
35
+ ];
36
+
37
+ const kSymBreak = Symbol.for("breakWalk");
38
+ const kSymSkip = Symbol.for("skipWalk");
39
+
40
+ export function runOnProbes(node, analysis) {
41
+ const breakedGroups = new Set();
42
+
43
+ for (const probe of kListOfProbes) {
44
+ if (breakedGroups.has(probe.breakGroup)) {
45
+ continue;
46
+ }
47
+
48
+ const [isMatching, data = null] = probe.validateNode(node, analysis);
49
+ if (isMatching) {
50
+ const result = probe.main(node, { analysis, data });
51
+
52
+ if (result === kSymSkip) {
53
+ return "skip";
54
+ }
55
+ if (result === kSymBreak || probe.breakOnMatch) {
56
+ const breakGroup = probe.breakGroup || null;
57
+ if (breakGroup === null) {
58
+ break;
59
+ }
60
+ else {
61
+ breakedGroups.add(breakGroup);
62
+ }
63
+ }
64
+ }
65
+ }
66
+
67
+ return null;
68
+ }
@@ -1,6 +1,3 @@
1
- // Require Internal Dependencies
2
- import { warnings } from "../constants.js";
3
-
4
1
  /**
5
2
  * @description Search for ESM ImportDeclaration
6
3
  * @see https://github.com/estree/estree/blob/master/es2015.md#importdeclaration
@@ -22,7 +19,7 @@ function main(node, options) {
22
19
  // Searching for dangerous import "data:text/javascript;..." statement.
23
20
  // see: https://2ality.com/2019/10/eval-via-import.html
24
21
  if (node.source.value.startsWith("data:text/javascript")) {
25
- analysis.addWarning(warnings.unsafeImport, node.source.value, node.loc);
22
+ analysis.addWarning("unsafe-import", node.source.value, node.loc);
26
23
  }
27
24
  analysis.dependencies.add(node.source.value, node.loc);
28
25
  }