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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"threat-detector.js","sourceRoot":"","sources":["../../../src/ai/analyzers/threat-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** ScriptGuard — Gemini AI client wrapper */
|
|
2
|
+
import type { AIBatchRequest, AIBatchResponse } from '../types/index.js';
|
|
3
|
+
export declare class GeminiClient {
|
|
4
|
+
private client;
|
|
5
|
+
private model;
|
|
6
|
+
private totalTokensUsed;
|
|
7
|
+
constructor(apiKey?: string);
|
|
8
|
+
/**
|
|
9
|
+
* Sanitize script content before sending to API
|
|
10
|
+
* Redacts API keys, tokens, and other sensitive data
|
|
11
|
+
*/
|
|
12
|
+
private sanitizeScripts;
|
|
13
|
+
/**
|
|
14
|
+
* Generate cache key from request data
|
|
15
|
+
*/
|
|
16
|
+
private getCacheKey;
|
|
17
|
+
/**
|
|
18
|
+
* Check cache for existing response
|
|
19
|
+
*/
|
|
20
|
+
private getCachedResponse;
|
|
21
|
+
/**
|
|
22
|
+
* Cache a response
|
|
23
|
+
*/
|
|
24
|
+
private setCachedResponse;
|
|
25
|
+
/**
|
|
26
|
+
* Get total tokens used across all requests
|
|
27
|
+
*/
|
|
28
|
+
getTotalTokensUsed(): number;
|
|
29
|
+
/**
|
|
30
|
+
* Analyze a batch of packages using Gemini AI
|
|
31
|
+
*/
|
|
32
|
+
analyzeBatch(request: AIBatchRequest): Promise<AIBatchResponse>;
|
|
33
|
+
/**
|
|
34
|
+
* Clear the response cache
|
|
35
|
+
*/
|
|
36
|
+
clearCache(): void;
|
|
37
|
+
/**
|
|
38
|
+
* Get cache statistics
|
|
39
|
+
*/
|
|
40
|
+
getCacheStats(): {
|
|
41
|
+
size: number;
|
|
42
|
+
keys: string[];
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export declare function getGeminiClient(apiKey?: string): GeminiClient;
|
|
46
|
+
export declare function resetGeminiClient(): void;
|
|
47
|
+
//# sourceMappingURL=gemini-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-client.d.ts","sourceRoot":"","sources":["../../src/ai/gemini-client.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAG7C,OAAO,KAAK,EAAU,cAAc,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAqCjF,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,eAAe,CAAK;gBAEhB,MAAM,CAAC,EAAE,MAAM;IAa3B;;;OAGG;IACH,OAAO,CAAC,eAAe;IA+BvB;;OAEG;IACH,OAAO,CAAC,WAAW;IAQnB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAazB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAOzB;;OAEG;IACI,kBAAkB,IAAI,MAAM;IAInC;;OAEG;IACU,YAAY,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;IA8E5E;;OAEG;IACI,UAAU,IAAI,IAAI;IAIzB;;OAEG;IACI,aAAa,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE;CAMzD;AAOD,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,YAAY,CAK7D;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAExC"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/** ScriptGuard — Gemini AI client wrapper */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.GeminiClient = void 0;
|
|
5
|
+
exports.getGeminiClient = getGeminiClient;
|
|
6
|
+
exports.resetGeminiClient = resetGeminiClient;
|
|
7
|
+
const generative_ai_1 = require("@google/generative-ai");
|
|
8
|
+
// Dynamic import for p-throttle to avoid ESM/CJS issues
|
|
9
|
+
let pThrottle;
|
|
10
|
+
async function getThrottle() {
|
|
11
|
+
if (!pThrottle) {
|
|
12
|
+
const module = await import('p-throttle');
|
|
13
|
+
pThrottle = module.default || module;
|
|
14
|
+
}
|
|
15
|
+
return pThrottle;
|
|
16
|
+
}
|
|
17
|
+
// Rate limiting: 5 requests per second to stay within free tier limits
|
|
18
|
+
let throttle;
|
|
19
|
+
async function getThrottledGenerateContent() {
|
|
20
|
+
if (!throttle) {
|
|
21
|
+
const pThrottleModule = await getThrottle();
|
|
22
|
+
throttle = pThrottleModule({
|
|
23
|
+
limit: 5,
|
|
24
|
+
interval: 1000,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
return throttle(async (model, prompt) => {
|
|
28
|
+
return await model.generateContent(prompt);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
// In-memory cache with 24-hour TTL
|
|
32
|
+
const cache = new Map();
|
|
33
|
+
const CACHE_TTL = 24 * 60 * 60 * 1000; // 24 hours
|
|
34
|
+
class GeminiClient {
|
|
35
|
+
client;
|
|
36
|
+
model;
|
|
37
|
+
totalTokensUsed = 0;
|
|
38
|
+
constructor(apiKey) {
|
|
39
|
+
const key = apiKey || process.env.GOOGLE_AI_API_KEY;
|
|
40
|
+
if (!key) {
|
|
41
|
+
throw new Error('GOOGLE_AI_API_KEY environment variable not set. ' +
|
|
42
|
+
'Get your key at: https://makersuite.google.com/app/apikey');
|
|
43
|
+
}
|
|
44
|
+
this.client = new generative_ai_1.GoogleGenerativeAI(key);
|
|
45
|
+
this.model = this.client.getGenerativeModel({ model: 'gemini-3-flash-preview' });
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Sanitize script content before sending to API
|
|
49
|
+
* Redacts API keys, tokens, and other sensitive data
|
|
50
|
+
*/
|
|
51
|
+
sanitizeScripts(scripts) {
|
|
52
|
+
const sanitized = {};
|
|
53
|
+
for (const [name, content] of Object.entries(scripts)) {
|
|
54
|
+
let cleaned = content;
|
|
55
|
+
// Redact common secret patterns
|
|
56
|
+
const secretPatterns = [
|
|
57
|
+
/(?:api[_-]?key|apikey|secret[_-]?key|access[_-]?token|refresh[_-]?token)\s*[:=]\s*['"]?[a-zA-Z0-9_\-]{20,}['"]?/gi,
|
|
58
|
+
/bearer\s+[a-zA-Z0-9_\-]{20,}/gi,
|
|
59
|
+
/sk-[a-zA-Z0-9]{48}/g, // OpenAI API keys
|
|
60
|
+
/ghp_[a-zA-Z0-9]{36}/g, // GitHub tokens
|
|
61
|
+
/gho_[a-zA-Z0-9]{36}/g, // GitHub OAuth tokens
|
|
62
|
+
/ghu_[a-zA-Z0-9]{36}/g, // GitHub user tokens
|
|
63
|
+
/ghs_[a-zA-Z0-9]{36}/g, // GitHub server tokens
|
|
64
|
+
/ghr_[a-zA-Z0-9]{36}/g, // GitHub refresh tokens
|
|
65
|
+
/xoxb-[0-9]{13}-[0-9]{13}-[a-zA-Z0-9]{24}/g, // Slack bot tokens
|
|
66
|
+
/xoxp-[0-9]{13}-[0-9]{13}-[0-9]{12}-[a-zA-Z0-9]{24}/g, // Slack user tokens
|
|
67
|
+
/AKIA[0-9A-Z]{16}/g, // AWS access keys
|
|
68
|
+
];
|
|
69
|
+
for (const pattern of secretPatterns) {
|
|
70
|
+
cleaned = cleaned.replace(pattern, '[REDACTED_SECRET]');
|
|
71
|
+
}
|
|
72
|
+
sanitized[name] = cleaned;
|
|
73
|
+
}
|
|
74
|
+
return sanitized;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Generate cache key from request data
|
|
78
|
+
*/
|
|
79
|
+
getCacheKey(request) {
|
|
80
|
+
const packagesHash = request.packages
|
|
81
|
+
.map(p => `${p.name}@${p.version}:${Object.keys(p.scripts).join(',')}`)
|
|
82
|
+
.sort()
|
|
83
|
+
.join('|');
|
|
84
|
+
return `${request.mode}:${packagesHash}`;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Check cache for existing response
|
|
88
|
+
*/
|
|
89
|
+
getCachedResponse(cacheKey) {
|
|
90
|
+
const cached = cache.get(cacheKey);
|
|
91
|
+
if (!cached)
|
|
92
|
+
return null;
|
|
93
|
+
const now = Date.now();
|
|
94
|
+
if (now - cached.timestamp > CACHE_TTL) {
|
|
95
|
+
cache.delete(cacheKey);
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
return cached.response;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Cache a response
|
|
102
|
+
*/
|
|
103
|
+
setCachedResponse(cacheKey, response) {
|
|
104
|
+
cache.set(cacheKey, {
|
|
105
|
+
response,
|
|
106
|
+
timestamp: Date.now(),
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Get total tokens used across all requests
|
|
111
|
+
*/
|
|
112
|
+
getTotalTokensUsed() {
|
|
113
|
+
return this.totalTokensUsed;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Analyze a batch of packages using Gemini AI
|
|
117
|
+
*/
|
|
118
|
+
async analyzeBatch(request) {
|
|
119
|
+
// Check cache first
|
|
120
|
+
const cacheKey = this.getCacheKey(request);
|
|
121
|
+
const cached = this.getCachedResponse(cacheKey);
|
|
122
|
+
if (cached) {
|
|
123
|
+
return cached;
|
|
124
|
+
}
|
|
125
|
+
// Import prompts dynamically
|
|
126
|
+
const { buildPrompt } = await import('./prompts.js');
|
|
127
|
+
// Sanitize all scripts before sending to API
|
|
128
|
+
const sanitizedRequest = {
|
|
129
|
+
...request,
|
|
130
|
+
packages: request.packages.map(pkg => ({
|
|
131
|
+
...pkg,
|
|
132
|
+
scripts: this.sanitizeScripts(pkg.scripts),
|
|
133
|
+
})),
|
|
134
|
+
};
|
|
135
|
+
// Build prompt based on mode
|
|
136
|
+
const prompt = buildPrompt(sanitizedRequest, request.mode);
|
|
137
|
+
try {
|
|
138
|
+
// Call Gemini API with rate limiting
|
|
139
|
+
const throttledGenerate = await getThrottledGenerateContent();
|
|
140
|
+
const result = await throttledGenerate(this.model, prompt);
|
|
141
|
+
const response = result.response;
|
|
142
|
+
const text = response.text();
|
|
143
|
+
// Track token usage
|
|
144
|
+
const usage = response.usageMetadata;
|
|
145
|
+
if (usage) {
|
|
146
|
+
this.totalTokensUsed += usage.totalTokenCount || 0;
|
|
147
|
+
}
|
|
148
|
+
// Parse JSON response
|
|
149
|
+
let jsonResponse;
|
|
150
|
+
try {
|
|
151
|
+
// Extract JSON from markdown code blocks if present
|
|
152
|
+
const jsonMatch = text.match(/```json\n?([\s\S]*?)\n?```/) || text.match(/\{[\s\S]*\}/);
|
|
153
|
+
const jsonText = jsonMatch ? jsonMatch[1] || jsonMatch[0] : text;
|
|
154
|
+
jsonResponse = JSON.parse(jsonText);
|
|
155
|
+
}
|
|
156
|
+
catch (parseError) {
|
|
157
|
+
// Fallback: return empty analysis if parsing fails
|
|
158
|
+
console.warn('Failed to parse AI response, returning empty analysis');
|
|
159
|
+
jsonResponse = {
|
|
160
|
+
analyses: sanitizedRequest.packages.map(pkg => ({
|
|
161
|
+
package: pkg.name,
|
|
162
|
+
version: pkg.version,
|
|
163
|
+
falsePositivesFiltered: 0,
|
|
164
|
+
newThreatsDetected: 0,
|
|
165
|
+
insights: [],
|
|
166
|
+
confidence: 0,
|
|
167
|
+
tokensUsed: 0,
|
|
168
|
+
})),
|
|
169
|
+
totalTokensUsed: usage?.totalTokenCount || 0,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
// Cache the response
|
|
173
|
+
this.setCachedResponse(cacheKey, jsonResponse);
|
|
174
|
+
return jsonResponse;
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
// Handle API errors gracefully
|
|
178
|
+
if (error.status === 429) {
|
|
179
|
+
throw new Error('Rate limit exceeded. Please try again later.');
|
|
180
|
+
}
|
|
181
|
+
else if (error.status === 401) {
|
|
182
|
+
throw new Error('Invalid API key. Please check your GOOGLE_AI_API_KEY.');
|
|
183
|
+
}
|
|
184
|
+
else if (error.code === 'ECONNABORTED' || error.message?.includes('timeout')) {
|
|
185
|
+
throw new Error('Request timeout. The AI service took too long to respond.');
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
throw new Error(`AI analysis failed: ${error.message || 'Unknown error'}`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Clear the response cache
|
|
194
|
+
*/
|
|
195
|
+
clearCache() {
|
|
196
|
+
cache.clear();
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Get cache statistics
|
|
200
|
+
*/
|
|
201
|
+
getCacheStats() {
|
|
202
|
+
return {
|
|
203
|
+
size: cache.size,
|
|
204
|
+
keys: Array.from(cache.keys()),
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
exports.GeminiClient = GeminiClient;
|
|
209
|
+
/**
|
|
210
|
+
* Create a singleton Gemini client instance
|
|
211
|
+
*/
|
|
212
|
+
let clientInstance = null;
|
|
213
|
+
function getGeminiClient(apiKey) {
|
|
214
|
+
if (!clientInstance) {
|
|
215
|
+
clientInstance = new GeminiClient(apiKey);
|
|
216
|
+
}
|
|
217
|
+
return clientInstance;
|
|
218
|
+
}
|
|
219
|
+
function resetGeminiClient() {
|
|
220
|
+
clientInstance = null;
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=gemini-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-client.js","sourceRoot":"","sources":["../../src/ai/gemini-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** ScriptGuard — AI module exports */
|
|
2
|
+
export { GeminiClient, getGeminiClient, resetGeminiClient } from './gemini-client.js';
|
|
3
|
+
export { buildPrompt, sanitizeForPrompt } from './prompts.js';
|
|
4
|
+
export { analyzeFalsePositives, getFalsePositiveConfidence, } from './analyzers/false-positive-filter.js';
|
|
5
|
+
export { detectAdvancedThreats, } from './analyzers/threat-detector.js';
|
|
6
|
+
export { generateInsights, } from './analyzers/insight-generator.js';
|
|
7
|
+
export type { AIOptions, AIMode, AIAnalysis, AIInsight, AIBatchRequest, AIBatchResponse, } from '../types/index.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ai/index.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACtF,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EACL,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,qBAAqB,GACtB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,gBAAgB,GACjB,MAAM,kCAAkC,CAAC;AAG1C,YAAY,EACV,SAAS,EACT,MAAM,EACN,UAAU,EACV,SAAS,EACT,cAAc,EACd,eAAe,GAChB,MAAM,mBAAmB,CAAC"}
|
package/dist/ai/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/** ScriptGuard — AI module exports */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.generateInsights = exports.detectAdvancedThreats = exports.getFalsePositiveConfidence = exports.analyzeFalsePositives = exports.sanitizeForPrompt = exports.buildPrompt = exports.resetGeminiClient = exports.getGeminiClient = exports.GeminiClient = void 0;
|
|
5
|
+
var gemini_client_js_1 = require("./gemini-client.js");
|
|
6
|
+
Object.defineProperty(exports, "GeminiClient", { enumerable: true, get: function () { return gemini_client_js_1.GeminiClient; } });
|
|
7
|
+
Object.defineProperty(exports, "getGeminiClient", { enumerable: true, get: function () { return gemini_client_js_1.getGeminiClient; } });
|
|
8
|
+
Object.defineProperty(exports, "resetGeminiClient", { enumerable: true, get: function () { return gemini_client_js_1.resetGeminiClient; } });
|
|
9
|
+
var prompts_js_1 = require("./prompts.js");
|
|
10
|
+
Object.defineProperty(exports, "buildPrompt", { enumerable: true, get: function () { return prompts_js_1.buildPrompt; } });
|
|
11
|
+
Object.defineProperty(exports, "sanitizeForPrompt", { enumerable: true, get: function () { return prompts_js_1.sanitizeForPrompt; } });
|
|
12
|
+
var false_positive_filter_js_1 = require("./analyzers/false-positive-filter.js");
|
|
13
|
+
Object.defineProperty(exports, "analyzeFalsePositives", { enumerable: true, get: function () { return false_positive_filter_js_1.analyzeFalsePositives; } });
|
|
14
|
+
Object.defineProperty(exports, "getFalsePositiveConfidence", { enumerable: true, get: function () { return false_positive_filter_js_1.getFalsePositiveConfidence; } });
|
|
15
|
+
var threat_detector_js_1 = require("./analyzers/threat-detector.js");
|
|
16
|
+
Object.defineProperty(exports, "detectAdvancedThreats", { enumerable: true, get: function () { return threat_detector_js_1.detectAdvancedThreats; } });
|
|
17
|
+
var insight_generator_js_1 = require("./analyzers/insight-generator.js");
|
|
18
|
+
Object.defineProperty(exports, "generateInsights", { enumerable: true, get: function () { return insight_generator_js_1.generateInsights; } });
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ai/index.ts"],"names":[],"mappings":";AAAA,sCAAsC;;;AAEtC,uDAAsF;AAA7E,gHAAA,YAAY,OAAA;AAAE,mHAAA,eAAe,OAAA;AAAE,qHAAA,iBAAiB,OAAA;AACzD,2CAA8D;AAArD,yGAAA,WAAW,OAAA;AAAE,+GAAA,iBAAiB,OAAA;AACvC,iFAG8C;AAF5C,iIAAA,qBAAqB,OAAA;AACrB,sIAAA,0BAA0B,OAAA;AAE5B,qEAEwC;AADtC,2HAAA,qBAAqB,OAAA;AAEvB,yEAE0C;AADxC,wHAAA,gBAAgB,OAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** ScriptGuard — AI prompt templates for different analysis modes */
|
|
2
|
+
import type { AIMode, AIBatchRequest } from '../types/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Build the analysis prompt based on mode
|
|
5
|
+
*/
|
|
6
|
+
export declare function buildPrompt(request: AIBatchRequest, mode: AIMode): string;
|
|
7
|
+
/**
|
|
8
|
+
* Sanitize script content to remove obvious secrets before sending to AI
|
|
9
|
+
*/
|
|
10
|
+
export declare function sanitizeForPrompt(content: string): string;
|
|
11
|
+
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/ai/prompts.ts"],"names":[],"mappings":"AAAA,qEAAqE;AAErE,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEhE;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMzE;AAsMD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAQzD"}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/** ScriptGuard — AI prompt templates for different analysis modes */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.buildPrompt = buildPrompt;
|
|
5
|
+
exports.sanitizeForPrompt = sanitizeForPrompt;
|
|
6
|
+
/**
|
|
7
|
+
* Build the analysis prompt based on mode
|
|
8
|
+
*/
|
|
9
|
+
function buildPrompt(request, mode) {
|
|
10
|
+
const basePrompt = getBasePrompt();
|
|
11
|
+
const modePrompt = getModePrompt(mode);
|
|
12
|
+
const packageData = formatPackageData(request);
|
|
13
|
+
return `${basePrompt}\n\n${modePrompt}\n\n${packageData}\n\n${getOutputInstructions(mode)}`;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Base system prompt - context about ScriptGuard and npm security
|
|
17
|
+
*/
|
|
18
|
+
function getBasePrompt() {
|
|
19
|
+
return `You are ScriptGuard AI, an expert security analyst specializing in npm package supply chain attacks.
|
|
20
|
+
|
|
21
|
+
Your task is to analyze npm package lifecycle scripts (postinstall, preinstall, prepare, etc.) and provide security insights.
|
|
22
|
+
|
|
23
|
+
## Context
|
|
24
|
+
|
|
25
|
+
- **Supply chain attacks**: Malicious code often hides in lifecycle scripts that run automatically during \`npm install\`
|
|
26
|
+
- **Common threats**: Remote code execution (curl | bash), credential theft, data exfiltration, obfuscated payloads
|
|
27
|
+
- **False positives**: Many legitimate packages use similar patterns for build tools, platform-specific binaries, or configuration
|
|
28
|
+
|
|
29
|
+
## Your Role
|
|
30
|
+
|
|
31
|
+
1. **Distinguish safe from unsafe**: Understand context to identify false positives
|
|
32
|
+
2. **Detect advanced threats**: Identify obfuscated code, novel attack patterns, multi-stage attacks
|
|
33
|
+
3. **Provide actionable insights**: Explain threats clearly and suggest remediation steps
|
|
34
|
+
|
|
35
|
+
## Safety Rules
|
|
36
|
+
|
|
37
|
+
- **DO NOT** execute any code - analyze only
|
|
38
|
+
- **Assume malicious intent** unless there's clear evidence of legitimacy
|
|
39
|
+
- **Flag suspicious patterns** even if they might be legitimate - better safe than sorry
|
|
40
|
+
- **Consider the package context**: Unknown packages with risky scripts = higher suspicion`;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Mode-specific instructions
|
|
44
|
+
*/
|
|
45
|
+
function getModePrompt(mode) {
|
|
46
|
+
switch (mode) {
|
|
47
|
+
case 'basic':
|
|
48
|
+
return `## Analysis Mode: Basic
|
|
49
|
+
|
|
50
|
+
Focus on identifying **false positives** from regex pattern matching.
|
|
51
|
+
|
|
52
|
+
For each package with findings:
|
|
53
|
+
1. Analyze the script content and context
|
|
54
|
+
2. Determine if the pattern match represents a real threat or a false positive
|
|
55
|
+
3. Consider: Is this a well-known package? Does the pattern serve a legitimate purpose?
|
|
56
|
+
4. Provide brief explanation for your decision
|
|
57
|
+
|
|
58
|
+
**Time constraint**: Quick analysis, focus on obvious false positives`;
|
|
59
|
+
case 'standard':
|
|
60
|
+
return `## Analysis Mode: Standard
|
|
61
|
+
|
|
62
|
+
Provide comprehensive security analysis for each package.
|
|
63
|
+
|
|
64
|
+
For each package:
|
|
65
|
+
1. **False positive analysis**: Determine which regex matches are false positives
|
|
66
|
+
2. **Threat detection**: Identify advanced threats (obfuscation, novel patterns, multi-stage attacks)
|
|
67
|
+
3. **Contextual understanding**: What does this script actually do?
|
|
68
|
+
4. **Risk assessment**: Overall confidence in your analysis
|
|
69
|
+
|
|
70
|
+
**Output**: Balanced depth - detailed analysis without excessive detail`;
|
|
71
|
+
case 'thorough':
|
|
72
|
+
return `## Analysis Mode: Thorough
|
|
73
|
+
|
|
74
|
+
Perform deep security analysis with cross-script correlation.
|
|
75
|
+
|
|
76
|
+
For each package:
|
|
77
|
+
1. **Comprehensive false positive analysis**: Examine each finding in detail
|
|
78
|
+
2. **Advanced threat detection**: Identify obfuscation, encoding, polyglot code, novel attack patterns
|
|
79
|
+
3. **Cross-script correlation**: Analyze relationships between multiple lifecycle scripts
|
|
80
|
+
4. **Attack chain identification**: Detect multi-stage attacks across scripts
|
|
81
|
+
5. **Package reputation context**: Consider package name, version patterns, script complexity
|
|
82
|
+
6. **Detailed explanations**: Step-by-step breakdown of what the code does
|
|
83
|
+
|
|
84
|
+
**Output**: Maximum depth - leave no stone unturned`;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Format package data for the AI
|
|
89
|
+
*/
|
|
90
|
+
function formatPackageData(request) {
|
|
91
|
+
const packages = request.packages.map((pkg, idx) => {
|
|
92
|
+
const scriptsList = Object.entries(pkg.scripts)
|
|
93
|
+
.map(([name, content]) => `\`${name}\`: ${content}`)
|
|
94
|
+
.join('\n ');
|
|
95
|
+
const findingsList = pkg.findings.length > 0
|
|
96
|
+
? pkg.findings.map(f => ` - Pattern: \`${f.pattern}\` (Risk: ${f.riskLevel})\n` +
|
|
97
|
+
` Match: \`${f.match.substring(0, 100)}${f.match.length > 100 ? '...' : ''}\``).join('\n')
|
|
98
|
+
: ' (No regex findings)';
|
|
99
|
+
return `## Package ${idx + 1}: ${pkg.name}@${pkg.version}
|
|
100
|
+
|
|
101
|
+
**Lifecycle Scripts:**
|
|
102
|
+
${scriptsList}
|
|
103
|
+
|
|
104
|
+
**Regex Pattern Findings:**
|
|
105
|
+
${findingsList}`;
|
|
106
|
+
}).join('\n\n');
|
|
107
|
+
return `## Packages to Analyze
|
|
108
|
+
|
|
109
|
+
Total packages: ${request.packages.length}
|
|
110
|
+
|
|
111
|
+
${packages}`;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Output format instructions for the AI
|
|
115
|
+
*/
|
|
116
|
+
function getOutputInstructions(mode) {
|
|
117
|
+
return `## Required Output Format
|
|
118
|
+
|
|
119
|
+
Respond ONLY with valid JSON in this exact structure:
|
|
120
|
+
|
|
121
|
+
\`\`\`json
|
|
122
|
+
{
|
|
123
|
+
"analyses": [
|
|
124
|
+
{
|
|
125
|
+
"package": "package-name",
|
|
126
|
+
"version": "1.0.0",
|
|
127
|
+
"falsePositivesFiltered": 2,
|
|
128
|
+
"newThreatsDetected": 1,
|
|
129
|
+
"insights": [
|
|
130
|
+
{
|
|
131
|
+
"type": "false-positive",
|
|
132
|
+
"severity": "low",
|
|
133
|
+
"description": "Brief explanation of why this is a false positive",
|
|
134
|
+
"confidence": 0.9
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"type": "threat",
|
|
138
|
+
"severity": "high",
|
|
139
|
+
"description": "Detailed explanation of the threat",
|
|
140
|
+
"attackTechnique": "e.g., DNS tunneling, reverse shell, credential theft",
|
|
141
|
+
"remediation": "Specific steps to mitigate",
|
|
142
|
+
"confidence": 0.85
|
|
143
|
+
}
|
|
144
|
+
],
|
|
145
|
+
"confidence": 0.88,
|
|
146
|
+
"tokensUsed": 150
|
|
147
|
+
}
|
|
148
|
+
],
|
|
149
|
+
"totalTokensUsed": 150
|
|
150
|
+
}
|
|
151
|
+
\`\`\`
|
|
152
|
+
|
|
153
|
+
## Field Descriptions
|
|
154
|
+
|
|
155
|
+
- **type**: Either "false-positive", "threat", or "mitigation"
|
|
156
|
+
- **severity**: "low", "medium", "high", or "critical"
|
|
157
|
+
- **description**: Clear, concise explanation
|
|
158
|
+
- **attackTechnique**: (optional) Name of the attack technique (e.g., "reverse shell", "DNS exfiltration")
|
|
159
|
+
- **remediation**: (optional) Specific steps to fix or mitigate the issue
|
|
160
|
+
- **confidence**: Number from 0.0 to 1.0 indicating your certainty
|
|
161
|
+
|
|
162
|
+
## Insight Type Guidelines
|
|
163
|
+
|
|
164
|
+
**false-positive**: The regex match is actually safe
|
|
165
|
+
- Example: \`process.env.PORT\` is for config, not exfiltration
|
|
166
|
+
- Example: \`child_process\` compiling native modules
|
|
167
|
+
- Required fields: type, severity, description, confidence
|
|
168
|
+
|
|
169
|
+
**threat**: Confirmed security issue (including missed threats)
|
|
170
|
+
- Example: Obfuscated base64 payload
|
|
171
|
+
- Example: Suspicious network request to unknown domain
|
|
172
|
+
- Required fields: type, severity, description, attackTechnique (optional), remediation, confidence
|
|
173
|
+
|
|
174
|
+
**mitigation**: Remediation advice for confirmed threats
|
|
175
|
+
- Example: "Remove this script entirely" or "Replace with auditable alternative"
|
|
176
|
+
- Required fields: type, severity, description, remediation, confidence
|
|
177
|
+
|
|
178
|
+
## Confidence Scoring
|
|
179
|
+
|
|
180
|
+
- **0.9-1.0**: Very confident - clear evidence
|
|
181
|
+
- **0.7-0.9**: Confident - strong indicators
|
|
182
|
+
- **0.5-0.7**: Moderately confident - some ambiguity
|
|
183
|
+
- **0.3-0.5**: Low confidence - significant uncertainty
|
|
184
|
+
- **0.0-0.3**: Very uncertain - highly speculative
|
|
185
|
+
|
|
186
|
+
## Additional Guidelines
|
|
187
|
+
|
|
188
|
+
${mode === 'basic' ? `- Focus on obvious false positives
|
|
189
|
+
- Keep descriptions brief (1-2 sentences)
|
|
190
|
+
- Only report high-confidence findings (>0.7)` : mode === 'standard' ? `- Provide balanced detail
|
|
191
|
+
- Include both obvious and subtle findings
|
|
192
|
+
- Report moderate-confidence findings (>0.5)` : `- Be exhaustive in your analysis
|
|
193
|
+
- Report all findings regardless of confidence
|
|
194
|
+
- Provide detailed explanations and context
|
|
195
|
+
- Correlate findings across multiple scripts
|
|
196
|
+
- Consider package reputation and naming patterns`}
|
|
197
|
+
|
|
198
|
+
**CRITICAL**: Respond with ONLY the JSON. No markdown formatting, no explanations outside the JSON structure.`;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Sanitize script content to remove obvious secrets before sending to AI
|
|
202
|
+
*/
|
|
203
|
+
function sanitizeForPrompt(content) {
|
|
204
|
+
// Redact API keys, tokens, secrets
|
|
205
|
+
return content
|
|
206
|
+
.replace(/(?:api[_-]?key|secret|token)\s*[:=]\s*['"]?[a-zA-Z0-9_\-]{20,}['"]?/gi, '[REDACTED_SECRET]')
|
|
207
|
+
.replace(/bearer\s+[a-zA-Z0-9_\-]{20,}/gi, 'bearer [REDACTED_TOKEN]')
|
|
208
|
+
.replace(/sk-[a-zA-Z0-9]{48}/g, 'sk-[REDACTED]')
|
|
209
|
+
.replace(/ghp_[a-zA-Z0-9]{36}/g, 'ghp_[REDACTED]')
|
|
210
|
+
.replace(/AKIA[0-9A-Z]{16}/g, 'AKIA[REDACTED]');
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/ai/prompts.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,oCAAoC"}
|