@mr-aftab-ahmad-khan/depguard-cli 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/CHANGELOG.md ADDED
@@ -0,0 +1,10 @@
1
+ # Changelog
2
+
3
+ ## [0.1.0] โ€” 2026-05-15
4
+
5
+ ### Added
6
+
7
+ - `scan`, `audit`, and `baseline` commands for npm supply-chain auditing.
8
+ - Detects curl-pipe-shell install scripts, base64+eval, network calls to untrusted domains, and obfuscated one-liners.
9
+ - Typosquat detection via Levenshtein distance to the top-1000 packages.
10
+ - Configurable risk levels in `.depguardrc.json` plus `.driftignore` support.
package/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 depguard-cli contributors
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.
package/README.md ADDED
@@ -0,0 +1,337 @@
1
+ # depguard-cli
2
+
3
+ [![npm version](https://img.shields.io/npm/v/%40mr-aftab-ahmad-khan%2Fdepguard-cli.svg)](https://www.npmjs.com/package/@mr-aftab-ahmad-khan/depguard-cli)
4
+ [![license](https://img.shields.io/npm/l/%40mr-aftab-ahmad-khan%2Fdepguard-cli.svg)](./LICENSE)
5
+ [![TypeScript](https://img.shields.io/badge/types-TypeScript-blue.svg)](https://www.typescriptlang.org/)
6
+
7
+ **A free, fast, open-source supply-chain security scanner for npm.** `depguard-cli` audits your installed `node_modules` for the four attack vectors that cause real-world npm incidents:
8
+
9
+ - ๐Ÿชช **Maintainer changes** โ€” new maintainers added since your trusted baseline
10
+ - ๐Ÿงจ **Suspicious install scripts** โ€” `preinstall`/`postinstall` lines that curl-pipe-shell, base64+eval, exfiltrate env vars, or hide behind obfuscation
11
+ - ๐Ÿ“ˆ **Version anomalies** โ€” packages that bumped a major version in under 7 days, brand-new packages claiming to be popular
12
+ - โœ๏ธ **Typosquats** โ€” installed names that are within Levenshtein 2 of a top-200 popular package
13
+
14
+ Socket.dev costs $19/month per developer. `depguard-cli` is free and fast enough to run in your `postinstall` hook or block PRs in CI.
15
+
16
+ ---
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install -g depguard-cli
22
+ pnpm add -g depguard-cli
23
+ yarn global add depguard-cli
24
+
25
+ # Or one-off:
26
+ npx depguard-cli scan
27
+ ```
28
+
29
+ ---
30
+
31
+ ## Quick Start
32
+
33
+ ```bash
34
+ $ depguard scan
35
+ depguard report โ€” 2 package(s) with findings (of 412 scanned)
36
+
37
+ HIGH react@18.2.0 score=6
38
+ - high install-script:postinstall: postinstall script is suspicious (curl/wget piped to a shell or node)
39
+
40
+ CRITICAL reactt@0.0.1 score=10
41
+ - critical typosquat: Name closely resembles "react" โ€” likely typosquat
42
+ ```
43
+
44
+ ---
45
+
46
+ ## Core Usage Examples
47
+
48
+ ### 1. Scan and read the report
49
+
50
+ ```bash
51
+ depguard scan
52
+ ```
53
+
54
+ ### 2. Save a trusted baseline
55
+
56
+ ```bash
57
+ depguard baseline
58
+ # depguard: baseline saved (412 packages)
59
+ ```
60
+
61
+ ### 3. Audit a single suspicious package
62
+
63
+ ```bash
64
+ depguard audit reactt
65
+ # CRITICAL reactt@0.0.1 score=10
66
+ # - critical typosquat: Name closely resembles "react" โ€” likely typosquat
67
+ ```
68
+
69
+ ### 4. Fail PRs in CI
70
+
71
+ ```bash
72
+ depguard scan --fail-on high
73
+ echo $? # 1 when any package is high+ severity
74
+ ```
75
+
76
+ ### 5. JSON output for `jq`
77
+
78
+ ```bash
79
+ depguard scan --format json | jq '.packages[] | select(.worstSeverity == "critical")'
80
+ ```
81
+
82
+ ### 6. Run on every install
83
+
84
+ ```json
85
+ {
86
+ "scripts": {
87
+ "postinstall": "depguard scan --fail-on critical"
88
+ }
89
+ }
90
+ ```
91
+
92
+ ---
93
+
94
+ ## CI/CD Integration Examples
95
+
96
+ ### GitHub Actions
97
+
98
+ ```yaml
99
+ name: security
100
+ on: [pull_request]
101
+ jobs:
102
+ depguard:
103
+ runs-on: ubuntu-latest
104
+ steps:
105
+ - uses: actions/checkout@v4
106
+ - uses: actions/setup-node@v4
107
+ with: { node-version: 20 }
108
+ - run: npm ci
109
+ - run: npx depguard-cli scan --fail-on high
110
+ ```
111
+
112
+ ### GitLab CI
113
+
114
+ ```yaml
115
+ depguard:
116
+ stage: test
117
+ image: node:20
118
+ script:
119
+ - npm ci
120
+ - npx depguard-cli scan --fail-on high
121
+ ```
122
+
123
+ ### Pre-commit hook with husky
124
+
125
+ ```bash
126
+ # .husky/pre-push
127
+ #!/bin/sh
128
+ npx depguard-cli scan --fail-on critical
129
+ ```
130
+
131
+ ### postinstall
132
+
133
+ ```json
134
+ {
135
+ "scripts": {
136
+ "postinstall": "depguard scan --fail-on critical --no-network"
137
+ }
138
+ }
139
+ ```
140
+
141
+ ---
142
+
143
+ ## Configuration Reference
144
+
145
+ `.depguardrc.json`:
146
+
147
+ ```json
148
+ {
149
+ "failOn": "high",
150
+ "ignore": ["some-known-noisy-pkg"],
151
+ "cacheTTL": 3600000,
152
+ "scanDepth": "all"
153
+ }
154
+ ```
155
+
156
+ | Option | Type | Default | Description |
157
+ | -------------- | ----------- | ------------ | ---------------------------------------------------------- |
158
+ | `failOn` | `RiskLevel` | `undefined` | Exit code 1 when any package's worst severity โ‰ฅ this level |
159
+ | `ignore` | `string[]` | `[]` | Package names to skip |
160
+ | `baselinePath` | `string` | `~/.depguard/baseline.json` | Custom baseline location |
161
+ | `cacheTTL` | `number` | `3600000` | Registry cache TTL in ms |
162
+ | `scanDepth` | `"direct" \| "all"` | `"all"` | Direct dependencies only vs full tree |
163
+
164
+ ---
165
+
166
+ ## Risk Scoring Explained
167
+
168
+ ### Maintainer changes
169
+
170
+ | Condition | Severity | Score |
171
+ | ---------------------------------------- | -------- | ----- |
172
+ | New maintainer added since baseline | high | 6 |
173
+
174
+ ### Suspicious install scripts
175
+
176
+ | Pattern | Points |
177
+ | ---------------------------------------- | ------ |
178
+ | `curl`/`wget` piped to a shell or node | 5 |
179
+ | `base64` combined with `eval`/`exec` | 5 |
180
+ | Dynamic `new Function(...)` call | 3 |
181
+ | Reads `process.env.*` | 2 |
182
+ | Network call to a non-trusted domain | 3 |
183
+ | Long opaque token (>= 200 base64 chars) | 3 |
184
+ | One-liner > 300 chars without newlines | 2 |
185
+
186
+ Total is capped at 10. Severity mapping: 8-10 = critical, 5-7 = high, 3-4 = medium, 1-2 = low.
187
+
188
+ ### Version anomaly
189
+
190
+ | Condition | Severity | Score |
191
+ | -------------------------------------------------- | -------- | ----- |
192
+ | Major version bump within 7 days of previous major | medium | 4 |
193
+ | Package first published < 30 days ago | low | 2 |
194
+
195
+ ### Typosquat
196
+
197
+ | Levenshtein distance to a top-200 pkg | Severity | Score |
198
+ | ------------------------------------- | -------- | ----- |
199
+ | 1โ€“2 | critical | 10 |
200
+
201
+ ---
202
+
203
+ ## TypeScript Types
204
+
205
+ ```ts
206
+ import { scan, audit, type ScanResult, type PackageRisk, type RiskLevel } from "@mr-aftab-ahmad-khan/depguard-cli";
207
+
208
+ const result: ScanResult = await scan({ failOn: "high" });
209
+ for (const p of result.packages) {
210
+ console.log(p.name, p.worstSeverity, p.totalScore);
211
+ }
212
+
213
+ const single: PackageRisk | undefined = await audit("react");
214
+ ```
215
+
216
+ ---
217
+
218
+ ## CLI Reference
219
+
220
+ ```
221
+ depguard scan [options]
222
+ --fail-on <severity> Exit 1 when worst severity โ‰ฅ this level (info|low|medium|high|critical)
223
+ --format <fmt> pretty | json (default pretty)
224
+ --no-network Skip registry lookups (uses cache only)
225
+ --depth <depth> direct | all (default all)
226
+
227
+ depguard baseline
228
+ Save the current node_modules maintainer list as the trusted baseline.
229
+
230
+ depguard audit <package>
231
+ Audit a single named package by fetching its registry metadata.
232
+ ```
233
+
234
+ Sample JSON output:
235
+
236
+ ```json
237
+ {
238
+ "packages": [
239
+ {
240
+ "name": "reactt",
241
+ "version": "0.0.1",
242
+ "worstSeverity": "critical",
243
+ "totalScore": 10,
244
+ "findings": [
245
+ { "rule": "typosquat", "severity": "critical", "message": "Name closely resembles \"react\" โ€” likely typosquat", "score": 10 }
246
+ ]
247
+ }
248
+ ],
249
+ "scannedAt": "2026-01-12T10:01:22.000Z",
250
+ "generatedAt": "2026-01-12T10:01:23.130Z",
251
+ "totalPackages": 412
252
+ }
253
+ ```
254
+
255
+ ---
256
+
257
+ ## Real-World Recipe โ€” Full CI Security Gate
258
+
259
+ ```bash
260
+ # 1. After a clean install, set the trusted baseline
261
+ npm ci
262
+ npx depguard-cli baseline
263
+ ```
264
+
265
+ ```yaml
266
+ # 2. .github/workflows/security.yml โ€” blocks PRs with new high-risk dependencies
267
+ name: security
268
+ on: [pull_request, schedule]
269
+ on:
270
+ pull_request:
271
+ schedule:
272
+ - cron: "0 6 * * 1" # Mondays 06:00 UTC
273
+
274
+ jobs:
275
+ depguard:
276
+ runs-on: ubuntu-latest
277
+ steps:
278
+ - uses: actions/checkout@v4
279
+ - uses: actions/setup-node@v4
280
+ with: { node-version: 20 }
281
+ - run: npm ci
282
+ - id: scan
283
+ run: npx depguard-cli scan --fail-on high --format json > report.json || echo "had_findings=true" >> $GITHUB_OUTPUT
284
+ - if: ${{ steps.scan.outputs.had_findings == 'true' }}
285
+ run: |
286
+ curl -X POST -H 'Content-type: application/json' \
287
+ --data "$(jq -c '{text: "depguard found high-risk packages: " + (.packages | map(.name) | join(", "))}' report.json)" \
288
+ "${{ secrets.SLACK_WEBHOOK_URL }}"
289
+ - if: ${{ steps.scan.outputs.had_findings == 'true' }}
290
+ run: exit 1
291
+ ```
292
+
293
+ ```json
294
+ // 3. .depguardrc.json โ€” monorepo with a known noisy package
295
+ {
296
+ "failOn": "high",
297
+ "ignore": ["legacy-internal-tool"],
298
+ "scanDepth": "all"
299
+ }
300
+ ```
301
+
302
+ ---
303
+
304
+ ## False Positive Guide
305
+
306
+ The two most common false positives:
307
+
308
+ 1. **`postinstall` runs `node-gyp` for native builds.** Already filtered; if you see it surface anyway, add the package to `ignore`.
309
+ 2. **Major bump within 7 days.** Usually a frontend framework correcting a release. Add the specific package to `.depguardrc.json#ignore` once you've verified.
310
+
311
+ Workflow:
312
+
313
+ ```bash
314
+ depguard audit suspicious-pkg # confirm whether it's truly safe
315
+ # safe? add to ignore:
316
+ echo '{"ignore":["suspicious-pkg"]}' > .depguardrc.json
317
+ ```
318
+
319
+ ---
320
+
321
+ ## Comparison Table
322
+
323
+ | Feature | npm audit | Socket.dev | **depguard-cli** |
324
+ | ----------------------------- | :-------: | :--------: | :--------------: |
325
+ | Maintainer-change detection | โŒ | โœ… | โœ… |
326
+ | Install-script analysis | โŒ | โœ… | โœ… |
327
+ | Typosquat detection | โŒ | โœ… | โœ… |
328
+ | Free tier | โœ… | limited | โœ… |
329
+ | CI integration | โœ… | โœ… | โœ… |
330
+ | Offline mode | โŒ | โŒ | โœ… |
331
+ | Self-hosted | n/a | โŒ | โœ… |
332
+
333
+ ---
334
+
335
+ ## License
336
+
337
+ MIT