@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.
Files changed (197) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +281 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +703 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/index.d.ts +3 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +4 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/scanner/batch.d.ts +12 -0
  12. package/dist/scanner/batch.d.ts.map +1 -0
  13. package/dist/scanner/batch.js +104 -0
  14. package/dist/scanner/batch.js.map +1 -0
  15. package/dist/scanner/bundler.d.ts +35 -0
  16. package/dist/scanner/bundler.d.ts.map +1 -0
  17. package/dist/scanner/bundler.js +120 -0
  18. package/dist/scanner/bundler.js.map +1 -0
  19. package/dist/scanner/cache.d.ts +45 -0
  20. package/dist/scanner/cache.d.ts.map +1 -0
  21. package/dist/scanner/cache.js +153 -0
  22. package/dist/scanner/cache.js.map +1 -0
  23. package/dist/scanner/cache.test.d.ts +2 -0
  24. package/dist/scanner/cache.test.d.ts.map +1 -0
  25. package/dist/scanner/cache.test.js +149 -0
  26. package/dist/scanner/cache.test.js.map +1 -0
  27. package/dist/scanner/capabilities.d.ts +29 -0
  28. package/dist/scanner/capabilities.d.ts.map +1 -0
  29. package/dist/scanner/capabilities.js +217 -0
  30. package/dist/scanner/capabilities.js.map +1 -0
  31. package/dist/scanner/checks/ast.d.ts +3 -0
  32. package/dist/scanner/checks/ast.d.ts.map +1 -0
  33. package/dist/scanner/checks/ast.js +469 -0
  34. package/dist/scanner/checks/ast.js.map +1 -0
  35. package/dist/scanner/checks/ast.test.d.ts +2 -0
  36. package/dist/scanner/checks/ast.test.d.ts.map +1 -0
  37. package/dist/scanner/checks/ast.test.js +389 -0
  38. package/dist/scanner/checks/ast.test.js.map +1 -0
  39. package/dist/scanner/checks/behavioral.d.ts +3 -0
  40. package/dist/scanner/checks/behavioral.d.ts.map +1 -0
  41. package/dist/scanner/checks/behavioral.js +367 -0
  42. package/dist/scanner/checks/behavioral.js.map +1 -0
  43. package/dist/scanner/checks/blocklist.d.ts +3 -0
  44. package/dist/scanner/checks/blocklist.d.ts.map +1 -0
  45. package/dist/scanner/checks/blocklist.js +32 -0
  46. package/dist/scanner/checks/blocklist.js.map +1 -0
  47. package/dist/scanner/checks/blocklist.test.d.ts +2 -0
  48. package/dist/scanner/checks/blocklist.test.d.ts.map +1 -0
  49. package/dist/scanner/checks/blocklist.test.js +74 -0
  50. package/dist/scanner/checks/blocklist.test.js.map +1 -0
  51. package/dist/scanner/checks/chains.d.ts +35 -0
  52. package/dist/scanner/checks/chains.d.ts.map +1 -0
  53. package/dist/scanner/checks/chains.js +505 -0
  54. package/dist/scanner/checks/chains.js.map +1 -0
  55. package/dist/scanner/checks/chains.test.d.ts +2 -0
  56. package/dist/scanner/checks/chains.test.d.ts.map +1 -0
  57. package/dist/scanner/checks/chains.test.js +250 -0
  58. package/dist/scanner/checks/chains.test.js.map +1 -0
  59. package/dist/scanner/checks/dataflow.d.ts +3 -0
  60. package/dist/scanner/checks/dataflow.d.ts.map +1 -0
  61. package/dist/scanner/checks/dataflow.js +316 -0
  62. package/dist/scanner/checks/dataflow.js.map +1 -0
  63. package/dist/scanner/checks/dependencies.d.ts +13 -0
  64. package/dist/scanner/checks/dependencies.d.ts.map +1 -0
  65. package/dist/scanner/checks/dependencies.js +225 -0
  66. package/dist/scanner/checks/dependencies.js.map +1 -0
  67. package/dist/scanner/checks/dependencies.test.d.ts +2 -0
  68. package/dist/scanner/checks/dependencies.test.d.ts.map +1 -0
  69. package/dist/scanner/checks/dependencies.test.js +248 -0
  70. package/dist/scanner/checks/dependencies.test.js.map +1 -0
  71. package/dist/scanner/checks/finding-quality.test.d.ts +8 -0
  72. package/dist/scanner/checks/finding-quality.test.d.ts.map +1 -0
  73. package/dist/scanner/checks/finding-quality.test.js +164 -0
  74. package/dist/scanner/checks/finding-quality.test.js.map +1 -0
  75. package/dist/scanner/checks/ioc.d.ts +20 -0
  76. package/dist/scanner/checks/ioc.d.ts.map +1 -0
  77. package/dist/scanner/checks/ioc.js +234 -0
  78. package/dist/scanner/checks/ioc.js.map +1 -0
  79. package/dist/scanner/checks/ioc.test.d.ts +2 -0
  80. package/dist/scanner/checks/ioc.test.d.ts.map +1 -0
  81. package/dist/scanner/checks/ioc.test.js +298 -0
  82. package/dist/scanner/checks/ioc.test.js.map +1 -0
  83. package/dist/scanner/checks/manifest.d.ts +6 -0
  84. package/dist/scanner/checks/manifest.d.ts.map +1 -0
  85. package/dist/scanner/checks/manifest.js +123 -0
  86. package/dist/scanner/checks/manifest.js.map +1 -0
  87. package/dist/scanner/checks/manifest.test.d.ts +2 -0
  88. package/dist/scanner/checks/manifest.test.d.ts.map +1 -0
  89. package/dist/scanner/checks/manifest.test.js +108 -0
  90. package/dist/scanner/checks/manifest.test.js.map +1 -0
  91. package/dist/scanner/checks/obfuscation.d.ts +3 -0
  92. package/dist/scanner/checks/obfuscation.d.ts.map +1 -0
  93. package/dist/scanner/checks/obfuscation.js +432 -0
  94. package/dist/scanner/checks/obfuscation.js.map +1 -0
  95. package/dist/scanner/checks/obfuscation.test.d.ts +2 -0
  96. package/dist/scanner/checks/obfuscation.test.d.ts.map +1 -0
  97. package/dist/scanner/checks/obfuscation.test.js +399 -0
  98. package/dist/scanner/checks/obfuscation.test.js.map +1 -0
  99. package/dist/scanner/checks/package.d.ts +17 -0
  100. package/dist/scanner/checks/package.d.ts.map +1 -0
  101. package/dist/scanner/checks/package.js +422 -0
  102. package/dist/scanner/checks/package.js.map +1 -0
  103. package/dist/scanner/checks/package.test.d.ts +2 -0
  104. package/dist/scanner/checks/package.test.d.ts.map +1 -0
  105. package/dist/scanner/checks/package.test.js +518 -0
  106. package/dist/scanner/checks/package.test.js.map +1 -0
  107. package/dist/scanner/checks/patterns.d.ts +5 -0
  108. package/dist/scanner/checks/patterns.d.ts.map +1 -0
  109. package/dist/scanner/checks/patterns.js +251 -0
  110. package/dist/scanner/checks/patterns.js.map +1 -0
  111. package/dist/scanner/checks/patterns.test.d.ts +2 -0
  112. package/dist/scanner/checks/patterns.test.d.ts.map +1 -0
  113. package/dist/scanner/checks/patterns.test.js +147 -0
  114. package/dist/scanner/checks/patterns.test.js.map +1 -0
  115. package/dist/scanner/checks/unicode.d.ts +3 -0
  116. package/dist/scanner/checks/unicode.d.ts.map +1 -0
  117. package/dist/scanner/checks/unicode.js +247 -0
  118. package/dist/scanner/checks/unicode.js.map +1 -0
  119. package/dist/scanner/checks/unicode.test.d.ts +2 -0
  120. package/dist/scanner/checks/unicode.test.d.ts.map +1 -0
  121. package/dist/scanner/checks/unicode.test.js +202 -0
  122. package/dist/scanner/checks/unicode.test.js.map +1 -0
  123. package/dist/scanner/checks/yara.d.ts +23 -0
  124. package/dist/scanner/checks/yara.d.ts.map +1 -0
  125. package/dist/scanner/checks/yara.js +349 -0
  126. package/dist/scanner/checks/yara.js.map +1 -0
  127. package/dist/scanner/checks/yara.test.d.ts +2 -0
  128. package/dist/scanner/checks/yara.test.d.ts.map +1 -0
  129. package/dist/scanner/checks/yara.test.js +126 -0
  130. package/dist/scanner/checks/yara.test.js.map +1 -0
  131. package/dist/scanner/constants.d.ts +18 -0
  132. package/dist/scanner/constants.d.ts.map +1 -0
  133. package/dist/scanner/constants.js +37 -0
  134. package/dist/scanner/constants.js.map +1 -0
  135. package/dist/scanner/detection-coverage.test.d.ts +2 -0
  136. package/dist/scanner/detection-coverage.test.d.ts.map +1 -0
  137. package/dist/scanner/detection-coverage.test.js +216 -0
  138. package/dist/scanner/detection-coverage.test.js.map +1 -0
  139. package/dist/scanner/download.d.ts +76 -0
  140. package/dist/scanner/download.d.ts.map +1 -0
  141. package/dist/scanner/download.js +339 -0
  142. package/dist/scanner/download.js.map +1 -0
  143. package/dist/scanner/download.test.d.ts +2 -0
  144. package/dist/scanner/download.test.d.ts.map +1 -0
  145. package/dist/scanner/download.test.js +149 -0
  146. package/dist/scanner/download.test.js.map +1 -0
  147. package/dist/scanner/index.d.ts +8 -0
  148. package/dist/scanner/index.d.ts.map +1 -0
  149. package/dist/scanner/index.js +167 -0
  150. package/dist/scanner/index.js.map +1 -0
  151. package/dist/scanner/index.test.d.ts +2 -0
  152. package/dist/scanner/index.test.d.ts.map +1 -0
  153. package/dist/scanner/index.test.js +71 -0
  154. package/dist/scanner/index.test.js.map +1 -0
  155. package/dist/scanner/loaders/zoo.d.ts +3 -0
  156. package/dist/scanner/loaders/zoo.d.ts.map +1 -0
  157. package/dist/scanner/loaders/zoo.js +112 -0
  158. package/dist/scanner/loaders/zoo.js.map +1 -0
  159. package/dist/scanner/types.d.ts +118 -0
  160. package/dist/scanner/types.d.ts.map +1 -0
  161. package/dist/scanner/types.js +2 -0
  162. package/dist/scanner/types.js.map +1 -0
  163. package/dist/scanner/utils.d.ts +14 -0
  164. package/dist/scanner/utils.d.ts.map +1 -0
  165. package/dist/scanner/utils.js +25 -0
  166. package/dist/scanner/utils.js.map +1 -0
  167. package/dist/scanner/vsix.d.ts +6 -0
  168. package/dist/scanner/vsix.d.ts.map +1 -0
  169. package/dist/scanner/vsix.js +213 -0
  170. package/dist/scanner/vsix.js.map +1 -0
  171. package/dist/scanner/vsix.test.d.ts +2 -0
  172. package/dist/scanner/vsix.test.d.ts.map +1 -0
  173. package/dist/scanner/vsix.test.js +355 -0
  174. package/dist/scanner/vsix.test.js.map +1 -0
  175. package/package.json +60 -0
  176. package/zoo/blocklist/extensions.json +201 -0
  177. package/zoo/iocs/blockchain-extensions.txt +21 -0
  178. package/zoo/iocs/c2-domains.txt +50 -0
  179. package/zoo/iocs/c2-ips.txt +24 -0
  180. package/zoo/iocs/hashes.txt +47 -0
  181. package/zoo/iocs/malicious-npm.txt +85 -0
  182. package/zoo/iocs/wallets.txt +18 -0
  183. package/zoo/signatures/yara/README.md +46 -0
  184. package/zoo/signatures/yara/blockchain_c2.yar +48 -0
  185. package/zoo/signatures/yara/code_execution.yar +165 -0
  186. package/zoo/signatures/yara/credential_harvesting.yar +116 -0
  187. package/zoo/signatures/yara/crypto_wallet_targeting.yar +92 -0
  188. package/zoo/signatures/yara/data_exfiltration.yar +207 -0
  189. package/zoo/signatures/yara/google_calendar_c2.yar +187 -0
  190. package/zoo/signatures/yara/messaging_c2.yar +103 -0
  191. package/zoo/signatures/yara/multi_stage_attacks.yar +331 -0
  192. package/zoo/signatures/yara/obfuscation_patterns.yar +208 -0
  193. package/zoo/signatures/yara/powershell_attacks.yar +116 -0
  194. package/zoo/signatures/yara/rat_capabilities.yar +243 -0
  195. package/zoo/signatures/yara/self_propagation.yar +239 -0
  196. package/zoo/signatures/yara/unicode_stealth.yar +48 -0
  197. package/zoo/signatures/yara/websocket_c2.yar +83 -0
package/README.md ADDED
@@ -0,0 +1,281 @@
1
+ # vsix-audit
2
+
3
+ Security scanner for VS Code extensions. Detects malicious extensions before installation by analyzing code patterns, indicators of compromise, and known malware signatures.
4
+
5
+ ## The Problem
6
+
7
+ VS Code extensions run with full trust and the same permissions as the editor itself. Malicious extensions have been found in both the official Microsoft marketplace and OpenVSX:
8
+
9
+ - **Credential theft** - SSH keys, browser cookies, password manager databases
10
+ - **Cryptocurrency theft** - Wallet files, clipboard hijacking for addresses
11
+ - **Source code exfiltration** - Stealing proprietary code via Discord webhooks
12
+ - **Cryptominers and RATs** - CoinIMP miners, ScreenConnect RATs, multi-stage loaders
13
+ - **Self-propagation** - GlassWorm spread by modifying installed extensions
14
+
15
+ **Real campaigns we track:** GlassWorm, TigerJack, Evelyn, WhiteCobra, OctoRAT, Shiba, MUT-9332, FAMOUS CHOLLIMA
16
+
17
+ ## Detection Modules
18
+
19
+ The scanner runs 5 detection modules against each extension:
20
+
21
+ ### Package Analysis (`package.ts`)
22
+
23
+ Examines `package.json` and extension manifest for suspicious configurations.
24
+
25
+ | Check | What It Detects | Severity |
26
+ | ---------------------- | ------------------------------------------------------------------------------- | --------------- |
27
+ | Blocklist | Extension ID matches known malicious extensions | Critical |
28
+ | Wildcard activation | `activationEvents: ["*"]` - runs on every action | High |
29
+ | Startup activation | `onStartupFinished` - runs at VS Code launch | Medium |
30
+ | Theme with code | Theme extension that has a `main` entry point | High |
31
+ | Malicious npm packages | Dependencies matching known malware packages | Critical |
32
+ | Typosquatting | Dependencies within edit distance 1-2 of popular packages (lodash, axios, etc.) | High |
33
+ | Lifecycle scripts | `preinstall`/`postinstall` scripts with suspicious patterns | Critical/Medium |
34
+
35
+ ### Indicators of Compromise (`ioc.ts`)
36
+
37
+ Matches against curated threat intelligence from `zoo/iocs/`.
38
+
39
+ | Check | Detection Method | Severity |
40
+ | -------------- | ------------------------------------------------------------------- | -------- |
41
+ | Malware hashes | SHA256 hash of files matches known samples | Critical |
42
+ | C2 domains | Domain extraction matched against blocklist | Critical |
43
+ | C2 IPs | IPv4 extraction (excludes private ranges) matched against blocklist | Critical |
44
+ | Crypto wallets | BTC (legacy/SegWit/Bech32), ETH, Monero, Solana address patterns | High |
45
+
46
+ ### AST Analysis (`ast.ts`)
47
+
48
+ OXC-based parsing to detect structural patterns that regex can't catch.
49
+
50
+ | Rule | What It Detects | Severity |
51
+ | -------------------------- | ------------------------------------------------ | -------- |
52
+ | `AST_EVAL_DYNAMIC` | `eval(variable)` - non-literal argument | High |
53
+ | `AST_FUNCTION_CONSTRUCTOR` | `new Function(string)` - runtime code generation | High |
54
+ | `AST_DYNAMIC_REQUIRE` | `require(variable)` - computed module loads | Medium |
55
+ | `AST_DYNAMIC_IMPORT` | `import(variable)` - computed dynamic imports | Medium |
56
+ | `AST_PROCESS_BINDING` | `process.binding()` - Node.js internals access | High |
57
+ | `AST_GLOBAL_THIS_EVAL` | `globalThis.eval` - indirect eval access | High |
58
+
59
+ ### Obfuscation Detection (`obfuscation.ts`)
60
+
61
+ Detects obfuscation techniques used to hide malicious intent.
62
+
63
+ | Rule | Detection Method | Severity |
64
+ | -------------------------- | ----------------------------------------------------------------- | -------- |
65
+ | `OBFUSCATION_HIGH_ENTROPY` | Shannon entropy >5.5 bits/char (200-char windows) | Medium |
66
+ | `ZERO_WIDTH_CHARS` | Zero-width spaces/joiners hiding code (U+200B-200D) | High |
67
+ | `VARIATION_SELECTOR` | GlassWorm-style hidden data in variation selectors (U+FE00-FE0F) | Critical |
68
+ | `BIDI_OVERRIDE` | Trojan Source attacks using bidirectional overrides (U+202A-202E) | Critical |
69
+ | `UNICODE_ASCII_ESCAPE` | `\u00XX` escapes for normal ASCII chars (obfuscation) | Medium |
70
+ | `CYRILLIC_HOMOGLYPH` | Cyrillic letters that look like Latin (а/a, е/e, с/c) | High |
71
+ | `OTHER_INVISIBLE_CHARS` | Soft hyphens, combining marks, format controls | Medium |
72
+ | `INVISIBLE_CODE_EXECUTION` | Invisible chars near `eval`/`Function`/`exec` | Critical |
73
+
74
+ JavaScript obfuscation patterns (hex variables, `fromCharCode` arrays, eval+decode, packers) are now detected via YARA rules for better accuracy.
75
+
76
+ ### YARA Rules (`yara.ts`)
77
+
78
+ External YARA engine for complex pattern matching. Rules loaded from `zoo/signatures/yara/`. Requires `yara` CLI (`brew install yara`).
79
+
80
+ | Rule File | Detects |
81
+ | ----------------------------- | -------------------------------------------------------------- |
82
+ | `blockchain_c2.yar` | Solana RPC C2, memo parsing, blockchain-based command channels |
83
+ | `code_execution.yar` | `eval`, `Function` constructor, `child_process` patterns |
84
+ | `credential_harvesting.yar` | NPM/GitHub/SSH credential theft, `.npmrc` access |
85
+ | `crypto_wallet_targeting.yar` | MetaMask, Phantom, Exodus wallet extension targeting |
86
+ | `data_exfiltration.yar` | Discord webhooks, SSH key theft, browser data exfil |
87
+ | `google_calendar_c2.yar` | Google Calendar API abuse for C2 communication |
88
+ | `multi_stage_attacks.yar` | Dropper chains, reverse shells, keylogger patterns |
89
+ | `obfuscation_patterns.yar` | Hex variables, `fromCharCode`, packed/encoded code |
90
+ | `powershell_attacks.yar` | Hidden windows, `-ExecutionPolicy Bypass`, AMSI evasion |
91
+ | `rat_capabilities.yar` | SOCKS proxy, VNC, remote command execution |
92
+ | `self_propagation.yar` | GlassWorm-style worm propagation via extension modification |
93
+ | `unicode_stealth.yar` | Invisible Unicode, variation selectors, homoglyphs |
94
+
95
+ ### Triage-Friendly Output
96
+
97
+ Every finding includes context to help quickly determine if it's a real threat:
98
+
99
+ - **Legitimate uses** - Why this pattern exists in benign extensions
100
+ - **Red flags** - What makes the same pattern suspicious in context
101
+ - **Severity** - Critical/high/medium/low based on risk and intent signals
102
+ - **Location** - File path and line number for the match
103
+
104
+ The goal is rich context for human/agent review, not just pass/fail.
105
+
106
+ ## Installation
107
+
108
+ ```sh
109
+ npm install -g vsix-audit
110
+ ```
111
+
112
+ Requires Node.js 22 or later.
113
+
114
+ ## Usage
115
+
116
+ ### Commands
117
+
118
+ **Scan an extension for security issues:**
119
+
120
+ ```sh
121
+ vsix-audit scan ./extension.vsix
122
+ vsix-audit scan publisher.extension-name
123
+ vsix-audit scan openvsx:publisher.extension-name
124
+ ```
125
+
126
+ **Download an extension for offline analysis:**
127
+
128
+ ```sh
129
+ vsix-audit download ms-python.python
130
+ vsix-audit download ms-python.python@2024.1.0 -o ./downloads
131
+ vsix-audit download openvsx:redhat.java
132
+ ```
133
+
134
+ **Show extension metadata:**
135
+
136
+ ```sh
137
+ vsix-audit info ./extension.vsix
138
+ vsix-audit info ./extension-folder
139
+ ```
140
+
141
+ Displays: name, publisher, version, activation events, entry points, contributions, dependencies, file count, and size.
142
+
143
+ ### Registry Prefixes
144
+
145
+ | Prefix | Registry |
146
+ | -------------- | ------------------------------ |
147
+ | (none) | VS Code Marketplace (default) |
148
+ | `marketplace:` | VS Code Marketplace (explicit) |
149
+ | `openvsx:` | Open VSX Registry |
150
+ | `cursor:` | Cursor Extension Marketplace |
151
+
152
+ ### Scan Options
153
+
154
+ | Option | Description |
155
+ | ------------------------ | -------------------------------------------------------------------------------- |
156
+ | `-o, --output <format>` | Output format: `text`, `json`, or `sarif` (default: `text`) |
157
+ | `-s, --severity <level>` | Minimum severity to report: `low`, `medium`, `high`, `critical` (default: `low`) |
158
+ | `-r, --recursive` | Recursively scan all .vsix files in a directory |
159
+ | `-j, --jobs <n>` | Number of parallel scans (default: 4, used with --recursive) |
160
+ | `--no-network` | Disable network-based checks |
161
+ | `--no-cache` | Bypass cache, download fresh |
162
+ | `--force` | Re-download even if cached |
163
+ | `--all-registries` | Scan from all registries (Marketplace + OpenVSX + Cursor) |
164
+
165
+ ### Extension Cache
166
+
167
+ Downloaded extensions are cached for faster subsequent scans:
168
+
169
+ | Platform | Cache Location |
170
+ | -------- | ------------------------------------------------------- |
171
+ | macOS | `~/Library/Caches/vsix-audit/` |
172
+ | Linux | `$XDG_CACHE_HOME/vsix-audit/` or `~/.cache/vsix-audit/` |
173
+
174
+ Extensions are organized by registry (`marketplace/`, `openvsx/`, `cursor/`).
175
+
176
+ **Cache management commands:**
177
+
178
+ ```sh
179
+ vsix-audit cache path # Print cache directory
180
+ vsix-audit cache list [--json] # List cached extensions
181
+ vsix-audit cache clear [pattern] # Clear cache (optional glob pattern)
182
+ vsix-audit cache info <ext-id> # Show cached versions
183
+ ```
184
+
185
+ **Examples:**
186
+
187
+ ```sh
188
+ # First scan downloads to cache
189
+ vsix-audit scan ms-python.python
190
+ # → Downloaded ~/.cache/vsix-audit/marketplace/ms-python.python-2024.1.0.vsix
191
+
192
+ # Second scan uses cache
193
+ vsix-audit scan ms-python.python
194
+ # → Using cached ~/.cache/vsix-audit/marketplace/ms-python.python-2024.1.0.vsix
195
+
196
+ # Force re-download
197
+ vsix-audit scan --force ms-python.python
198
+
199
+ # Bypass cache entirely
200
+ vsix-audit scan --no-cache ms-python.python
201
+
202
+ # Clear specific extensions
203
+ vsix-audit cache clear ms-python.*
204
+ ```
205
+
206
+ ### Output Formats
207
+
208
+ **Text** (default) - Human-readable report for terminal output.
209
+
210
+ **JSON** - Machine-readable results for integration with other tools.
211
+
212
+ **SARIF** - Static Analysis Results Interchange Format for CI/CD integration.
213
+
214
+ ### Exit Codes
215
+
216
+ | Code | Meaning |
217
+ | ---- | ----------------- |
218
+ | 0 | No findings |
219
+ | 1 | Findings detected |
220
+ | 2 | Error during scan |
221
+
222
+ ## Threat Intelligence
223
+
224
+ The `zoo/` directory contains threat intelligence for detection:
225
+
226
+ | Directory | Contents |
227
+ | ----------------- | --------------------------------------------------------------------- |
228
+ | `zoo/blocklist/` | Known malicious extension IDs with campaign attribution |
229
+ | `zoo/iocs/` | SHA256 hashes, C2 domains/IPs, crypto wallets, malicious npm packages |
230
+ | `zoo/signatures/` | YARA rules for credential harvesting, RAT behavior, self-propagation |
231
+
232
+ **Campaigns covered:** GlassWorm, Evelyn, TigerJack, OctoRAT, WhiteCobra, Shiba, MUT-9332, FAMOUS CHOLLIMA, ReversingLabs-Dec2025
233
+
234
+ ### Malware Samples (for development)
235
+
236
+ Malware samples are in a separate private repository ([trailofbits/vsix-zoo](https://github.com/trailofbits/vsix-zoo)) to avoid Dependabot alerts and AV triggers.
237
+
238
+ ```bash
239
+ # Clone the samples repo (requires access)
240
+ git clone git@github.com:trailofbits/vsix-zoo.git ../vsix-zoo
241
+
242
+ # Run tests with samples
243
+ VSIX_ZOO_PATH=../vsix-zoo/samples npm test
244
+ ```
245
+
246
+ ## Development
247
+
248
+ ```sh
249
+ git clone https://github.com/trailofbits/vsix-audit.git
250
+ cd vsix-audit
251
+ npm install
252
+ npm run build
253
+ ```
254
+
255
+ Set up pre-commit hooks:
256
+
257
+ ```sh
258
+ prek install
259
+ ```
260
+
261
+ Run tests:
262
+
263
+ ```sh
264
+ npm test
265
+ ```
266
+
267
+ Type check and lint:
268
+
269
+ ```sh
270
+ npm run check
271
+ ```
272
+
273
+ Run from development directory:
274
+
275
+ ```sh
276
+ npm exec -- vsix-audit scan ./extension.vsix
277
+ ```
278
+
279
+ ## License
280
+
281
+ AGPL-3.0
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const cli: Command;
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmEpC,eAAO,MAAM,GAAG,SAGG,CAAC"}