@nodesecure/js-x-ray 6.0.0 → 6.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 +42 -27
- package/index.js +48 -16
- package/package.json +3 -3
- package/src/obfuscators/freejsobfuscator.js +9 -9
- package/src/obfuscators/index.js +5 -1
- package/src/probes/isAssignmentExpression.js +29 -29
- package/src/probes/isLiteral.js +61 -49
- package/src/utils.js +4 -0
- package/src/warnings.js +5 -0
- package/types/api.d.ts +17 -0
- package/types/warnings.d.ts +2 -1
package/README.md
CHANGED
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<
|
|
2
|
+
<img src="https://user-images.githubusercontent.com/4438263/213887379-c873eb89-8786-4b5c-8a59-dcca49e01cb8.jpg" alt="@nodesecure/js-x-ray">
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://github.com/NodeSecure/js-x-ray">
|
|
7
|
+
<img src="https://img.shields.io/badge/dynamic/json.svg?style=for-the-badge&url=https://raw.githubusercontent.com/NodeSecure/js-x-ray/master/package.json&query=$.version&label=Version" alt="npm version">
|
|
8
|
+
</a>
|
|
9
|
+
<a href="https://github.com/NodeSecure/js-x-ray/blob/master/LICENSE">
|
|
10
|
+
<img src="https://img.shields.io/github/license/Naereen/StrapDown.js.svg?style=for-the-badge" alt="license">
|
|
11
|
+
</a>
|
|
12
|
+
<a href="https://api.securityscorecards.dev/projects/github.com/NodeSecure/js-x-ray">
|
|
13
|
+
<img src="https://api.securityscorecards.dev/projects/github.com/NodeSecure/js-x-ray/badge?style=for-the-badge" alt="ossf scorecard">
|
|
14
|
+
</a>
|
|
15
|
+
<a href="https://github.com/NodeSecure/js-x-ray/actions?query=workflow%3A%22Node.js+CI%22">
|
|
16
|
+
<img src="https://img.shields.io/github/actions/workflow/status/NodeSecure/js-x-ray/node.js.yml?style=for-the-badge" alt="github ci workflow">
|
|
17
|
+
</a>
|
|
18
|
+
<a href="https://codecov.io/github/NodeSecure/js-xray">
|
|
19
|
+
<img src="https://img.shields.io/codecov/c/github/NodeSecure/js-x-ray?style=for-the-badge" alt="codecov">
|
|
20
|
+
</a>
|
|
21
|
+
</p>
|
|
11
22
|
|
|
12
23
|
JavaScript AST analysis. This package has been created to export the [Node-Secure](https://github.com/ES-Community/nsecure) AST Analysis to enable better code evolution and allow better access to developers and researchers.
|
|
13
24
|
|
|
@@ -90,7 +101,8 @@ type WarningName = "parsing-error"
|
|
|
90
101
|
| "suspicious-file"
|
|
91
102
|
| "obfuscated-code"
|
|
92
103
|
| "weak-crypto"
|
|
93
|
-
| "unsafe-import"
|
|
104
|
+
| "unsafe-import"
|
|
105
|
+
| "shady-link";
|
|
94
106
|
|
|
95
107
|
declare const warnings: Record<WarningName, {
|
|
96
108
|
i18n: string;
|
|
@@ -126,6 +138,7 @@ This section describe all the possible warnings returned by JSXRay. Click on the
|
|
|
126
138
|
| [suspicious-file](./docs/suspicious-file.md) | ✔️ | A suspicious file with more than ten encoded-literal in it |
|
|
127
139
|
| [obfuscated-code](./docs/obfuscated-code.md) | ✔️ | There's a very high probability that the code is obfuscated. |
|
|
128
140
|
| [weak-crypto](./docs/weak-crypto.md) | ✔️ | The code probably contains a weak crypto algorithm (md5, sha1...) |
|
|
141
|
+
| [shady-link](./docs/shady-link.md) | ✔️ | The code contains shady/unsafe link |
|
|
129
142
|
|
|
130
143
|
## API
|
|
131
144
|
|
|
@@ -134,8 +147,9 @@ This section describe all the possible warnings returned by JSXRay. Click on the
|
|
|
134
147
|
|
|
135
148
|
```ts
|
|
136
149
|
interface RuntimeOptions {
|
|
137
|
-
|
|
138
|
-
|
|
150
|
+
module?: boolean;
|
|
151
|
+
isMinified?: boolean;
|
|
152
|
+
removeHTMLComments?: boolean;
|
|
139
153
|
}
|
|
140
154
|
```
|
|
141
155
|
|
|
@@ -143,11 +157,11 @@ The method take a first argument which is the code you want to analyse. It will
|
|
|
143
157
|
|
|
144
158
|
```ts
|
|
145
159
|
interface Report {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
160
|
+
dependencies: ASTDeps;
|
|
161
|
+
warnings: Warning[];
|
|
162
|
+
idsLengthAvg: number;
|
|
163
|
+
stringScore: number;
|
|
164
|
+
isOneLineRequire: boolean;
|
|
151
165
|
}
|
|
152
166
|
```
|
|
153
167
|
|
|
@@ -158,8 +172,9 @@ interface Report {
|
|
|
158
172
|
|
|
159
173
|
```ts
|
|
160
174
|
interface RuntimeOptions {
|
|
161
|
-
|
|
162
|
-
|
|
175
|
+
module?: boolean;
|
|
176
|
+
isMinified?: boolean;
|
|
177
|
+
removeHTMLComments?: boolean;
|
|
163
178
|
}
|
|
164
179
|
```
|
|
165
180
|
|
|
@@ -194,18 +209,18 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|
|
194
209
|
<table>
|
|
195
210
|
<tbody>
|
|
196
211
|
<tr>
|
|
197
|
-
<td align="center"><a href="https://www.linkedin.com/in/thomas-gentilhomme/"><img src="https://avatars.githubusercontent.com/u/4438263?v=4?s=100" width="100px;" alt="Gentilhomme"/><br /><sub><b>Gentilhomme</b></sub></a><br /><a href="https://github.com/NodeSecure/js-x-ray/commits?author=fraxken" title="Code">💻</a> <a href="https://github.com/NodeSecure/js-x-ray/commits?author=fraxken" title="Documentation">📖</a> <a href="https://github.com/NodeSecure/js-x-ray/pulls?q=is%3Apr+reviewed-by%3Afraxken" title="Reviewed Pull Requests">👀</a> <a href="#security-fraxken" title="Security">🛡️</a> <a href="https://github.com/NodeSecure/js-x-ray/issues?q=author%3Afraxken" title="Bug reports">🐛</a></td>
|
|
198
|
-
<td align="center"><a href="https://github.com/Rossb0b"><img src="https://avatars.githubusercontent.com/u/39910164?v=4?s=100" width="100px;" alt="Nicolas Hallaert"/><br /><sub><b>Nicolas Hallaert</b></sub></a><br /><a href="https://github.com/NodeSecure/js-x-ray/commits?author=Rossb0b" title="Documentation">📖</a></td>
|
|
199
|
-
<td align="center"><a href="https://github.com/antoine-coulon"><img src="https://avatars.githubusercontent.com/u/43391199?v=4?s=100" width="100px;" alt="Antoine"/><br /><sub><b>Antoine</b></sub></a><br /><a href="https://github.com/NodeSecure/js-x-ray/commits?author=antoine-coulon" title="Code">💻</a></td>
|
|
200
|
-
<td align="center"><a href="https://github.com/Mathieuka"><img src="https://avatars.githubusercontent.com/u/34446722?v=4?s=100" width="100px;" alt="Mathieu"/><br /><sub><b>Mathieu</b></sub></a><br /><a href="https://github.com/NodeSecure/js-x-ray/commits?author=Mathieuka" title="Code">💻</a></td>
|
|
201
|
-
<td align="center"><a href="https://github.com/Kawacrepe"><img src="https://avatars.githubusercontent.com/u/40260517?v=4?s=100" width="100px;" alt="Vincent Dhennin"/><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>
|
|
202
|
-
<td align="center"><a href="http://tonygo.dev"><img src="https://avatars.githubusercontent.com/u/22824417?v=4?s=100" width="100px;" alt="Tony Gorez"/><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>
|
|
203
|
-
<td align="center"><a href="https://github.com/PierreDemailly"><img src="https://avatars.githubusercontent.com/u/39910767?v=4?s=100" width="100px;" alt="PierreD"/><br /><sub><b>PierreD</b></sub></a><br /><a href="https://github.com/NodeSecure/js-x-ray/commits?author=PierreDemailly" title="Tests">⚠️</a></td>
|
|
212
|
+
<td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/thomas-gentilhomme/"><img src="https://avatars.githubusercontent.com/u/4438263?v=4?s=100" width="100px;" alt="Gentilhomme"/><br /><sub><b>Gentilhomme</b></sub></a><br /><a href="https://github.com/NodeSecure/js-x-ray/commits?author=fraxken" title="Code">💻</a> <a href="https://github.com/NodeSecure/js-x-ray/commits?author=fraxken" title="Documentation">📖</a> <a href="https://github.com/NodeSecure/js-x-ray/pulls?q=is%3Apr+reviewed-by%3Afraxken" title="Reviewed Pull Requests">👀</a> <a href="#security-fraxken" title="Security">🛡️</a> <a href="https://github.com/NodeSecure/js-x-ray/issues?q=author%3Afraxken" title="Bug reports">🐛</a></td>
|
|
213
|
+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Rossb0b"><img src="https://avatars.githubusercontent.com/u/39910164?v=4?s=100" width="100px;" alt="Nicolas Hallaert"/><br /><sub><b>Nicolas Hallaert</b></sub></a><br /><a href="https://github.com/NodeSecure/js-x-ray/commits?author=Rossb0b" title="Documentation">📖</a></td>
|
|
214
|
+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/antoine-coulon"><img src="https://avatars.githubusercontent.com/u/43391199?v=4?s=100" width="100px;" alt="Antoine"/><br /><sub><b>Antoine</b></sub></a><br /><a href="https://github.com/NodeSecure/js-x-ray/commits?author=antoine-coulon" title="Code">💻</a></td>
|
|
215
|
+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Mathieuka"><img src="https://avatars.githubusercontent.com/u/34446722?v=4?s=100" width="100px;" alt="Mathieu"/><br /><sub><b>Mathieu</b></sub></a><br /><a href="https://github.com/NodeSecure/js-x-ray/commits?author=Mathieuka" title="Code">💻</a></td>
|
|
216
|
+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Kawacrepe"><img src="https://avatars.githubusercontent.com/u/40260517?v=4?s=100" width="100px;" alt="Vincent Dhennin"/><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>
|
|
217
|
+
<td align="center" valign="top" width="14.28%"><a href="http://tonygo.dev"><img src="https://avatars.githubusercontent.com/u/22824417?v=4?s=100" width="100px;" alt="Tony Gorez"/><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>
|
|
218
|
+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/PierreDemailly"><img src="https://avatars.githubusercontent.com/u/39910767?v=4?s=100" width="100px;" alt="PierreD"/><br /><sub><b>PierreD</b></sub></a><br /><a href="https://github.com/NodeSecure/js-x-ray/commits?author=PierreDemailly" title="Tests">⚠️</a> <a href="https://github.com/NodeSecure/js-x-ray/commits?author=PierreDemailly" title="Code">💻</a></td>
|
|
204
219
|
</tr>
|
|
205
220
|
<tr>
|
|
206
|
-
<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="Franck Hallaert"/><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>
|
|
207
|
-
<td align="center"><a href="https://maji.kiwi"><img src="https://avatars.githubusercontent.com/u/33150916?v=4?s=100" width="100px;" alt="Maji"/><br /><sub><b>Maji</b></sub></a><br /><a href="https://github.com/NodeSecure/js-x-ray/commits?author=M4gie" title="Code">💻</a></td>
|
|
208
|
-
<td align="center"><a href="https://github.com/targos"><img src="https://avatars.githubusercontent.com/u/2352663?v=4?s=100" width="100px;" alt="Michaël Zasso"/><br /><sub><b>Michaël Zasso</b></sub></a><br /><a href="https://github.com/NodeSecure/js-x-ray/commits?author=targos" title="Code">💻</a> <a href="https://github.com/NodeSecure/js-x-ray/issues?q=author%3Atargos" title="Bug reports">🐛</a></td>
|
|
221
|
+
<td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/franck-hallaert/"><img src="https://avatars.githubusercontent.com/u/110826655?v=4?s=100" width="100px;" alt="Franck Hallaert"/><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>
|
|
222
|
+
<td align="center" valign="top" width="14.28%"><a href="https://maji.kiwi"><img src="https://avatars.githubusercontent.com/u/33150916?v=4?s=100" width="100px;" alt="Maji"/><br /><sub><b>Maji</b></sub></a><br /><a href="https://github.com/NodeSecure/js-x-ray/commits?author=M4gie" title="Code">💻</a></td>
|
|
223
|
+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/targos"><img src="https://avatars.githubusercontent.com/u/2352663?v=4?s=100" width="100px;" alt="Michaël Zasso"/><br /><sub><b>Michaël Zasso</b></sub></a><br /><a href="https://github.com/NodeSecure/js-x-ray/commits?author=targos" title="Code">💻</a> <a href="https://github.com/NodeSecure/js-x-ray/issues?q=author%3Atargos" title="Bug reports">🐛</a></td>
|
|
209
224
|
</tr>
|
|
210
225
|
</tbody>
|
|
211
226
|
</table>
|
package/index.js
CHANGED
|
@@ -10,22 +10,30 @@ import isMinified from "is-minified-code";
|
|
|
10
10
|
// Import Internal Dependencies
|
|
11
11
|
import Analysis from "./src/Analysis.js";
|
|
12
12
|
import { warnings } from "./src/warnings.js";
|
|
13
|
+
import * as utils from "./src/utils.js";
|
|
13
14
|
|
|
14
15
|
// CONSTANTS
|
|
15
16
|
const kMeriyahDefaultOptions = {
|
|
16
17
|
next: true,
|
|
17
18
|
loc: true,
|
|
18
|
-
raw: true
|
|
19
|
+
raw: true,
|
|
20
|
+
jsx: true
|
|
19
21
|
};
|
|
20
22
|
|
|
21
23
|
export function runASTAnalysis(str, options = Object.create(null)) {
|
|
22
|
-
const {
|
|
24
|
+
const {
|
|
25
|
+
module = true,
|
|
26
|
+
isMinified = false,
|
|
27
|
+
removeHTMLComments = false
|
|
28
|
+
} = options;
|
|
23
29
|
|
|
24
30
|
// Note: if the file start with a shebang then we remove it because 'parseScript' may fail to parse it.
|
|
25
31
|
// Example: #!/usr/bin/env node
|
|
26
32
|
const strToAnalyze = str.charAt(0) === "#" ? str.slice(str.indexOf("\n")) : str;
|
|
27
|
-
const
|
|
28
|
-
|
|
33
|
+
const body = parseScriptExtended(strToAnalyze, {
|
|
34
|
+
isEcmaScriptModule: Boolean(module),
|
|
35
|
+
removeHTMLComments
|
|
36
|
+
});
|
|
29
37
|
|
|
30
38
|
const sastAnalysis = new Analysis();
|
|
31
39
|
sastAnalysis.analyzeSourceString(str);
|
|
@@ -56,14 +64,20 @@ export function runASTAnalysis(str, options = Object.create(null)) {
|
|
|
56
64
|
|
|
57
65
|
export async function runASTAnalysisOnFile(pathToFile, options = {}) {
|
|
58
66
|
try {
|
|
59
|
-
const {
|
|
67
|
+
const {
|
|
68
|
+
packageName = null,
|
|
69
|
+
module = true,
|
|
70
|
+
removeHTMLComments = false
|
|
71
|
+
} = options;
|
|
72
|
+
|
|
60
73
|
const str = await fs.readFile(pathToFile, "utf-8");
|
|
61
74
|
const filePathString = pathToFile instanceof URL ? pathToFile.href : pathToFile;
|
|
62
75
|
|
|
63
76
|
const isMin = filePathString.includes(".min") || isMinified(str);
|
|
64
77
|
const data = runASTAnalysis(str, {
|
|
65
78
|
isMinified: isMin,
|
|
66
|
-
module: path.extname(filePathString) === ".mjs" ? true : module
|
|
79
|
+
module: path.extname(filePathString) === ".mjs" ? true : module,
|
|
80
|
+
removeHTMLComments
|
|
67
81
|
});
|
|
68
82
|
if (packageName !== null) {
|
|
69
83
|
data.dependencies.removeByName(packageName);
|
|
@@ -86,21 +100,39 @@ export async function runASTAnalysisOnFile(pathToFile, options = {}) {
|
|
|
86
100
|
}
|
|
87
101
|
}
|
|
88
102
|
|
|
89
|
-
function parseScriptExtended(strToAnalyze,
|
|
103
|
+
function parseScriptExtended(strToAnalyze, options = {}) {
|
|
104
|
+
const { isEcmaScriptModule, removeHTMLComments } = options;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @see https://github.com/NodeSecure/js-x-ray/issues/109
|
|
108
|
+
*/
|
|
109
|
+
const cleanedStrToAnalyze = removeHTMLComments ?
|
|
110
|
+
utils.removeHTMLComment(strToAnalyze) : strToAnalyze;
|
|
111
|
+
|
|
90
112
|
try {
|
|
91
|
-
const { body } = meriyah.parseScript(
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
113
|
+
const { body } = meriyah.parseScript(
|
|
114
|
+
cleanedStrToAnalyze,
|
|
115
|
+
{
|
|
116
|
+
...kMeriyahDefaultOptions,
|
|
117
|
+
module: isEcmaScriptModule,
|
|
118
|
+
globalReturn: !isEcmaScriptModule
|
|
119
|
+
}
|
|
120
|
+
);
|
|
96
121
|
|
|
97
122
|
return body;
|
|
98
123
|
}
|
|
99
124
|
catch (error) {
|
|
100
|
-
if (error.name === "SyntaxError" &&
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
125
|
+
if (error.name === "SyntaxError" && (
|
|
126
|
+
error.description.includes("The import keyword") ||
|
|
127
|
+
error.description.includes("The export keyword")
|
|
128
|
+
)) {
|
|
129
|
+
const { body } = meriyah.parseScript(
|
|
130
|
+
cleanedStrToAnalyze,
|
|
131
|
+
{
|
|
132
|
+
...kMeriyahDefaultOptions,
|
|
133
|
+
module: true
|
|
134
|
+
}
|
|
135
|
+
);
|
|
104
136
|
|
|
105
137
|
return body;
|
|
106
138
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nodesecure/js-x-ray",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.1.0",
|
|
4
4
|
"description": "JavaScript AST XRay analysis",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": "./index.js",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
},
|
|
40
40
|
"homepage": "https://github.com/NodeSecure/js-x-ray#readme",
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@nodesecure/estree-ast-utils": "^1.3.
|
|
42
|
+
"@nodesecure/estree-ast-utils": "^1.3.1",
|
|
43
43
|
"@nodesecure/sec-literal": "^1.2.0",
|
|
44
44
|
"estree-walker": "^3.0.1",
|
|
45
45
|
"is-minified-code": "^2.0.0",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@nodesecure/eslint-config": "^1.6.0",
|
|
51
|
-
"@slimio/is": "^
|
|
51
|
+
"@slimio/is": "^2.0.0",
|
|
52
52
|
"@small-tech/esm-tape-runner": "^2.0.0",
|
|
53
53
|
"@small-tech/tap-monkey": "^1.4.0",
|
|
54
54
|
"@types/node": "^18.11.18",
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
// Import Third-party Dependencies
|
|
2
|
-
import { Utils } from "@nodesecure/sec-literal";
|
|
3
|
-
|
|
4
|
-
export function verify(analysis, prefix) {
|
|
5
|
-
const pValue = Object.keys(prefix).pop();
|
|
6
|
-
const regexStr = `^${Utils.escapeRegExp(pValue)}[a-zA-Z]{1,2}[0-9]{0,2}$`;
|
|
7
|
-
|
|
8
|
-
return analysis.identifiersName.every(({ name }) => new RegExp(regexStr).test(name));
|
|
9
|
-
}
|
|
1
|
+
// Import Third-party Dependencies
|
|
2
|
+
import { Utils } from "@nodesecure/sec-literal";
|
|
3
|
+
|
|
4
|
+
export function verify(analysis, prefix) {
|
|
5
|
+
const pValue = Object.keys(prefix).pop();
|
|
6
|
+
const regexStr = `^${Utils.escapeRegExp(pValue)}[a-zA-Z]{1,2}[0-9]{0,2}$`;
|
|
7
|
+
|
|
8
|
+
return analysis.identifiersName.every(({ name }) => new RegExp(regexStr).test(name));
|
|
9
|
+
}
|
package/src/obfuscators/index.js
CHANGED
|
@@ -25,8 +25,12 @@ export function isObfuscatedCode(analysis) {
|
|
|
25
25
|
}
|
|
26
26
|
else {
|
|
27
27
|
// TODO: also implement Dictionnary checkup
|
|
28
|
+
const identifiers = analysis.identifiersName
|
|
29
|
+
.map((value) => value?.name ?? null)
|
|
30
|
+
.filter((name) => typeof name === "string");
|
|
31
|
+
|
|
28
32
|
const { prefix, oneTimeOccurence } = Patterns.commonHexadecimalPrefix(
|
|
29
|
-
|
|
33
|
+
identifiers
|
|
30
34
|
);
|
|
31
35
|
const uPrefixNames = new Set(Object.keys(prefix));
|
|
32
36
|
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
// Import Third-party Dependencies
|
|
2
|
-
import { getVariableDeclarationIdentifiers } from "@nodesecure/estree-ast-utils";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @description Search for AssignmentExpression (Not to be confused with AssignmentPattern).
|
|
6
|
-
*
|
|
7
|
-
* @see https://github.com/estree/estree/blob/master/es5.md#assignmentexpression
|
|
8
|
-
* @example
|
|
9
|
-
* (foo = 5)
|
|
10
|
-
*/
|
|
11
|
-
function validateNode(node) {
|
|
12
|
-
return [
|
|
13
|
-
node.type === "AssignmentExpression"
|
|
14
|
-
];
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function main(node, options) {
|
|
18
|
-
const { analysis } = options;
|
|
19
|
-
|
|
20
|
-
analysis.idtypes.assignExpr++;
|
|
21
|
-
for (const { name } of getVariableDeclarationIdentifiers(node.left)) {
|
|
22
|
-
analysis.identifiersName.push({ name, type: "assignExpr" });
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export default {
|
|
27
|
-
name: "isAssignmentExpression",
|
|
28
|
-
validateNode, main, breakOnMatch: false
|
|
29
|
-
};
|
|
1
|
+
// Import Third-party Dependencies
|
|
2
|
+
import { getVariableDeclarationIdentifiers } from "@nodesecure/estree-ast-utils";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @description Search for AssignmentExpression (Not to be confused with AssignmentPattern).
|
|
6
|
+
*
|
|
7
|
+
* @see https://github.com/estree/estree/blob/master/es5.md#assignmentexpression
|
|
8
|
+
* @example
|
|
9
|
+
* (foo = 5)
|
|
10
|
+
*/
|
|
11
|
+
function validateNode(node) {
|
|
12
|
+
return [
|
|
13
|
+
node.type === "AssignmentExpression"
|
|
14
|
+
];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function main(node, options) {
|
|
18
|
+
const { analysis } = options;
|
|
19
|
+
|
|
20
|
+
analysis.idtypes.assignExpr++;
|
|
21
|
+
for (const { name } of getVariableDeclarationIdentifiers(node.left)) {
|
|
22
|
+
analysis.identifiersName.push({ name, type: "assignExpr" });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default {
|
|
27
|
+
name: "isAssignmentExpression",
|
|
28
|
+
validateNode, main, breakOnMatch: false
|
|
29
|
+
};
|
package/src/probes/isLiteral.js
CHANGED
|
@@ -1,49 +1,61 @@
|
|
|
1
|
-
// Import Node.js Dependencies
|
|
2
|
-
import { builtinModules } from "repl";
|
|
3
|
-
|
|
4
|
-
// Import Third-party Dependencies
|
|
5
|
-
import { Hex } from "@nodesecure/sec-literal";
|
|
6
|
-
|
|
7
|
-
// CONSTANTS
|
|
8
|
-
const kNodeDeps = new Set(builtinModules);
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
analysis.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
1
|
+
// Import Node.js Dependencies
|
|
2
|
+
import { builtinModules } from "repl";
|
|
3
|
+
|
|
4
|
+
// Import Third-party Dependencies
|
|
5
|
+
import { Hex } from "@nodesecure/sec-literal";
|
|
6
|
+
|
|
7
|
+
// CONSTANTS
|
|
8
|
+
const kNodeDeps = new Set(builtinModules);
|
|
9
|
+
const kShadyLinkRegExps = [
|
|
10
|
+
/(http[s]?:\/\/bit\.ly.*)$/,
|
|
11
|
+
/(http[s]?:\/\/.*\.(link|xyz|tk|ml|ga|cf|gq|pw|top|club|mw|bd|ke|am|sbs|date|quest|cd|bid|cd|ws|icu|cam|uno|email|stream))$/
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @description Search for Literal AST Node
|
|
16
|
+
* @see https://github.com/estree/estree/blob/master/es5.md#literal
|
|
17
|
+
* @example
|
|
18
|
+
* "foobar"
|
|
19
|
+
*/
|
|
20
|
+
function validateNode(node) {
|
|
21
|
+
return [
|
|
22
|
+
node.type === "Literal" && typeof node.value === "string"
|
|
23
|
+
];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function main(node, options) {
|
|
27
|
+
const { analysis } = options;
|
|
28
|
+
|
|
29
|
+
// We are searching for value obfuscated as hex of a minimum length of 4.
|
|
30
|
+
if (/^[0-9A-Fa-f]{4,}$/g.test(node.value)) {
|
|
31
|
+
const value = Buffer.from(node.value, "hex").toString();
|
|
32
|
+
analysis.analyzeString(value);
|
|
33
|
+
|
|
34
|
+
// If the value we are retrieving is the name of a Node.js dependency,
|
|
35
|
+
// then we add it to the dependencies list and we throw an unsafe-import at the current location.
|
|
36
|
+
if (kNodeDeps.has(value)) {
|
|
37
|
+
analysis.dependencies.add(value, node.loc);
|
|
38
|
+
analysis.addWarning("unsafe-import", null, node.loc);
|
|
39
|
+
}
|
|
40
|
+
else if (value === "require" || !Hex.isSafe(node.value)) {
|
|
41
|
+
analysis.addWarning("encoded-literal", node.value, node.loc);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// Else we are checking all other string with our suspect method
|
|
45
|
+
else {
|
|
46
|
+
for (const regex of kShadyLinkRegExps) {
|
|
47
|
+
if (regex.test(node.value)) {
|
|
48
|
+
analysis.addWarning("shady-link", node.value, node.loc);
|
|
49
|
+
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
analysis.analyzeLiteral(node);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export default {
|
|
59
|
+
name: "isLiteral",
|
|
60
|
+
validateNode, main, breakOnMatch: false
|
|
61
|
+
};
|
package/src/utils.js
CHANGED
package/src/warnings.js
CHANGED
package/types/api.d.ts
CHANGED
|
@@ -13,8 +13,18 @@ export {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
interface RuntimeOptions {
|
|
16
|
+
/**
|
|
17
|
+
* @default true
|
|
18
|
+
*/
|
|
16
19
|
module?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* @default false
|
|
22
|
+
*/
|
|
17
23
|
isMinified?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* @default false
|
|
26
|
+
*/
|
|
27
|
+
removeHTMLComments?: boolean;
|
|
18
28
|
}
|
|
19
29
|
|
|
20
30
|
interface Report {
|
|
@@ -27,7 +37,14 @@ interface Report {
|
|
|
27
37
|
|
|
28
38
|
interface RuntimeFileOptions {
|
|
29
39
|
packageName?: string;
|
|
40
|
+
/**
|
|
41
|
+
* @default true
|
|
42
|
+
*/
|
|
30
43
|
module?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* @default false
|
|
46
|
+
*/
|
|
47
|
+
removeHTMLComments?: boolean;
|
|
31
48
|
}
|
|
32
49
|
|
|
33
50
|
type ReportOnFile = {
|
package/types/warnings.d.ts
CHANGED
|
@@ -15,7 +15,8 @@ type WarningNameWithValue = "parsing-error"
|
|
|
15
15
|
| "suspicious-literal"
|
|
16
16
|
| "suspicious-file"
|
|
17
17
|
| "obfuscated-code"
|
|
18
|
-
| "weak-crypto"
|
|
18
|
+
| "weak-crypto"
|
|
19
|
+
| "shady-link";
|
|
19
20
|
type WarningName = WarningNameWithValue | "unsafe-import";
|
|
20
21
|
|
|
21
22
|
type WarningLocation = [[number, number], [number, number]];
|