@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,422 @@
|
|
|
1
|
+
// Known-good packages that are NOT typosquats despite edit distance
|
|
2
|
+
// These are legitimate packages that happen to be similar to popular packages
|
|
3
|
+
const KNOWN_GOOD_PACKAGES = new Set([
|
|
4
|
+
// Testing and utilities
|
|
5
|
+
"chai", // Testing library, not typosquat of chalk
|
|
6
|
+
"async", // Async utilities, legitimate
|
|
7
|
+
"debug", // Debug logging, legitimate
|
|
8
|
+
// URL/file openers
|
|
9
|
+
"open", // URL opener, not typosquat of openai
|
|
10
|
+
"opener", // URL/file opener, not typosquat of openai
|
|
11
|
+
// Linters (all legitimate, not typosquats of eslint)
|
|
12
|
+
"tslint", // TypeScript linter (deprecated but legitimate)
|
|
13
|
+
"xqlint", // XQuery linter
|
|
14
|
+
// UUID and ID libraries
|
|
15
|
+
"uuid4", // UUID v4 package, not typosquat of uuid
|
|
16
|
+
"uuidv4", // Another UUID v4 package, not typosquat of uuid
|
|
17
|
+
"ulid", // ULID library, different from UUID
|
|
18
|
+
// Node.js core module shims
|
|
19
|
+
"util", // Node.js util shim, not typosquat of uuid
|
|
20
|
+
"os", // Node.js os shim, not typosquat of cors
|
|
21
|
+
// Database drivers
|
|
22
|
+
"mssql", // Microsoft SQL Server driver, not typosquat of mysql
|
|
23
|
+
"mysql2", // MySQL2 driver (successor to mysql package)
|
|
24
|
+
// React ecosystem
|
|
25
|
+
"preact", // Lightweight React alternative, not typosquat
|
|
26
|
+
// CLI utilities
|
|
27
|
+
"colors", // CLI colors, not typosquat of cors
|
|
28
|
+
// Build/config utilities
|
|
29
|
+
"core", // Common name, not typosquat of cors
|
|
30
|
+
"acorn", // JS parser, not typosquat of cors
|
|
31
|
+
"cpr", // Recursive copy, not typosquat of cors
|
|
32
|
+
"dotenv-expand", // dotenv companion, not typosquat
|
|
33
|
+
"cross-spawn", // Spawn helper, not typosquat of cross-env
|
|
34
|
+
"defu", // Deep defaults utility (unjs), not typosquat of debug
|
|
35
|
+
"jsonc", // JSON with Comments parser, not typosquat of async
|
|
36
|
+
]);
|
|
37
|
+
// Popular packages and their common typosquats
|
|
38
|
+
const POPULAR_PACKAGES = new Map([
|
|
39
|
+
["lodash", ["lodahs", "lodashs", "loadsh", "lodaash", "lo-dash", "lodassh"]],
|
|
40
|
+
["express", ["expres", "expresss", "exprees", "xpress"]],
|
|
41
|
+
["react", ["reect", "raect", "reactt", "reakt"]],
|
|
42
|
+
["axios", ["axois", "axio", "axioss", "axiosjs"]],
|
|
43
|
+
["moment", ["momment", "momnent", "momentjs"]],
|
|
44
|
+
["webpack", ["webpak", "webpackk", "web-pack"]],
|
|
45
|
+
["babel", ["babell", "bable", "babeel"]],
|
|
46
|
+
["eslint", ["esslint", "eslnt", "eslintjs"]],
|
|
47
|
+
["typescript", ["typscript", "tyepscript", "typescipt"]],
|
|
48
|
+
["mongoose", ["mongose", "mongoos", "mongoosee"]],
|
|
49
|
+
["jquery", ["jquerry", "jqeury", "jqueryjs", "jquery.js"]],
|
|
50
|
+
["chalk", ["challk", "chaulk", "chak"]],
|
|
51
|
+
["commander", ["comandar", "comander", "commanderjs"]],
|
|
52
|
+
["request", ["reqest", "requets", "requestjs"]],
|
|
53
|
+
["underscore", ["undrscore", "undescore", "underscorejs"]],
|
|
54
|
+
["async", ["asnyc", "asyncjs", "asynic"]],
|
|
55
|
+
["debug", ["debuf", "debgu", "debugjs"]],
|
|
56
|
+
["uuid", ["uuuid", "uuidjs", "uiid"]],
|
|
57
|
+
["dotenv", ["dtoenv", "dotenvjs", "dot-env"]],
|
|
58
|
+
["cors", ["corss", "corsjs", "cros"]],
|
|
59
|
+
["cross-env", ["crossenv", "cross-env.js", "cros-env"]],
|
|
60
|
+
["mysql", ["mysqljs", "my-sql", "mysqll"]],
|
|
61
|
+
["sqlite3", ["sqliter", "sqlite.js", "sqllite3"]],
|
|
62
|
+
["openai", ["openai-api", "open-ai", "openaijs"]],
|
|
63
|
+
["anthropic", ["anthropic-api", "anthopic", "antropic"]],
|
|
64
|
+
["langchain", ["langchain-core", "lang-chain", "langchainjs"]],
|
|
65
|
+
]);
|
|
66
|
+
// Dangerous npm lifecycle scripts
|
|
67
|
+
const DANGEROUS_SCRIPTS = [
|
|
68
|
+
"preinstall",
|
|
69
|
+
"postinstall",
|
|
70
|
+
"preuninstall",
|
|
71
|
+
"postuninstall",
|
|
72
|
+
"prepublish",
|
|
73
|
+
"postpublish",
|
|
74
|
+
];
|
|
75
|
+
// Patterns that indicate malicious script content
|
|
76
|
+
const MALICIOUS_SCRIPT_PATTERNS = [
|
|
77
|
+
{ pattern: /curl\s+.*\|\s*(ba)?sh/i, desc: "Downloads and executes remote script" },
|
|
78
|
+
{ pattern: /wget\s+.*\|\s*(ba)?sh/i, desc: "Downloads and executes remote script" },
|
|
79
|
+
{ pattern: /eval\s*\(.*\$\(/i, desc: "Eval with command substitution" },
|
|
80
|
+
{ pattern: /node\s+-e\s+.*atob/i, desc: "Node.js eval with base64 decode" },
|
|
81
|
+
{ pattern: /powershell.*-enc/i, desc: "Encoded PowerShell command" },
|
|
82
|
+
{ pattern: /\bexec\s*\(.*http/i, desc: "Executes remote content" },
|
|
83
|
+
{ pattern: /\.ssh\/id_/i, desc: "SSH key access" },
|
|
84
|
+
{ pattern: /discord\.com\/api\/webhooks/i, desc: "Discord webhook (data exfiltration)" },
|
|
85
|
+
{ pattern: /crypto.*wallet/i, desc: "Cryptocurrency wallet access" },
|
|
86
|
+
{ pattern: /APPDATA.*Chrome/i, desc: "Chrome browser data access" },
|
|
87
|
+
{ pattern: /\.credentials/i, desc: "Credential file access" },
|
|
88
|
+
{ pattern: /keychain|keyring/i, desc: "System keychain access" },
|
|
89
|
+
];
|
|
90
|
+
function levenshteinDistance(a, b) {
|
|
91
|
+
const matrix = [];
|
|
92
|
+
for (let i = 0; i <= b.length; i++) {
|
|
93
|
+
matrix[i] = [i];
|
|
94
|
+
}
|
|
95
|
+
const firstRow = matrix[0];
|
|
96
|
+
if (!firstRow)
|
|
97
|
+
return 0;
|
|
98
|
+
for (let j = 0; j <= a.length; j++) {
|
|
99
|
+
firstRow[j] = j;
|
|
100
|
+
}
|
|
101
|
+
for (let i = 1; i <= b.length; i++) {
|
|
102
|
+
const currentRow = matrix[i];
|
|
103
|
+
const prevRow = matrix[i - 1];
|
|
104
|
+
if (!currentRow || !prevRow)
|
|
105
|
+
continue;
|
|
106
|
+
for (let j = 1; j <= a.length; j++) {
|
|
107
|
+
if (b.charAt(i - 1) === a.charAt(j - 1)) {
|
|
108
|
+
currentRow[j] = prevRow[j - 1] ?? 0;
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
currentRow[j] = Math.min((prevRow[j - 1] ?? 0) + 1, // substitution
|
|
112
|
+
(currentRow[j - 1] ?? 0) + 1, // insertion
|
|
113
|
+
(prevRow[j] ?? 0) + 1);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return matrix[b.length]?.[a.length] ?? 0;
|
|
118
|
+
}
|
|
119
|
+
function checkTyposquatting(pkgName) {
|
|
120
|
+
const lowerName = pkgName.toLowerCase();
|
|
121
|
+
// Skip known-good packages that are NOT typosquats
|
|
122
|
+
if (KNOWN_GOOD_PACKAGES.has(lowerName)) {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
// First check known typosquats
|
|
126
|
+
for (const [popular, typos] of POPULAR_PACKAGES) {
|
|
127
|
+
if (typos.includes(lowerName)) {
|
|
128
|
+
return { target: popular, distance: 1 };
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Then check by edit distance for short package names
|
|
132
|
+
for (const [popular] of POPULAR_PACKAGES) {
|
|
133
|
+
// Only check if package name is similar length
|
|
134
|
+
if (Math.abs(pkgName.length - popular.length) > 2)
|
|
135
|
+
continue;
|
|
136
|
+
const distance = levenshteinDistance(lowerName, popular);
|
|
137
|
+
// Flag if edit distance is 1-2 and names are not identical
|
|
138
|
+
if (distance > 0 && distance <= 2 && lowerName !== popular) {
|
|
139
|
+
return { target: popular, distance };
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
// --- Blocklist check ---
|
|
145
|
+
function matchesWildcard(extensionId, pattern) {
|
|
146
|
+
const lowerId = extensionId.toLowerCase();
|
|
147
|
+
const lowerPattern = pattern.toLowerCase();
|
|
148
|
+
if (lowerPattern.endsWith(".*")) {
|
|
149
|
+
const prefix = lowerPattern.slice(0, -2);
|
|
150
|
+
return lowerId.startsWith(prefix + ".");
|
|
151
|
+
}
|
|
152
|
+
return lowerId === lowerPattern;
|
|
153
|
+
}
|
|
154
|
+
export function checkBlocklist(manifest, blocklist) {
|
|
155
|
+
const findings = [];
|
|
156
|
+
const extensionId = `${manifest.publisher}.${manifest.name}`;
|
|
157
|
+
for (const entry of blocklist) {
|
|
158
|
+
if (matchesWildcard(extensionId, entry.id)) {
|
|
159
|
+
findings.push({
|
|
160
|
+
id: "BLOCKLIST_MATCH",
|
|
161
|
+
title: "Extension on malware blocklist",
|
|
162
|
+
description: `Extension "${extensionId}" matches blocklisted pattern "${entry.id}": ${entry.reason}`,
|
|
163
|
+
severity: "critical",
|
|
164
|
+
category: "blocklist",
|
|
165
|
+
location: {
|
|
166
|
+
file: "package.json",
|
|
167
|
+
},
|
|
168
|
+
metadata: {
|
|
169
|
+
campaign: entry.campaign,
|
|
170
|
+
reference: entry.reference,
|
|
171
|
+
blocklistEntry: entry.id,
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return findings;
|
|
177
|
+
}
|
|
178
|
+
// --- Manifest checks ---
|
|
179
|
+
export function checkActivationEvents(manifest) {
|
|
180
|
+
const findings = [];
|
|
181
|
+
if (manifest.activationEvents?.includes("*")) {
|
|
182
|
+
findings.push({
|
|
183
|
+
id: "ACTIVATION_WILDCARD",
|
|
184
|
+
title: "Extension activates on all events",
|
|
185
|
+
description: 'Extension uses "activationEvents": ["*"] which activates on every VS Code action. This is often used by malware to ensure immediate execution, but may be legitimate for extensions that need to respond to many different events.',
|
|
186
|
+
severity: "high",
|
|
187
|
+
category: "manifest",
|
|
188
|
+
location: {
|
|
189
|
+
file: "package.json",
|
|
190
|
+
},
|
|
191
|
+
metadata: {
|
|
192
|
+
legitimateUses: ["Extensions with many contribution points", "Global workspace tools"],
|
|
193
|
+
redFlags: [
|
|
194
|
+
"Simple extension with wildcard activation",
|
|
195
|
+
"Combined with suspicious patterns",
|
|
196
|
+
],
|
|
197
|
+
},
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
if (manifest.activationEvents?.includes("onStartupFinished")) {
|
|
201
|
+
findings.push({
|
|
202
|
+
id: "ACTIVATION_STARTUP",
|
|
203
|
+
title: "Extension activates on startup",
|
|
204
|
+
description: 'Extension uses "onStartupFinished" activation event. Common in extensions that need to initialize early (git integration, status bar items, language servers). Review if early activation is necessary for the extension\'s purpose.',
|
|
205
|
+
severity: "medium",
|
|
206
|
+
category: "manifest",
|
|
207
|
+
location: {
|
|
208
|
+
file: "package.json",
|
|
209
|
+
},
|
|
210
|
+
metadata: {
|
|
211
|
+
legitimateUses: [
|
|
212
|
+
"Git integration",
|
|
213
|
+
"Status bar extensions",
|
|
214
|
+
"Language servers",
|
|
215
|
+
"Background services",
|
|
216
|
+
],
|
|
217
|
+
redFlags: [
|
|
218
|
+
"Combined with network activity on startup",
|
|
219
|
+
"No obvious need for early activation",
|
|
220
|
+
],
|
|
221
|
+
},
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
return findings;
|
|
225
|
+
}
|
|
226
|
+
export function checkThemeAbuse(manifest) {
|
|
227
|
+
const findings = [];
|
|
228
|
+
const hasMain = Boolean(manifest.main || manifest.browser);
|
|
229
|
+
const hasThemes = (manifest.contributes?.themes?.length ?? 0) > 0 ||
|
|
230
|
+
(manifest.contributes?.iconThemes?.length ?? 0) > 0;
|
|
231
|
+
if (hasThemes && hasMain) {
|
|
232
|
+
findings.push({
|
|
233
|
+
id: "THEME_WITH_CODE",
|
|
234
|
+
title: "Theme extension has code entry point",
|
|
235
|
+
description: "This extension contributes themes/icon themes but also has a code entry point (main/browser). Pure themes don't need executable code. However, some legitimate extensions combine themes with additional functionality (commands, settings sync).",
|
|
236
|
+
severity: "high",
|
|
237
|
+
category: "manifest",
|
|
238
|
+
location: {
|
|
239
|
+
file: "package.json",
|
|
240
|
+
},
|
|
241
|
+
metadata: {
|
|
242
|
+
main: manifest.main,
|
|
243
|
+
browser: manifest.browser,
|
|
244
|
+
themes: manifest.contributes?.themes?.length ?? 0,
|
|
245
|
+
iconThemes: manifest.contributes?.iconThemes?.length ?? 0,
|
|
246
|
+
legitimateUses: [
|
|
247
|
+
"Theme packs with additional commands",
|
|
248
|
+
"Theme switchers",
|
|
249
|
+
"Theme previews",
|
|
250
|
+
],
|
|
251
|
+
redFlags: [
|
|
252
|
+
"Theme-only description but runs code",
|
|
253
|
+
"Network activity from theme extension",
|
|
254
|
+
"Known malware pattern",
|
|
255
|
+
],
|
|
256
|
+
},
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
return findings;
|
|
260
|
+
}
|
|
261
|
+
export function checkSuspiciousPermissions(manifest) {
|
|
262
|
+
const findings = [];
|
|
263
|
+
const extensionDependencies = manifest["extensionDependencies"];
|
|
264
|
+
if (extensionDependencies) {
|
|
265
|
+
for (const dep of extensionDependencies) {
|
|
266
|
+
if (dep.includes("remote-ssh") || dep.includes("remote-wsl")) {
|
|
267
|
+
findings.push({
|
|
268
|
+
id: "REMOTE_DEPENDENCY",
|
|
269
|
+
title: "Extension depends on remote access extension",
|
|
270
|
+
description: `Extension depends on "${dep}" which provides remote system access. This is expected for extensions that enhance remote development workflows.`,
|
|
271
|
+
severity: "medium",
|
|
272
|
+
category: "manifest",
|
|
273
|
+
location: {
|
|
274
|
+
file: "package.json",
|
|
275
|
+
},
|
|
276
|
+
metadata: {
|
|
277
|
+
dependency: dep,
|
|
278
|
+
legitimateUses: [
|
|
279
|
+
"Remote development helpers",
|
|
280
|
+
"SSH workflow tools",
|
|
281
|
+
"Container development",
|
|
282
|
+
],
|
|
283
|
+
redFlags: [
|
|
284
|
+
"No clear remote development purpose",
|
|
285
|
+
"Combined with credential access patterns",
|
|
286
|
+
],
|
|
287
|
+
},
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return findings;
|
|
293
|
+
}
|
|
294
|
+
// --- Dependency checks ---
|
|
295
|
+
export function checkMaliciousPackages(packageJson, maliciousPackages) {
|
|
296
|
+
const findings = [];
|
|
297
|
+
// Only check runtime dependencies, not devDependencies
|
|
298
|
+
// devDependencies aren't bundled in .vsix files and only used during development
|
|
299
|
+
const deps = packageJson.dependencies ?? {};
|
|
300
|
+
for (const pkgName of Object.keys(deps)) {
|
|
301
|
+
if (maliciousPackages.has(pkgName.toLowerCase())) {
|
|
302
|
+
findings.push({
|
|
303
|
+
id: "MALICIOUS_NPM_PACKAGE",
|
|
304
|
+
title: "Known malicious npm package",
|
|
305
|
+
description: `Dependency "${pkgName}" is a known malicious npm package. This package has been identified in previous attacks and should be removed immediately.`,
|
|
306
|
+
severity: "critical",
|
|
307
|
+
category: "dependency",
|
|
308
|
+
location: {
|
|
309
|
+
file: "package.json",
|
|
310
|
+
},
|
|
311
|
+
metadata: {
|
|
312
|
+
package: pkgName,
|
|
313
|
+
},
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return findings;
|
|
318
|
+
}
|
|
319
|
+
export function checkTyposquattingPackages(packageJson) {
|
|
320
|
+
const findings = [];
|
|
321
|
+
const allDeps = {
|
|
322
|
+
...packageJson.dependencies,
|
|
323
|
+
...packageJson.devDependencies,
|
|
324
|
+
};
|
|
325
|
+
for (const pkgName of Object.keys(allDeps)) {
|
|
326
|
+
const typosquat = checkTyposquatting(pkgName);
|
|
327
|
+
if (typosquat) {
|
|
328
|
+
findings.push({
|
|
329
|
+
id: "TYPOSQUAT_PACKAGE",
|
|
330
|
+
title: "Potential typosquatting package",
|
|
331
|
+
description: `Dependency "${pkgName}" is suspiciously similar to popular package "${typosquat.target}" (edit distance: ${typosquat.distance}). This may be a typosquatting attack.`,
|
|
332
|
+
severity: "high",
|
|
333
|
+
category: "dependency",
|
|
334
|
+
location: {
|
|
335
|
+
file: "package.json",
|
|
336
|
+
},
|
|
337
|
+
metadata: {
|
|
338
|
+
package: pkgName,
|
|
339
|
+
similar_to: typosquat.target,
|
|
340
|
+
edit_distance: typosquat.distance,
|
|
341
|
+
},
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
return findings;
|
|
346
|
+
}
|
|
347
|
+
export function checkLifecycleScripts(packageJson) {
|
|
348
|
+
const findings = [];
|
|
349
|
+
const scripts = packageJson.scripts ?? {};
|
|
350
|
+
for (const scriptName of DANGEROUS_SCRIPTS) {
|
|
351
|
+
const scriptContent = scripts[scriptName];
|
|
352
|
+
if (!scriptContent)
|
|
353
|
+
continue;
|
|
354
|
+
// Check for malicious patterns in the script
|
|
355
|
+
for (const { pattern, desc } of MALICIOUS_SCRIPT_PATTERNS) {
|
|
356
|
+
if (pattern.test(scriptContent)) {
|
|
357
|
+
findings.push({
|
|
358
|
+
id: "MALICIOUS_LIFECYCLE_SCRIPT",
|
|
359
|
+
title: `Suspicious ${scriptName} script`,
|
|
360
|
+
description: `The ${scriptName} script contains suspicious content: ${desc}. Lifecycle scripts run automatically during npm install and can execute arbitrary code.`,
|
|
361
|
+
severity: "critical",
|
|
362
|
+
category: "dependency",
|
|
363
|
+
location: {
|
|
364
|
+
file: "package.json",
|
|
365
|
+
},
|
|
366
|
+
metadata: {
|
|
367
|
+
script: scriptName,
|
|
368
|
+
content: scriptContent.slice(0, 200),
|
|
369
|
+
pattern: desc,
|
|
370
|
+
},
|
|
371
|
+
});
|
|
372
|
+
break; // Only report one pattern per script
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
// Also flag any lifecycle script that exists even without malicious patterns
|
|
376
|
+
// as they're a common attack vector
|
|
377
|
+
if (!findings.some((f) => f.id === "MALICIOUS_LIFECYCLE_SCRIPT" && f.metadata?.["script"] === scriptName)) {
|
|
378
|
+
findings.push({
|
|
379
|
+
id: "LIFECYCLE_SCRIPT",
|
|
380
|
+
title: `Has ${scriptName} script`,
|
|
381
|
+
description: `The extension has a ${scriptName} script that runs during installation. While not always malicious, lifecycle scripts are a common attack vector. Review the script content carefully.`,
|
|
382
|
+
severity: "medium",
|
|
383
|
+
category: "dependency",
|
|
384
|
+
location: {
|
|
385
|
+
file: "package.json",
|
|
386
|
+
},
|
|
387
|
+
metadata: {
|
|
388
|
+
script: scriptName,
|
|
389
|
+
content: scriptContent.slice(0, 200),
|
|
390
|
+
},
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
return findings;
|
|
395
|
+
}
|
|
396
|
+
// --- Main export ---
|
|
397
|
+
export function checkPackage(contents, zooData) {
|
|
398
|
+
const { manifest } = contents;
|
|
399
|
+
const findings = [];
|
|
400
|
+
// Blocklist check
|
|
401
|
+
findings.push(...checkBlocklist(manifest, zooData.blocklist));
|
|
402
|
+
// Manifest checks (use manifest object directly)
|
|
403
|
+
findings.push(...checkActivationEvents(manifest));
|
|
404
|
+
findings.push(...checkThemeAbuse(manifest));
|
|
405
|
+
findings.push(...checkSuspiciousPermissions(manifest));
|
|
406
|
+
// Dependencies checks (parse package.json from files)
|
|
407
|
+
const packageJsonBuffer = contents.files.get("package.json");
|
|
408
|
+
if (packageJsonBuffer) {
|
|
409
|
+
let packageJson;
|
|
410
|
+
try {
|
|
411
|
+
packageJson = JSON.parse(packageJsonBuffer.toString("utf8"));
|
|
412
|
+
}
|
|
413
|
+
catch {
|
|
414
|
+
return findings;
|
|
415
|
+
}
|
|
416
|
+
findings.push(...checkMaliciousPackages(packageJson, zooData.maliciousNpmPackages));
|
|
417
|
+
findings.push(...checkTyposquattingPackages(packageJson));
|
|
418
|
+
findings.push(...checkLifecycleScripts(packageJson));
|
|
419
|
+
}
|
|
420
|
+
return findings;
|
|
421
|
+
}
|
|
422
|
+
//# sourceMappingURL=package.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package.js","sourceRoot":"","sources":["../../../src/scanner/checks/package.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package.test.d.ts","sourceRoot":"","sources":["../../../src/scanner/checks/package.test.ts"],"names":[],"mappings":""}
|