shai-scan 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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Chris Engelhard (digi4care)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,253 @@
1
+ # shai-scan
2
+
3
+ > Zero-dependency CLI scanner for npm and PyPI supply chain compromises.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/shai-scan)](https://www.npmjs.com/package/shai-scan)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
7
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D22-brightgreen)](https://nodejs.org/)
8
+
9
+ ## Why?
10
+
11
+ On May 11, 2026, a self-propagating supply chain worm dubbed **Mini Shai-Hulud** (CVE-2026-45321, GHSA-g7cv-rxg3-hmpx) compromised the npm ecosystem. Attributed to **TeamPCP** (aka DeadCatx3, PCPcat, ShellForce, CipherForce), the malware hijacked GitHub Actions OIDC tokens to publish malicious packages with valid SLSA Build Level 3 provenance. It stole credentials from CI/CD pipelines, cloud providers, and cryptocurrency wallets, and installed persistence hooks in Claude Code and VS Code. A built-in dead-man switch threatened to wipe the user's home directory if npm tokens were revoked.
12
+
13
+ Affected packages included TanStack router and start packages, Mistral AI SDKs, OpenSearch client, UiPath tooling, and dozens of others. Because supply chain attacks move fast, organizations need a lightweight, trustworthy scanner they can run anywhere without adding new dependencies to their own attack surface.
14
+
15
+ ## Features
16
+
17
+ - **Lockfile scanning** — Detects compromised npm and PyPI packages in `package-lock.json`, `pnpm-lock.yaml`, `yarn.lock`, `bun.lock`, `bun.lockb`, `poetry.lock`, `Pipfile.lock`, and `requirements.txt`
18
+ - **System IOC checks** — Scans running processes, filesystem artifacts, network connections, and known persistence paths for indicators of compromise
19
+ - **Zero runtime dependencies** — Uses only Node.js/Bun built-ins (`fs`, `path`, `child_process`, `os`). The scanner does not increase your supply chain risk
20
+ - **Multiple output formats** — Human-readable text, machine-readable JSON, and SARIF for GitHub Code Scanning
21
+ - **CI/CD native** — Exit codes designed for automation (`0` = clean, `1` = findings, `2` = error)
22
+ - **Path-agnostic** — Accept any directory; defaults to the current working directory
23
+ - **Campaign-based database** — New attack waves are added as discrete campaigns in `src/db.ts`; update the file and rerun
24
+
25
+ ## Install
26
+
27
+ No installation required. Run directly with your package runner of choice:
28
+
29
+ ```bash
30
+ # npx
31
+ npx shai-scan
32
+
33
+ # bunx
34
+ bunx shai-scan
35
+
36
+ # pnpm dlx
37
+ pnpm dlx shai-scan
38
+ ```
39
+
40
+ Global install (optional):
41
+
42
+ ```bash
43
+ npm install -g shai-scan
44
+ # or
45
+ pnpm add -g shai-scan
46
+ ```
47
+
48
+ From source:
49
+
50
+ ```bash
51
+ git clone https://github.com/digi4care/shai-scan.git
52
+ cd shai-scan
53
+ pnpm install
54
+ node src/cli.ts --help # Node.js ≥ 22 (v24+ runs .ts natively)
55
+ # or
56
+ bun run src/cli.ts --help
57
+ ```
58
+
59
+ ## Usage
60
+
61
+ ### Scan the current project
62
+
63
+ ```bash
64
+ npx shai-scan
65
+ ```
66
+
67
+ ### Scan a specific path
68
+
69
+ ```bash
70
+ npx shai-scan ~/projects/my-app
71
+ ```
72
+
73
+ ### JSON output for automation
74
+
75
+ ```bash
76
+ npx shai-scan --json .
77
+ ```
78
+
79
+ ### SARIF output for GitHub Code Scanning
80
+
81
+ ```bash
82
+ npx shai-scan --sarif --sarif-file results.sarif .
83
+ ```
84
+
85
+ ### CI/CD exit codes
86
+
87
+ ```bash
88
+ #!/bin/bash
89
+ npx shai-scan --severity high . || {
90
+ code=$?
91
+ if [ "$code" -eq 1 ]; then
92
+ echo "Supply chain findings detected"
93
+ exit 1
94
+ elif [ "$code" -eq 2 ]; then
95
+ echo "Scanner error"
96
+ exit 2
97
+ fi
98
+ }
99
+ ```
100
+
101
+ ## CI/CD Integration
102
+
103
+ ### GitHub Actions (text output)
104
+
105
+ ```yaml
106
+ name: Supply Chain Scan
107
+ on:
108
+ push:
109
+ branches: [main]
110
+ pull_request:
111
+ branches: [main]
112
+
113
+ jobs:
114
+ scan:
115
+ runs-on: ubuntu-latest
116
+ steps:
117
+ - uses: actions/checkout@v4
118
+ - uses: pnpm/action-setup@v4
119
+ - uses: actions/setup-node@v4
120
+ with:
121
+ node-version: 22
122
+ - run: pnpm install --frozen-lockfile
123
+ - run: npx shai-scan --severity high .
124
+ ```
125
+
126
+ ### GitHub Actions (SARIF upload)
127
+
128
+ ```yaml
129
+ name: Supply Chain Scan SARIF
130
+ on:
131
+ push:
132
+ branches: [main]
133
+ pull_request:
134
+ branches: [main]
135
+ schedule:
136
+ - cron: '0 6 * * 1'
137
+
138
+ jobs:
139
+ scan:
140
+ runs-on: ubuntu-latest
141
+ permissions:
142
+ security-events: write
143
+ steps:
144
+ - uses: actions/checkout@v4
145
+ - uses: pnpm/action-setup@v4
146
+ - uses: actions/setup-node@v4
147
+ with:
148
+ node-version: 22
149
+ - run: pnpm install --frozen-lockfile
150
+ - run: npx shai-scan --sarif --sarif-file results.sarif .
151
+ - uses: github/codeql-action/upload-sarif@v3
152
+ with:
153
+ sarif_file: results.sarif
154
+ ```
155
+
156
+ ## Output Formats
157
+
158
+ | Format | Flag | Description |
159
+ |--------|------|-------------|
160
+ | Text | (default) | Human-readable table of findings with severity, package name, version, and campaign details |
161
+ | JSON | `--json` | Structured JSON array of findings, suitable for ingestion into SIEMs or custom dashboards |
162
+ | SARIF | `--sarif` | OASIS SARIF 2.1.0 format for upload to GitHub Code Scanning, GitLab Secure, or other SARIF consumers |
163
+
164
+ Example JSON excerpt:
165
+
166
+ ```json
167
+ [
168
+ {
169
+ "package": "@tanstack/react-router",
170
+ "version": "1.169.5",
171
+ "ecosystem": "npm",
172
+ "severity": "critical",
173
+ "campaign": "mini-shai-hulud-wave4",
174
+ "cve": "CVE-2026-45321",
175
+ "reference": "https://github.com/TanStack/router/security/advisories/GHSA-g7cv-rxg3-hmpx"
176
+ }
177
+ ]
178
+ ```
179
+
180
+ ## Exit Codes
181
+
182
+ | Code | Meaning |
183
+ |------|---------|
184
+ | 0 | No compromised packages or IOCs detected |
185
+ | 1 | One or more findings detected |
186
+ | 2 | Runtime error (invalid path, unreadable lockfile, etc.) |
187
+
188
+ ## Adding New Campaigns
189
+
190
+ When a new supply chain attack is discovered, update `src/db.ts`:
191
+
192
+ 1. Add a new `CompromisedVersion[]` array with the affected packages and versions
193
+ 2. Append a new `Campaign` object to the `CAMPAIGNS` array, including CVE/GHSA identifiers, severity, description, reference URLs, and IOC indicators
194
+ 3. The `buildLookup()` function automatically rebuilds the lookup map on the next run
195
+
196
+ No rebuild step is required. Changes to `src/db.ts` take effect immediately — the project runs TypeScript directly via Node.js (v22+) or Bun.
197
+
198
+ ## Security Considerations
199
+
200
+ - **Zero runtime dependencies**: The scanner uses only Node.js/Bun built-in modules. It does not download or execute third-party code at runtime, eliminating the risk that the scanner itself becomes a compromise vector.
201
+ - **pnpm as package manager**: pnpm uses strict lockfiles, does not execute lifecycle scripts by default, and supports content-addressable storage. These properties reduce the attack surface compared to other package managers.
202
+ - **Recommended `.npmrc` settings**: For maximum protection when installing packages, add the following to your project or global `.npmrc`:
203
+
204
+ ```ini
205
+ ignore-scripts=true
206
+ engine-strict=true
207
+ ```
208
+
209
+ - **No network calls**: `shai-scan` does not phone home, download signatures, or require an API key. All campaign data is shipped with the package.
210
+
211
+ ## Affected Packages (Current Campaign)
212
+
213
+ The following packages and versions are known to be compromised in **CVE-2026-45321** (Mini Shai-Hulud Wave 4). This is a representative subset; the full list is maintained in `src/db.ts`.
214
+
215
+ | Package | Ecosystem | Compromised Versions |
216
+ |---------|-----------|---------------------|
217
+ | `@tanstack/react-router` | npm | 1.169.5, 1.169.8 |
218
+ | `@tanstack/vue-router` | npm | 1.169.5, 1.169.8 |
219
+ | `@tanstack/solid-router` | npm | 1.169.5, 1.169.8 |
220
+ | `@tanstack/router-core` | npm | 1.169.5, 1.169.8 |
221
+ | `@tanstack/react-start` | npm | 1.167.68, 1.167.71 |
222
+ | `@mistralai/mistralai` | npm | 2.2.2, 2.2.3, 2.2.4 |
223
+ | `@mistralai/mistralai-azure` | npm | 1.7.2, 1.7.3 |
224
+ | `mistralai` | pypi | 2.4.6 |
225
+ | `@opensearch-project/opensearch` | npm | 3.5.3, 3.6.2, 3.7.0, 3.8.0 |
226
+ | `@uipath/robot` | npm | 1.3.4 |
227
+ | `@squawk/airways` | npm | 0.4.2, 0.4.3, 0.4.5 |
228
+ | `@draftauth/core` | npm | 0.13.1, 0.13.2 |
229
+ | `@tallyui/core` | npm | 0.2.1, 0.2.2, 0.2.3 |
230
+ | `safe-action` | npm | 0.8.3, 0.8.4 |
231
+ | `cmux-agent-mcp` | npm | 0.1.3 - 0.1.8 |
232
+ | `nextmove-mcp` | npm | 0.1.3, 0.1.4, 0.1.5, 0.1.7 |
233
+ | `ts-dna` | npm | 3.0.1, 3.0.2, 3.0.4 |
234
+ | `cross-stitch` | npm | 1.1.3, 1.1.4, 1.1.6 |
235
+ | `git-git-git` | npm | 1.0.8 - 1.0.12 |
236
+ | `git-branch-selector` | npm | 1.3.3 - 1.3.7 |
237
+ | `agentwork-cli` | npm | 0.1.4, 0.1.5 |
238
+ | `wot-api` | npm | 0.8.1, 0.8.2, 0.8.4 |
239
+ | `ml-toolkit-ts` | npm | 1.0.4, 1.0.5 |
240
+ | `@beproduct/nestjs-auth` | npm | 0.1.2 - 0.1.19 |
241
+ | `@dirigible-ai/sdk` | npm | 0.6.2, 0.6.3 |
242
+ | `@taskflow-corp/cli` | npm | 0.1.24 - 0.1.29 |
243
+ | `@tolka/cli` | npm | 1.0.2, 1.0.3, 1.0.4, 1.0.6 |
244
+ | `@supersurkhet/cli` | npm | 0.0.2 - 0.0.7 |
245
+ | `guardrails-ai` | pypi | 0.10.1 |
246
+
247
+ ## License
248
+
249
+ MIT. See [LICENSE](LICENSE) for details.
250
+
251
+ ## Disclaimer
252
+
253
+ `shai-scan` is a detection aid, not a substitute for comprehensive security audits, dependency review, or threat intelligence platforms. It identifies known compromised versions based on the shipped database; novel or zero-day supply chain attacks may not be detected until a campaign is added. Always practice defense in depth: audit dependencies, pin versions, verify provenance, and monitor CI/CD pipelines.
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "shai-scan",
3
+ "version": "0.1.0",
4
+ "description": "Zero-dependency CLI scanner for npm/PyPI supply chain compromises. Detects compromised packages in lockfiles and system-level IOCs from attacks like Mini Shai-Hulud (CVE-2026-45321).",
5
+ "type": "module",
6
+ "bin": {
7
+ "shai-scan": "./src/cli.ts"
8
+ },
9
+ "files": ["src/"],
10
+ "scripts": {
11
+ "scan": "bun run src/cli.ts",
12
+ "check": "biome check src/",
13
+ "check:fix": "biome check --fix src/",
14
+ "release": "bumpp && npm publish"
15
+ },
16
+ "keywords": ["security", "supply-chain", "npm", "scanner", "malware", "shai-hulud", "CVE-2026-45321"],
17
+ "author": "Chris Engelhard",
18
+ "license": "MIT",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "https://github.com/digi4care/shai-scan"
22
+ },
23
+ "bugs": {
24
+ "url": "https://github.com/digi4care/shai-scan/issues"
25
+ },
26
+ "homepage": "https://github.com/digi4care/shai-scan#readme",
27
+ "engines": {
28
+ "node": ">=22.0.0"
29
+ },
30
+ "packageManager": "pnpm@10.11.0",
31
+ "devDependencies": {
32
+ "@biomejs/biome": "^2.0.0",
33
+ "bumpp": "^10.1.0",
34
+ "typescript": "^5.8.0"
35
+ }
36
+ }