@trailofbits/vsix-audit 0.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/LICENSE +661 -0
- package/README.md +281 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +703 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/scanner/batch.d.ts +12 -0
- package/dist/scanner/batch.d.ts.map +1 -0
- package/dist/scanner/batch.js +104 -0
- package/dist/scanner/batch.js.map +1 -0
- package/dist/scanner/bundler.d.ts +35 -0
- package/dist/scanner/bundler.d.ts.map +1 -0
- package/dist/scanner/bundler.js +120 -0
- package/dist/scanner/bundler.js.map +1 -0
- package/dist/scanner/cache.d.ts +45 -0
- package/dist/scanner/cache.d.ts.map +1 -0
- package/dist/scanner/cache.js +153 -0
- package/dist/scanner/cache.js.map +1 -0
- package/dist/scanner/cache.test.d.ts +2 -0
- package/dist/scanner/cache.test.d.ts.map +1 -0
- package/dist/scanner/cache.test.js +149 -0
- package/dist/scanner/cache.test.js.map +1 -0
- package/dist/scanner/capabilities.d.ts +29 -0
- package/dist/scanner/capabilities.d.ts.map +1 -0
- package/dist/scanner/capabilities.js +217 -0
- package/dist/scanner/capabilities.js.map +1 -0
- package/dist/scanner/checks/ast.d.ts +3 -0
- package/dist/scanner/checks/ast.d.ts.map +1 -0
- package/dist/scanner/checks/ast.js +469 -0
- package/dist/scanner/checks/ast.js.map +1 -0
- package/dist/scanner/checks/ast.test.d.ts +2 -0
- package/dist/scanner/checks/ast.test.d.ts.map +1 -0
- package/dist/scanner/checks/ast.test.js +389 -0
- package/dist/scanner/checks/ast.test.js.map +1 -0
- package/dist/scanner/checks/behavioral.d.ts +3 -0
- package/dist/scanner/checks/behavioral.d.ts.map +1 -0
- package/dist/scanner/checks/behavioral.js +367 -0
- package/dist/scanner/checks/behavioral.js.map +1 -0
- package/dist/scanner/checks/blocklist.d.ts +3 -0
- package/dist/scanner/checks/blocklist.d.ts.map +1 -0
- package/dist/scanner/checks/blocklist.js +32 -0
- package/dist/scanner/checks/blocklist.js.map +1 -0
- package/dist/scanner/checks/blocklist.test.d.ts +2 -0
- package/dist/scanner/checks/blocklist.test.d.ts.map +1 -0
- package/dist/scanner/checks/blocklist.test.js +74 -0
- package/dist/scanner/checks/blocklist.test.js.map +1 -0
- package/dist/scanner/checks/chains.d.ts +35 -0
- package/dist/scanner/checks/chains.d.ts.map +1 -0
- package/dist/scanner/checks/chains.js +505 -0
- package/dist/scanner/checks/chains.js.map +1 -0
- package/dist/scanner/checks/chains.test.d.ts +2 -0
- package/dist/scanner/checks/chains.test.d.ts.map +1 -0
- package/dist/scanner/checks/chains.test.js +250 -0
- package/dist/scanner/checks/chains.test.js.map +1 -0
- package/dist/scanner/checks/dataflow.d.ts +3 -0
- package/dist/scanner/checks/dataflow.d.ts.map +1 -0
- package/dist/scanner/checks/dataflow.js +316 -0
- package/dist/scanner/checks/dataflow.js.map +1 -0
- package/dist/scanner/checks/dependencies.d.ts +13 -0
- package/dist/scanner/checks/dependencies.d.ts.map +1 -0
- package/dist/scanner/checks/dependencies.js +225 -0
- package/dist/scanner/checks/dependencies.js.map +1 -0
- package/dist/scanner/checks/dependencies.test.d.ts +2 -0
- package/dist/scanner/checks/dependencies.test.d.ts.map +1 -0
- package/dist/scanner/checks/dependencies.test.js +248 -0
- package/dist/scanner/checks/dependencies.test.js.map +1 -0
- package/dist/scanner/checks/finding-quality.test.d.ts +8 -0
- package/dist/scanner/checks/finding-quality.test.d.ts.map +1 -0
- package/dist/scanner/checks/finding-quality.test.js +164 -0
- package/dist/scanner/checks/finding-quality.test.js.map +1 -0
- package/dist/scanner/checks/ioc.d.ts +20 -0
- package/dist/scanner/checks/ioc.d.ts.map +1 -0
- package/dist/scanner/checks/ioc.js +234 -0
- package/dist/scanner/checks/ioc.js.map +1 -0
- package/dist/scanner/checks/ioc.test.d.ts +2 -0
- package/dist/scanner/checks/ioc.test.d.ts.map +1 -0
- package/dist/scanner/checks/ioc.test.js +298 -0
- package/dist/scanner/checks/ioc.test.js.map +1 -0
- package/dist/scanner/checks/manifest.d.ts +6 -0
- package/dist/scanner/checks/manifest.d.ts.map +1 -0
- package/dist/scanner/checks/manifest.js +123 -0
- package/dist/scanner/checks/manifest.js.map +1 -0
- package/dist/scanner/checks/manifest.test.d.ts +2 -0
- package/dist/scanner/checks/manifest.test.d.ts.map +1 -0
- package/dist/scanner/checks/manifest.test.js +108 -0
- package/dist/scanner/checks/manifest.test.js.map +1 -0
- package/dist/scanner/checks/obfuscation.d.ts +3 -0
- package/dist/scanner/checks/obfuscation.d.ts.map +1 -0
- package/dist/scanner/checks/obfuscation.js +432 -0
- package/dist/scanner/checks/obfuscation.js.map +1 -0
- package/dist/scanner/checks/obfuscation.test.d.ts +2 -0
- package/dist/scanner/checks/obfuscation.test.d.ts.map +1 -0
- package/dist/scanner/checks/obfuscation.test.js +399 -0
- package/dist/scanner/checks/obfuscation.test.js.map +1 -0
- package/dist/scanner/checks/package.d.ts +17 -0
- package/dist/scanner/checks/package.d.ts.map +1 -0
- package/dist/scanner/checks/package.js +422 -0
- package/dist/scanner/checks/package.js.map +1 -0
- package/dist/scanner/checks/package.test.d.ts +2 -0
- package/dist/scanner/checks/package.test.d.ts.map +1 -0
- package/dist/scanner/checks/package.test.js +518 -0
- package/dist/scanner/checks/package.test.js.map +1 -0
- package/dist/scanner/checks/patterns.d.ts +5 -0
- package/dist/scanner/checks/patterns.d.ts.map +1 -0
- package/dist/scanner/checks/patterns.js +251 -0
- package/dist/scanner/checks/patterns.js.map +1 -0
- package/dist/scanner/checks/patterns.test.d.ts +2 -0
- package/dist/scanner/checks/patterns.test.d.ts.map +1 -0
- package/dist/scanner/checks/patterns.test.js +147 -0
- package/dist/scanner/checks/patterns.test.js.map +1 -0
- package/dist/scanner/checks/unicode.d.ts +3 -0
- package/dist/scanner/checks/unicode.d.ts.map +1 -0
- package/dist/scanner/checks/unicode.js +247 -0
- package/dist/scanner/checks/unicode.js.map +1 -0
- package/dist/scanner/checks/unicode.test.d.ts +2 -0
- package/dist/scanner/checks/unicode.test.d.ts.map +1 -0
- package/dist/scanner/checks/unicode.test.js +202 -0
- package/dist/scanner/checks/unicode.test.js.map +1 -0
- package/dist/scanner/checks/yara.d.ts +23 -0
- package/dist/scanner/checks/yara.d.ts.map +1 -0
- package/dist/scanner/checks/yara.js +349 -0
- package/dist/scanner/checks/yara.js.map +1 -0
- package/dist/scanner/checks/yara.test.d.ts +2 -0
- package/dist/scanner/checks/yara.test.d.ts.map +1 -0
- package/dist/scanner/checks/yara.test.js +126 -0
- package/dist/scanner/checks/yara.test.js.map +1 -0
- package/dist/scanner/constants.d.ts +18 -0
- package/dist/scanner/constants.d.ts.map +1 -0
- package/dist/scanner/constants.js +37 -0
- package/dist/scanner/constants.js.map +1 -0
- package/dist/scanner/detection-coverage.test.d.ts +2 -0
- package/dist/scanner/detection-coverage.test.d.ts.map +1 -0
- package/dist/scanner/detection-coverage.test.js +216 -0
- package/dist/scanner/detection-coverage.test.js.map +1 -0
- package/dist/scanner/download.d.ts +76 -0
- package/dist/scanner/download.d.ts.map +1 -0
- package/dist/scanner/download.js +339 -0
- package/dist/scanner/download.js.map +1 -0
- package/dist/scanner/download.test.d.ts +2 -0
- package/dist/scanner/download.test.d.ts.map +1 -0
- package/dist/scanner/download.test.js +149 -0
- package/dist/scanner/download.test.js.map +1 -0
- package/dist/scanner/index.d.ts +8 -0
- package/dist/scanner/index.d.ts.map +1 -0
- package/dist/scanner/index.js +167 -0
- package/dist/scanner/index.js.map +1 -0
- package/dist/scanner/index.test.d.ts +2 -0
- package/dist/scanner/index.test.d.ts.map +1 -0
- package/dist/scanner/index.test.js +71 -0
- package/dist/scanner/index.test.js.map +1 -0
- package/dist/scanner/loaders/zoo.d.ts +3 -0
- package/dist/scanner/loaders/zoo.d.ts.map +1 -0
- package/dist/scanner/loaders/zoo.js +112 -0
- package/dist/scanner/loaders/zoo.js.map +1 -0
- package/dist/scanner/types.d.ts +118 -0
- package/dist/scanner/types.d.ts.map +1 -0
- package/dist/scanner/types.js +2 -0
- package/dist/scanner/types.js.map +1 -0
- package/dist/scanner/utils.d.ts +14 -0
- package/dist/scanner/utils.d.ts.map +1 -0
- package/dist/scanner/utils.js +25 -0
- package/dist/scanner/utils.js.map +1 -0
- package/dist/scanner/vsix.d.ts +6 -0
- package/dist/scanner/vsix.d.ts.map +1 -0
- package/dist/scanner/vsix.js +213 -0
- package/dist/scanner/vsix.js.map +1 -0
- package/dist/scanner/vsix.test.d.ts +2 -0
- package/dist/scanner/vsix.test.d.ts.map +1 -0
- package/dist/scanner/vsix.test.js +355 -0
- package/dist/scanner/vsix.test.js.map +1 -0
- package/package.json +60 -0
- package/zoo/blocklist/extensions.json +201 -0
- package/zoo/iocs/blockchain-extensions.txt +21 -0
- package/zoo/iocs/c2-domains.txt +50 -0
- package/zoo/iocs/c2-ips.txt +24 -0
- package/zoo/iocs/hashes.txt +47 -0
- package/zoo/iocs/malicious-npm.txt +85 -0
- package/zoo/iocs/wallets.txt +18 -0
- package/zoo/signatures/yara/README.md +46 -0
- package/zoo/signatures/yara/blockchain_c2.yar +48 -0
- package/zoo/signatures/yara/code_execution.yar +165 -0
- package/zoo/signatures/yara/credential_harvesting.yar +116 -0
- package/zoo/signatures/yara/crypto_wallet_targeting.yar +92 -0
- package/zoo/signatures/yara/data_exfiltration.yar +207 -0
- package/zoo/signatures/yara/google_calendar_c2.yar +187 -0
- package/zoo/signatures/yara/messaging_c2.yar +103 -0
- package/zoo/signatures/yara/multi_stage_attacks.yar +331 -0
- package/zoo/signatures/yara/obfuscation_patterns.yar +208 -0
- package/zoo/signatures/yara/powershell_attacks.yar +116 -0
- package/zoo/signatures/yara/rat_capabilities.yar +243 -0
- package/zoo/signatures/yara/self_propagation.yar +239 -0
- package/zoo/signatures/yara/unicode_stealth.yar +48 -0
- package/zoo/signatures/yara/websocket_c2.yar +83 -0
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
import { parseSync, Visitor } from "oxc-parser";
|
|
2
|
+
import { detectBundler, hasGenuineObfuscation } from "../bundler.js";
|
|
3
|
+
import { isScannable, SCANNABLE_EXTENSIONS_PATTERN } from "../constants.js";
|
|
4
|
+
/**
|
|
5
|
+
* Pre-compute line start positions for fast line/column lookup from byte offsets.
|
|
6
|
+
*/
|
|
7
|
+
function computeLineStarts(content) {
|
|
8
|
+
const lineStarts = [0];
|
|
9
|
+
for (let i = 0; i < content.length; i++) {
|
|
10
|
+
if (content[i] === "\n") {
|
|
11
|
+
lineStarts.push(i + 1);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return lineStarts;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Convert byte offset to line number (1-indexed).
|
|
18
|
+
*/
|
|
19
|
+
function offsetToLine(offset, lineStarts) {
|
|
20
|
+
let low = 0;
|
|
21
|
+
let high = lineStarts.length - 1;
|
|
22
|
+
while (low < high) {
|
|
23
|
+
const mid = Math.ceil((low + high) / 2);
|
|
24
|
+
const midStart = lineStarts[mid];
|
|
25
|
+
if (midStart !== undefined && midStart <= offset) {
|
|
26
|
+
low = mid;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
high = mid - 1;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return low + 1;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Convert byte offset to column number (0-indexed).
|
|
36
|
+
*/
|
|
37
|
+
function offsetToColumn(offset, lineStarts) {
|
|
38
|
+
const line = offsetToLine(offset, lineStarts);
|
|
39
|
+
const lineStart = lineStarts[line - 1] ?? 0;
|
|
40
|
+
return offset - lineStart;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Get code snippet around a node's location.
|
|
44
|
+
*/
|
|
45
|
+
function getCodeSnippet(content, start, end, lineStarts, maxLen = 100) {
|
|
46
|
+
const lineNum = offsetToLine(start, lineStarts);
|
|
47
|
+
const lines = content.split("\n");
|
|
48
|
+
const line = lines[lineNum - 1];
|
|
49
|
+
if (!line)
|
|
50
|
+
return "(no line)";
|
|
51
|
+
const lineStart = lineStarts[lineNum - 1] ?? 0;
|
|
52
|
+
const colStart = start - lineStart;
|
|
53
|
+
const colEnd = end - lineStart;
|
|
54
|
+
const snippetStart = Math.max(0, colStart - 10);
|
|
55
|
+
const snippetEnd = Math.min(line.length, colEnd + 30);
|
|
56
|
+
let snippet = line.slice(snippetStart, snippetEnd);
|
|
57
|
+
if (snippetStart > 0)
|
|
58
|
+
snippet = "..." + snippet;
|
|
59
|
+
if (snippetEnd < line.length)
|
|
60
|
+
snippet = snippet + "...";
|
|
61
|
+
return snippet.slice(0, maxLen);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Check if a node is an Identifier with a specific name.
|
|
65
|
+
*/
|
|
66
|
+
function isIdentifier(node, name) {
|
|
67
|
+
if (!node || node.type !== "Identifier")
|
|
68
|
+
return false;
|
|
69
|
+
if (name !== undefined) {
|
|
70
|
+
return node.name === name;
|
|
71
|
+
}
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get the name of an identifier node.
|
|
76
|
+
*/
|
|
77
|
+
function getIdentifierName(node) {
|
|
78
|
+
if (node.type === "Identifier") {
|
|
79
|
+
return node.name;
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Check if a node is a call to a specific function name.
|
|
85
|
+
*/
|
|
86
|
+
function isCallTo(node, name) {
|
|
87
|
+
if (node.type !== "CallExpression")
|
|
88
|
+
return false;
|
|
89
|
+
const names = Array.isArray(name) ? name : [name];
|
|
90
|
+
const callee = node.callee;
|
|
91
|
+
// Direct call: eval()
|
|
92
|
+
if (isIdentifier(callee)) {
|
|
93
|
+
const calleeName = getIdentifierName(callee);
|
|
94
|
+
if (calleeName && names.includes(calleeName)) {
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Member call: require("child_process").exec()
|
|
99
|
+
if (callee.type === "MemberExpression") {
|
|
100
|
+
const memberExpr = callee;
|
|
101
|
+
if (isIdentifier(memberExpr.property)) {
|
|
102
|
+
const propName = getIdentifierName(memberExpr.property);
|
|
103
|
+
if (propName && names.includes(propName)) {
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Check if node is a new expression with specific constructor.
|
|
112
|
+
*/
|
|
113
|
+
function isNewExpression(node, name) {
|
|
114
|
+
if (node.type !== "NewExpression")
|
|
115
|
+
return false;
|
|
116
|
+
const newExpr = node;
|
|
117
|
+
return isIdentifier(newExpr.callee, name);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Check if argument is a literal (string, number, boolean, template).
|
|
121
|
+
* OXC uses "Literal" type for all primitive literals (ESTree spec).
|
|
122
|
+
*/
|
|
123
|
+
function isLiteral(node) {
|
|
124
|
+
if (!node)
|
|
125
|
+
return false;
|
|
126
|
+
const type = node.type;
|
|
127
|
+
// OXC uses "Literal" for string/number/boolean/null/regex/bigint
|
|
128
|
+
// TemplateLiteral keeps its own type
|
|
129
|
+
return type === "Literal" || type === "TemplateLiteral";
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Check if content has obfuscation indicators.
|
|
133
|
+
*/
|
|
134
|
+
function hasObfuscationIndicators(content) {
|
|
135
|
+
const indicators = [
|
|
136
|
+
/_0x[a-f0-9]{4,}/i, // Hex variable names
|
|
137
|
+
/\\x[a-f0-9]{2}(?:\\x[a-f0-9]{2}){5,}/i, // Many hex escapes
|
|
138
|
+
/atob\s*\([^)]+\)/i, // Base64 decode
|
|
139
|
+
/String\.fromCharCode\s*\([^)]*,/i, // Char code construction
|
|
140
|
+
];
|
|
141
|
+
return indicators.some((pattern) => pattern.test(content));
|
|
142
|
+
}
|
|
143
|
+
const AST_PATTERNS = [
|
|
144
|
+
{
|
|
145
|
+
id: "AST_EVAL_DYNAMIC",
|
|
146
|
+
title: "eval() with dynamic argument",
|
|
147
|
+
description: "eval() is called with a non-literal argument (variable or expression). This executes arbitrary code at runtime, making static analysis impossible.",
|
|
148
|
+
severity: "high",
|
|
149
|
+
detect: (node, context) => {
|
|
150
|
+
// Skip in bundled code - bundlers use eval for CSS-in-JS, source maps,
|
|
151
|
+
// hot module replacement, WASM initialization, etc.
|
|
152
|
+
if (context.isBundled && !context.hasObfuscationIndicators)
|
|
153
|
+
return null;
|
|
154
|
+
if (!isCallTo(node, "eval"))
|
|
155
|
+
return null;
|
|
156
|
+
const arg = node.arguments[0];
|
|
157
|
+
if (!arg || isLiteral(arg))
|
|
158
|
+
return null;
|
|
159
|
+
const span = node;
|
|
160
|
+
return {
|
|
161
|
+
start: span.start,
|
|
162
|
+
end: span.end,
|
|
163
|
+
codeSnippet: getCodeSnippet(context.content, span.start, span.end, context.lineStarts),
|
|
164
|
+
additionalInfo: context.hasObfuscationIndicators
|
|
165
|
+
? "Combined with obfuscation indicators"
|
|
166
|
+
: null,
|
|
167
|
+
};
|
|
168
|
+
},
|
|
169
|
+
legitimateUses: ["REPL implementations", "Dynamic expression evaluators"],
|
|
170
|
+
redFlags: ["Argument is decoded/decrypted value", "Combined with obfuscation"],
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
id: "AST_FUNCTION_CONSTRUCTOR",
|
|
174
|
+
title: "Function() constructor creates code from string",
|
|
175
|
+
description: "new Function() creates executable code from strings, similar to eval(). This can execute arbitrary code and bypass static analysis.",
|
|
176
|
+
severity: "high",
|
|
177
|
+
detect: (node, context) => {
|
|
178
|
+
if (!isNewExpression(node, "Function"))
|
|
179
|
+
return null;
|
|
180
|
+
// Skip in bundled code - webpack/rollup use Function() for module loading
|
|
181
|
+
if (context.isBundled && !context.hasObfuscationIndicators)
|
|
182
|
+
return null;
|
|
183
|
+
// Check if any argument is non-literal
|
|
184
|
+
const hasDynamicArg = node.arguments.some((arg) => !isLiteral(arg));
|
|
185
|
+
const span = node;
|
|
186
|
+
return {
|
|
187
|
+
start: span.start,
|
|
188
|
+
end: span.end,
|
|
189
|
+
codeSnippet: getCodeSnippet(context.content, span.start, span.end, context.lineStarts),
|
|
190
|
+
additionalInfo: hasDynamicArg ? "Uses dynamic (non-literal) argument" : null,
|
|
191
|
+
};
|
|
192
|
+
},
|
|
193
|
+
legitimateUses: ["Template compilation", "Code generators", "Bundlers"],
|
|
194
|
+
redFlags: ["Dynamic arguments", "Combined with decode functions"],
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
id: "AST_DYNAMIC_REQUIRE",
|
|
198
|
+
title: "require() with dynamic argument",
|
|
199
|
+
description: "require() is called with a variable or expression instead of a string literal. This can load arbitrary modules at runtime.",
|
|
200
|
+
severity: "medium",
|
|
201
|
+
detect: (node, context) => {
|
|
202
|
+
// Skip in bundled code - __webpack_require__ uses dynamic requires
|
|
203
|
+
if (context.isBundled)
|
|
204
|
+
return null;
|
|
205
|
+
if (node.type !== "CallExpression")
|
|
206
|
+
return null;
|
|
207
|
+
const callExpr = node;
|
|
208
|
+
if (!isIdentifier(callExpr.callee, "require")) {
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
const arg = callExpr.arguments[0];
|
|
212
|
+
if (!arg || isLiteral(arg))
|
|
213
|
+
return null;
|
|
214
|
+
const span = node;
|
|
215
|
+
return {
|
|
216
|
+
start: span.start,
|
|
217
|
+
end: span.end,
|
|
218
|
+
codeSnippet: getCodeSnippet(context.content, span.start, span.end, context.lineStarts),
|
|
219
|
+
additionalInfo: null,
|
|
220
|
+
};
|
|
221
|
+
},
|
|
222
|
+
legitimateUses: ["Plugin systems", "Dynamic module loading", "Bundlers"],
|
|
223
|
+
redFlags: ["Module name from network", "Combined with obfuscation"],
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
id: "AST_DYNAMIC_IMPORT",
|
|
227
|
+
title: "Dynamic import() with non-literal source",
|
|
228
|
+
description: "import() is called with a variable or expression. This can load arbitrary modules at runtime.",
|
|
229
|
+
severity: "medium",
|
|
230
|
+
detect: (node, context) => {
|
|
231
|
+
// OXC uses ImportExpression for dynamic imports
|
|
232
|
+
if (node.type !== "ImportExpression")
|
|
233
|
+
return null;
|
|
234
|
+
const importExpr = node;
|
|
235
|
+
const source = importExpr.source;
|
|
236
|
+
if (isLiteral(source))
|
|
237
|
+
return null;
|
|
238
|
+
const span = node;
|
|
239
|
+
return {
|
|
240
|
+
start: span.start,
|
|
241
|
+
end: span.end,
|
|
242
|
+
codeSnippet: getCodeSnippet(context.content, span.start, span.end, context.lineStarts),
|
|
243
|
+
additionalInfo: null,
|
|
244
|
+
};
|
|
245
|
+
},
|
|
246
|
+
legitimateUses: ["Lazy loading", "Code splitting"],
|
|
247
|
+
redFlags: ["Module URL from network", "User-controlled path"],
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
id: "AST_INDIRECT_CALL",
|
|
251
|
+
title: "Indirect function call via computed property",
|
|
252
|
+
description: "Function is called using computed property access like obj[var](). This can hide which function is being called.",
|
|
253
|
+
severity: "low",
|
|
254
|
+
detect: (node, context) => {
|
|
255
|
+
// Skip in bundled code - this is extremely common in bundled code
|
|
256
|
+
if (context.isBundled)
|
|
257
|
+
return null;
|
|
258
|
+
if (node.type !== "CallExpression")
|
|
259
|
+
return null;
|
|
260
|
+
const callExpr = node;
|
|
261
|
+
if (callExpr.callee.type !== "MemberExpression")
|
|
262
|
+
return null;
|
|
263
|
+
const memberExpr = callExpr.callee;
|
|
264
|
+
if (!memberExpr.computed)
|
|
265
|
+
return null;
|
|
266
|
+
// Skip if property is a literal
|
|
267
|
+
if (isLiteral(memberExpr.property))
|
|
268
|
+
return null;
|
|
269
|
+
// Only flag in obfuscated contexts
|
|
270
|
+
if (!context.hasObfuscationIndicators)
|
|
271
|
+
return null;
|
|
272
|
+
const span = node;
|
|
273
|
+
return {
|
|
274
|
+
start: span.start,
|
|
275
|
+
end: span.end,
|
|
276
|
+
codeSnippet: getCodeSnippet(context.content, span.start, span.end, context.lineStarts),
|
|
277
|
+
additionalInfo: "Appears in obfuscated code context",
|
|
278
|
+
};
|
|
279
|
+
},
|
|
280
|
+
redFlags: ["Property name is computed/decoded"],
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
id: "AST_PROCESS_BINDING",
|
|
284
|
+
title: "Access to process internal bindings",
|
|
285
|
+
description: "Code accesses process.binding() or process._linkedBinding() which provide access to Node.js internals and can bypass security restrictions.",
|
|
286
|
+
severity: "high",
|
|
287
|
+
detect: (node, context) => {
|
|
288
|
+
if (!isCallTo(node, ["binding", "_linkedBinding"]))
|
|
289
|
+
return null;
|
|
290
|
+
// Check if it's on process object
|
|
291
|
+
const callExpr = node;
|
|
292
|
+
if (callExpr.callee.type !== "MemberExpression")
|
|
293
|
+
return null;
|
|
294
|
+
const memberExpr = callExpr.callee;
|
|
295
|
+
if (!isIdentifier(memberExpr.object, "process"))
|
|
296
|
+
return null;
|
|
297
|
+
const span = node;
|
|
298
|
+
return {
|
|
299
|
+
start: span.start,
|
|
300
|
+
end: span.end,
|
|
301
|
+
codeSnippet: getCodeSnippet(context.content, span.start, span.end, context.lineStarts),
|
|
302
|
+
additionalInfo: null,
|
|
303
|
+
};
|
|
304
|
+
},
|
|
305
|
+
redFlags: ["Access to internal modules", "Bypass security checks"],
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
id: "AST_GLOBAL_THIS_EVAL",
|
|
309
|
+
title: "eval accessed via globalThis/window/global",
|
|
310
|
+
description: "Code accesses eval through global object property access, which can evade simple eval detection.",
|
|
311
|
+
severity: "high",
|
|
312
|
+
detect: (node, context) => {
|
|
313
|
+
if (node.type !== "MemberExpression")
|
|
314
|
+
return null;
|
|
315
|
+
const memberExpr = node;
|
|
316
|
+
const obj = memberExpr.object;
|
|
317
|
+
if (!isIdentifier(obj))
|
|
318
|
+
return null;
|
|
319
|
+
const objName = getIdentifierName(obj);
|
|
320
|
+
if (!objName || !["globalThis", "window", "global", "self"].includes(objName)) {
|
|
321
|
+
return null;
|
|
322
|
+
}
|
|
323
|
+
const prop = memberExpr.property;
|
|
324
|
+
if (isIdentifier(prop, "eval")) {
|
|
325
|
+
const span = node;
|
|
326
|
+
return {
|
|
327
|
+
start: span.start,
|
|
328
|
+
end: span.end,
|
|
329
|
+
codeSnippet: getCodeSnippet(context.content, span.start, span.end, context.lineStarts),
|
|
330
|
+
additionalInfo: null,
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
// Check string literal property: globalThis["eval"]
|
|
334
|
+
// OXC uses "Literal" type for string literals (ESTree spec)
|
|
335
|
+
if (prop.type === "Literal") {
|
|
336
|
+
const strLiteral = prop;
|
|
337
|
+
if (strLiteral.value === "eval") {
|
|
338
|
+
const span = node;
|
|
339
|
+
return {
|
|
340
|
+
start: span.start,
|
|
341
|
+
end: span.end,
|
|
342
|
+
codeSnippet: getCodeSnippet(context.content, span.start, span.end, context.lineStarts),
|
|
343
|
+
additionalInfo: null,
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return null;
|
|
348
|
+
},
|
|
349
|
+
redFlags: ["Evasion of eval detection"],
|
|
350
|
+
},
|
|
351
|
+
];
|
|
352
|
+
/**
|
|
353
|
+
* Parse and analyze a JavaScript/TypeScript file for suspicious patterns.
|
|
354
|
+
*/
|
|
355
|
+
function analyzeFile(filename, content) {
|
|
356
|
+
const findings = [];
|
|
357
|
+
// Determine lang from extension
|
|
358
|
+
const ext = filename.slice(filename.lastIndexOf(".")).toLowerCase();
|
|
359
|
+
const langMap = {
|
|
360
|
+
".js": "js",
|
|
361
|
+
".mjs": "js",
|
|
362
|
+
".cjs": "js",
|
|
363
|
+
".jsx": "jsx",
|
|
364
|
+
".ts": "ts",
|
|
365
|
+
".tsx": "tsx",
|
|
366
|
+
};
|
|
367
|
+
const lang = langMap[ext] || "tsx"; // Default to tsx for maximum compatibility
|
|
368
|
+
// Try to parse the file
|
|
369
|
+
let result;
|
|
370
|
+
try {
|
|
371
|
+
result = parseSync(filename, content, {
|
|
372
|
+
lang,
|
|
373
|
+
sourceType: "unambiguous",
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
catch {
|
|
377
|
+
// If parsing fails, skip this file
|
|
378
|
+
return findings;
|
|
379
|
+
}
|
|
380
|
+
// If there are errors, skip this file (error recovery mode)
|
|
381
|
+
if (result.errors.length > 0) {
|
|
382
|
+
return findings;
|
|
383
|
+
}
|
|
384
|
+
const bundlerInfo = detectBundler(content, filename);
|
|
385
|
+
const lineStarts = computeLineStarts(content);
|
|
386
|
+
const context = {
|
|
387
|
+
filename,
|
|
388
|
+
content,
|
|
389
|
+
hasObfuscationIndicators: hasObfuscationIndicators(content) || hasGenuineObfuscation(content),
|
|
390
|
+
isBundled: bundlerInfo.isBundled,
|
|
391
|
+
lineStarts,
|
|
392
|
+
};
|
|
393
|
+
const seenFindings = new Set();
|
|
394
|
+
const addFinding = (pattern, match) => {
|
|
395
|
+
const line = offsetToLine(match.start, lineStarts);
|
|
396
|
+
const key = `${pattern.id}:${filename}:${line}`;
|
|
397
|
+
if (seenFindings.has(key))
|
|
398
|
+
return;
|
|
399
|
+
seenFindings.add(key);
|
|
400
|
+
const finding = {
|
|
401
|
+
id: pattern.id,
|
|
402
|
+
title: pattern.title,
|
|
403
|
+
description: pattern.description,
|
|
404
|
+
severity: pattern.severity,
|
|
405
|
+
category: "ast",
|
|
406
|
+
location: {
|
|
407
|
+
file: filename,
|
|
408
|
+
line,
|
|
409
|
+
column: offsetToColumn(match.start, lineStarts),
|
|
410
|
+
},
|
|
411
|
+
metadata: {
|
|
412
|
+
codeSnippet: match.codeSnippet,
|
|
413
|
+
...(pattern.legitimateUses && {
|
|
414
|
+
legitimateUses: pattern.legitimateUses,
|
|
415
|
+
}),
|
|
416
|
+
...(pattern.redFlags && { redFlags: pattern.redFlags }),
|
|
417
|
+
},
|
|
418
|
+
};
|
|
419
|
+
if (match.additionalInfo) {
|
|
420
|
+
finding.metadata["additionalInfo"] = match.additionalInfo;
|
|
421
|
+
}
|
|
422
|
+
findings.push(finding);
|
|
423
|
+
};
|
|
424
|
+
// Process patterns for each node type using typed visitors
|
|
425
|
+
const processNode = (node) => {
|
|
426
|
+
for (const pattern of AST_PATTERNS) {
|
|
427
|
+
const match = pattern.detect(node, context);
|
|
428
|
+
if (match)
|
|
429
|
+
addFinding(pattern, match);
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
const visitor = new Visitor({
|
|
433
|
+
CallExpression(node) {
|
|
434
|
+
processNode(node);
|
|
435
|
+
},
|
|
436
|
+
NewExpression(node) {
|
|
437
|
+
processNode(node);
|
|
438
|
+
},
|
|
439
|
+
MemberExpression(node) {
|
|
440
|
+
processNode(node);
|
|
441
|
+
},
|
|
442
|
+
ImportExpression(node) {
|
|
443
|
+
processNode(node);
|
|
444
|
+
},
|
|
445
|
+
});
|
|
446
|
+
visitor.visit(result.program);
|
|
447
|
+
return findings;
|
|
448
|
+
}
|
|
449
|
+
export function checkAST(contents) {
|
|
450
|
+
const findings = [];
|
|
451
|
+
for (const [filename, buffer] of contents.files) {
|
|
452
|
+
// Skip vendor/third-party code - extension authors don't control this code
|
|
453
|
+
// and popular packages like protobufjs, @babel/*, pino legitimately use eval/Function
|
|
454
|
+
if (filename.includes("node_modules/") || filename.includes("vendor/")) {
|
|
455
|
+
continue;
|
|
456
|
+
}
|
|
457
|
+
// Only analyze JS/TS files
|
|
458
|
+
if (!isScannable(filename, SCANNABLE_EXTENSIONS_PATTERN))
|
|
459
|
+
continue;
|
|
460
|
+
// Skip non-JS/TS files that might be in the scannable set (like .sh, .ps1)
|
|
461
|
+
const ext = filename.slice(filename.lastIndexOf(".")).toLowerCase();
|
|
462
|
+
if (![".js", ".ts", ".mjs", ".cjs", ".jsx", ".tsx"].includes(ext))
|
|
463
|
+
continue;
|
|
464
|
+
const content = buffer.toString("utf8");
|
|
465
|
+
findings.push(...analyzeFile(filename, content));
|
|
466
|
+
}
|
|
467
|
+
return findings;
|
|
468
|
+
}
|
|
469
|
+
//# sourceMappingURL=ast.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast.js","sourceRoot":"","sources":["../../../src/scanner/checks/ast.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast.test.d.ts","sourceRoot":"","sources":["../../../src/scanner/checks/ast.test.ts"],"names":[],"mappings":""}
|