@ai-jshook/mcp 0.1.1
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/.env.example +38 -0
- package/CLAUDE.md +170 -0
- package/README.md +564 -0
- package/bun.lock +1484 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -0
- package/dist/modules/analyzer/AISummarizer.d.ts +41 -0
- package/dist/modules/analyzer/AISummarizer.d.ts.map +1 -0
- package/dist/modules/analyzer/AISummarizer.js +186 -0
- package/dist/modules/analyzer/AISummarizer.js.map +1 -0
- package/dist/modules/analyzer/CodeAnalyzer.d.ts +28 -0
- package/dist/modules/analyzer/CodeAnalyzer.d.ts.map +1 -0
- package/dist/modules/analyzer/CodeAnalyzer.js +1287 -0
- package/dist/modules/analyzer/CodeAnalyzer.js.map +1 -0
- package/dist/modules/analyzer/IntelligentAnalyzer.d.ts +114 -0
- package/dist/modules/analyzer/IntelligentAnalyzer.d.ts.map +1 -0
- package/dist/modules/analyzer/IntelligentAnalyzer.js +1176 -0
- package/dist/modules/analyzer/IntelligentAnalyzer.js.map +1 -0
- package/dist/modules/browser/BrowserModeManager.d.ts +31 -0
- package/dist/modules/browser/BrowserModeManager.d.ts.map +1 -0
- package/dist/modules/browser/BrowserModeManager.js +241 -0
- package/dist/modules/browser/BrowserModeManager.js.map +1 -0
- package/dist/modules/captcha/AICaptchaDetector.d.ts +32 -0
- package/dist/modules/captcha/AICaptchaDetector.d.ts.map +1 -0
- package/dist/modules/captcha/AICaptchaDetector.js +387 -0
- package/dist/modules/captcha/AICaptchaDetector.js.map +1 -0
- package/dist/modules/captcha/CaptchaDetector.d.ts +28 -0
- package/dist/modules/captcha/CaptchaDetector.d.ts.map +1 -0
- package/dist/modules/captcha/CaptchaDetector.js +513 -0
- package/dist/modules/captcha/CaptchaDetector.js.map +1 -0
- package/dist/modules/collector/CodeCache.d.ts +37 -0
- package/dist/modules/collector/CodeCache.d.ts.map +1 -0
- package/dist/modules/collector/CodeCache.js +188 -0
- package/dist/modules/collector/CodeCache.js.map +1 -0
- package/dist/modules/collector/CodeCollector.d.ts +107 -0
- package/dist/modules/collector/CodeCollector.d.ts.map +1 -0
- package/dist/modules/collector/CodeCollector.js +796 -0
- package/dist/modules/collector/CodeCollector.js.map +1 -0
- package/dist/modules/collector/CodeCompressor.d.ts +65 -0
- package/dist/modules/collector/CodeCompressor.d.ts.map +1 -0
- package/dist/modules/collector/CodeCompressor.js +245 -0
- package/dist/modules/collector/CodeCompressor.js.map +1 -0
- package/dist/modules/collector/DOMInspector.d.ts +51 -0
- package/dist/modules/collector/DOMInspector.d.ts.map +1 -0
- package/dist/modules/collector/DOMInspector.js +437 -0
- package/dist/modules/collector/DOMInspector.js.map +1 -0
- package/dist/modules/collector/PageController.d.ts +79 -0
- package/dist/modules/collector/PageController.d.ts.map +1 -0
- package/dist/modules/collector/PageController.js +287 -0
- package/dist/modules/collector/PageController.js.map +1 -0
- package/dist/modules/collector/SmartCodeCollector.d.ts +38 -0
- package/dist/modules/collector/SmartCodeCollector.d.ts.map +1 -0
- package/dist/modules/collector/SmartCodeCollector.js +208 -0
- package/dist/modules/collector/SmartCodeCollector.js.map +1 -0
- package/dist/modules/collector/StreamingCollector.d.ts +46 -0
- package/dist/modules/collector/StreamingCollector.d.ts.map +1 -0
- package/dist/modules/collector/StreamingCollector.js +127 -0
- package/dist/modules/collector/StreamingCollector.js.map +1 -0
- package/dist/modules/crypto/CryptoDetector.d.ts +22 -0
- package/dist/modules/crypto/CryptoDetector.d.ts.map +1 -0
- package/dist/modules/crypto/CryptoDetector.js +168 -0
- package/dist/modules/crypto/CryptoDetector.js.map +1 -0
- package/dist/modules/crypto/CryptoDetectorEnhanced.d.ts +31 -0
- package/dist/modules/crypto/CryptoDetectorEnhanced.d.ts.map +1 -0
- package/dist/modules/crypto/CryptoDetectorEnhanced.js +269 -0
- package/dist/modules/crypto/CryptoDetectorEnhanced.js.map +1 -0
- package/dist/modules/crypto/CryptoRules.d.ts +59 -0
- package/dist/modules/crypto/CryptoRules.d.ts.map +1 -0
- package/dist/modules/crypto/CryptoRules.js +234 -0
- package/dist/modules/crypto/CryptoRules.js.map +1 -0
- package/dist/modules/debugger/BlackboxManager.d.ts +14 -0
- package/dist/modules/debugger/BlackboxManager.d.ts.map +1 -0
- package/dist/modules/debugger/BlackboxManager.js +98 -0
- package/dist/modules/debugger/BlackboxManager.js.map +1 -0
- package/dist/modules/debugger/DebuggerManager.d.ts +138 -0
- package/dist/modules/debugger/DebuggerManager.d.ts.map +1 -0
- package/dist/modules/debugger/DebuggerManager.js +777 -0
- package/dist/modules/debugger/DebuggerManager.js.map +1 -0
- package/dist/modules/debugger/EventBreakpointManager.d.ts +30 -0
- package/dist/modules/debugger/EventBreakpointManager.d.ts.map +1 -0
- package/dist/modules/debugger/EventBreakpointManager.js +125 -0
- package/dist/modules/debugger/EventBreakpointManager.js.map +1 -0
- package/dist/modules/debugger/RuntimeInspector.d.ts +54 -0
- package/dist/modules/debugger/RuntimeInspector.d.ts.map +1 -0
- package/dist/modules/debugger/RuntimeInspector.js +277 -0
- package/dist/modules/debugger/RuntimeInspector.js.map +1 -0
- package/dist/modules/debugger/ScriptManager.d.ts +94 -0
- package/dist/modules/debugger/ScriptManager.d.ts.map +1 -0
- package/dist/modules/debugger/ScriptManager.js +433 -0
- package/dist/modules/debugger/ScriptManager.js.map +1 -0
- package/dist/modules/debugger/WatchExpressionManager.d.ts +52 -0
- package/dist/modules/debugger/WatchExpressionManager.d.ts.map +1 -0
- package/dist/modules/debugger/WatchExpressionManager.js +136 -0
- package/dist/modules/debugger/WatchExpressionManager.js.map +1 -0
- package/dist/modules/debugger/XHRBreakpointManager.d.ts +21 -0
- package/dist/modules/debugger/XHRBreakpointManager.d.ts.map +1 -0
- package/dist/modules/debugger/XHRBreakpointManager.js +81 -0
- package/dist/modules/debugger/XHRBreakpointManager.js.map +1 -0
- package/dist/modules/deobfuscator/ASTOptimizer.d.ts +12 -0
- package/dist/modules/deobfuscator/ASTOptimizer.d.ts.map +1 -0
- package/dist/modules/deobfuscator/ASTOptimizer.js +234 -0
- package/dist/modules/deobfuscator/ASTOptimizer.js.map +1 -0
- package/dist/modules/deobfuscator/AdvancedDeobfuscator.d.ts +52 -0
- package/dist/modules/deobfuscator/AdvancedDeobfuscator.d.ts.map +1 -0
- package/dist/modules/deobfuscator/AdvancedDeobfuscator.js +985 -0
- package/dist/modules/deobfuscator/AdvancedDeobfuscator.js.map +1 -0
- package/dist/modules/deobfuscator/Deobfuscator.d.ts +23 -0
- package/dist/modules/deobfuscator/Deobfuscator.d.ts.map +1 -0
- package/dist/modules/deobfuscator/Deobfuscator.js +487 -0
- package/dist/modules/deobfuscator/Deobfuscator.js.map +1 -0
- package/dist/modules/deobfuscator/JSVMPDeobfuscator.d.ts +19 -0
- package/dist/modules/deobfuscator/JSVMPDeobfuscator.d.ts.map +1 -0
- package/dist/modules/deobfuscator/JSVMPDeobfuscator.js +594 -0
- package/dist/modules/deobfuscator/JSVMPDeobfuscator.js.map +1 -0
- package/dist/modules/deobfuscator/JScramberDeobfuscator.d.ts +28 -0
- package/dist/modules/deobfuscator/JScramberDeobfuscator.d.ts.map +1 -0
- package/dist/modules/deobfuscator/JScramberDeobfuscator.js +239 -0
- package/dist/modules/deobfuscator/JScramberDeobfuscator.js.map +1 -0
- package/dist/modules/deobfuscator/PackerDeobfuscator.d.ts +38 -0
- package/dist/modules/deobfuscator/PackerDeobfuscator.d.ts.map +1 -0
- package/dist/modules/deobfuscator/PackerDeobfuscator.js +191 -0
- package/dist/modules/deobfuscator/PackerDeobfuscator.js.map +1 -0
- package/dist/modules/detector/ObfuscationDetector.d.ts +35 -0
- package/dist/modules/detector/ObfuscationDetector.d.ts.map +1 -0
- package/dist/modules/detector/ObfuscationDetector.js +278 -0
- package/dist/modules/detector/ObfuscationDetector.js.map +1 -0
- package/dist/modules/emulator/AIEnvironmentAnalyzer.d.ts +32 -0
- package/dist/modules/emulator/AIEnvironmentAnalyzer.d.ts.map +1 -0
- package/dist/modules/emulator/AIEnvironmentAnalyzer.js +548 -0
- package/dist/modules/emulator/AIEnvironmentAnalyzer.js.map +1 -0
- package/dist/modules/emulator/BrowserAPIDatabase.d.ts +34 -0
- package/dist/modules/emulator/BrowserAPIDatabase.d.ts.map +1 -0
- package/dist/modules/emulator/BrowserAPIDatabase.js +326 -0
- package/dist/modules/emulator/BrowserAPIDatabase.js.map +1 -0
- package/dist/modules/emulator/BrowserEnvironmentRules.d.ts +47 -0
- package/dist/modules/emulator/BrowserEnvironmentRules.d.ts.map +1 -0
- package/dist/modules/emulator/BrowserEnvironmentRules.js +493 -0
- package/dist/modules/emulator/BrowserEnvironmentRules.js.map +1 -0
- package/dist/modules/emulator/EnvironmentEmulator.d.ts +27 -0
- package/dist/modules/emulator/EnvironmentEmulator.d.ts.map +1 -0
- package/dist/modules/emulator/EnvironmentEmulator.js +1113 -0
- package/dist/modules/emulator/EnvironmentEmulator.js.map +1 -0
- package/dist/modules/emulator/EnvironmentEmulatorEnhanced.d.ts +26 -0
- package/dist/modules/emulator/EnvironmentEmulatorEnhanced.d.ts.map +1 -0
- package/dist/modules/emulator/EnvironmentEmulatorEnhanced.js +493 -0
- package/dist/modules/emulator/EnvironmentEmulatorEnhanced.js.map +1 -0
- package/dist/modules/emulator/templates/chrome-env.d.ts +260 -0
- package/dist/modules/emulator/templates/chrome-env.d.ts.map +1 -0
- package/dist/modules/emulator/templates/chrome-env.js +253 -0
- package/dist/modules/emulator/templates/chrome-env.js.map +1 -0
- package/dist/modules/hook/AIHookGenerator.d.ts +53 -0
- package/dist/modules/hook/AIHookGenerator.d.ts.map +1 -0
- package/dist/modules/hook/AIHookGenerator.js +353 -0
- package/dist/modules/hook/AIHookGenerator.js.map +1 -0
- package/dist/modules/hook/HookManager.d.ts +67 -0
- package/dist/modules/hook/HookManager.d.ts.map +1 -0
- package/dist/modules/hook/HookManager.js +1225 -0
- package/dist/modules/hook/HookManager.js.map +1 -0
- package/dist/modules/monitor/ConsoleMonitor.d.ts +140 -0
- package/dist/modules/monitor/ConsoleMonitor.d.ts.map +1 -0
- package/dist/modules/monitor/ConsoleMonitor.js +834 -0
- package/dist/modules/monitor/ConsoleMonitor.js.map +1 -0
- package/dist/modules/monitor/PerformanceMonitor.d.ts +65 -0
- package/dist/modules/monitor/PerformanceMonitor.d.ts.map +1 -0
- package/dist/modules/monitor/PerformanceMonitor.js +175 -0
- package/dist/modules/monitor/PerformanceMonitor.js.map +1 -0
- package/dist/modules/stealth/StealthScripts2025.d.ts +17 -0
- package/dist/modules/stealth/StealthScripts2025.d.ts.map +1 -0
- package/dist/modules/stealth/StealthScripts2025.js +274 -0
- package/dist/modules/stealth/StealthScripts2025.js.map +1 -0
- package/dist/modules/symbolic/JSVMPSymbolicExecutor.d.ts +69 -0
- package/dist/modules/symbolic/JSVMPSymbolicExecutor.d.ts.map +1 -0
- package/dist/modules/symbolic/JSVMPSymbolicExecutor.js +232 -0
- package/dist/modules/symbolic/JSVMPSymbolicExecutor.js.map +1 -0
- package/dist/modules/symbolic/SymbolicExecutor.d.ts +69 -0
- package/dist/modules/symbolic/SymbolicExecutor.d.ts.map +1 -0
- package/dist/modules/symbolic/SymbolicExecutor.js +346 -0
- package/dist/modules/symbolic/SymbolicExecutor.js.map +1 -0
- package/dist/server/AIHookToolDefinitions.d.ts +3 -0
- package/dist/server/AIHookToolDefinitions.d.ts.map +1 -0
- package/dist/server/AIHookToolDefinitions.js +284 -0
- package/dist/server/AIHookToolDefinitions.js.map +1 -0
- package/dist/server/AIHookToolHandlers.d.ts +50 -0
- package/dist/server/AIHookToolHandlers.d.ts.map +1 -0
- package/dist/server/AIHookToolHandlers.js +311 -0
- package/dist/server/AIHookToolHandlers.js.map +1 -0
- package/dist/server/AdvancedToolDefinitions.d.ts +3 -0
- package/dist/server/AdvancedToolDefinitions.d.ts.map +1 -0
- package/dist/server/AdvancedToolDefinitions.js +218 -0
- package/dist/server/AdvancedToolDefinitions.js.map +1 -0
- package/dist/server/AdvancedToolHandlers.d.ts +85 -0
- package/dist/server/AdvancedToolHandlers.d.ts.map +1 -0
- package/dist/server/AdvancedToolHandlers.js +431 -0
- package/dist/server/AdvancedToolHandlers.js.map +1 -0
- package/dist/server/BrowserToolDefinitions.d.ts +3 -0
- package/dist/server/BrowserToolDefinitions.d.ts.map +1 -0
- package/dist/server/BrowserToolDefinitions.js +841 -0
- package/dist/server/BrowserToolDefinitions.js.map +1 -0
- package/dist/server/BrowserToolHandlers.d.ts +290 -0
- package/dist/server/BrowserToolHandlers.d.ts.map +1 -0
- package/dist/server/BrowserToolHandlers.js +784 -0
- package/dist/server/BrowserToolHandlers.js.map +1 -0
- package/dist/server/CacheToolDefinitions.d.ts +3 -0
- package/dist/server/CacheToolDefinitions.d.ts.map +1 -0
- package/dist/server/CacheToolDefinitions.js +166 -0
- package/dist/server/CacheToolDefinitions.js.map +1 -0
- package/dist/server/DebuggerToolDefinitions.d.ts +3 -0
- package/dist/server/DebuggerToolDefinitions.d.ts.map +1 -0
- package/dist/server/DebuggerToolDefinitions.js +600 -0
- package/dist/server/DebuggerToolDefinitions.js.map +1 -0
- package/dist/server/DebuggerToolHandlers.d.ts +230 -0
- package/dist/server/DebuggerToolHandlers.d.ts.map +1 -0
- package/dist/server/DebuggerToolHandlers.js +935 -0
- package/dist/server/DebuggerToolHandlers.js.map +1 -0
- package/dist/server/MCPServer.d.ts +55 -0
- package/dist/server/MCPServer.d.ts.map +1 -0
- package/dist/server/MCPServer.js +1344 -0
- package/dist/server/MCPServer.js.map +1 -0
- package/dist/server/TokenBudgetToolDefinitions.d.ts +3 -0
- package/dist/server/TokenBudgetToolDefinitions.d.ts.map +1 -0
- package/dist/server/TokenBudgetToolDefinitions.js +114 -0
- package/dist/server/TokenBudgetToolDefinitions.js.map +1 -0
- package/dist/services/LLMService.d.ts +41 -0
- package/dist/services/LLMService.d.ts.map +1 -0
- package/dist/services/LLMService.js +792 -0
- package/dist/services/LLMService.js.map +1 -0
- package/dist/types/index.d.ts +527 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/AdaptiveDataSerializer.d.ts +27 -0
- package/dist/utils/AdaptiveDataSerializer.d.ts.map +1 -0
- package/dist/utils/AdaptiveDataSerializer.js +215 -0
- package/dist/utils/AdaptiveDataSerializer.js.map +1 -0
- package/dist/utils/CacheAdapters.d.ts +30 -0
- package/dist/utils/CacheAdapters.d.ts.map +1 -0
- package/dist/utils/CacheAdapters.js +83 -0
- package/dist/utils/CacheAdapters.js.map +1 -0
- package/dist/utils/TokenBudgetManager.d.ts +52 -0
- package/dist/utils/TokenBudgetManager.d.ts.map +1 -0
- package/dist/utils/TokenBudgetManager.js +190 -0
- package/dist/utils/TokenBudgetManager.js.map +1 -0
- package/dist/utils/UnifiedCacheManager.d.ts +55 -0
- package/dist/utils/UnifiedCacheManager.d.ts.map +1 -0
- package/dist/utils/UnifiedCacheManager.js +207 -0
- package/dist/utils/UnifiedCacheManager.js.map +1 -0
- package/dist/utils/cache.d.ts +13 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +92 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/config.d.ts +7 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +93 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/detailedDataManager.d.ts +60 -0
- package/dist/utils/detailedDataManager.d.ts.map +1 -0
- package/dist/utils/detailedDataManager.js +204 -0
- package/dist/utils/detailedDataManager.js.map +1 -0
- package/dist/utils/logger.d.ts +16 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +47 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/parallel.d.ts +40 -0
- package/dist/utils/parallel.d.ts.map +1 -0
- package/dist/utils/parallel.js +148 -0
- package/dist/utils/parallel.js.map +1 -0
- package/package.json +94 -0
- package/server.json +39 -0
- package/tsconfig.dev.json +14 -0
|
@@ -0,0 +1,792 @@
|
|
|
1
|
+
import OpenAI from 'openai';
|
|
2
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
3
|
+
import { readFile } from 'fs/promises';
|
|
4
|
+
import { logger } from '../utils/logger.js';
|
|
5
|
+
export class LLMService {
|
|
6
|
+
config;
|
|
7
|
+
openai;
|
|
8
|
+
anthropic;
|
|
9
|
+
retryOptions = {
|
|
10
|
+
maxRetries: 3,
|
|
11
|
+
initialDelay: 1000,
|
|
12
|
+
maxDelay: 10000,
|
|
13
|
+
backoffMultiplier: 2,
|
|
14
|
+
};
|
|
15
|
+
constructor(config, retryOptions) {
|
|
16
|
+
this.config = config;
|
|
17
|
+
if (retryOptions) {
|
|
18
|
+
this.retryOptions = { ...this.retryOptions, ...retryOptions };
|
|
19
|
+
}
|
|
20
|
+
this.initClients();
|
|
21
|
+
}
|
|
22
|
+
initClients() {
|
|
23
|
+
if (this.config.provider === 'openai' && this.config.openai?.apiKey) {
|
|
24
|
+
this.openai = new OpenAI({
|
|
25
|
+
apiKey: this.config.openai.apiKey,
|
|
26
|
+
baseURL: this.config.openai.baseURL,
|
|
27
|
+
defaultHeaders: this.config.openai.headers,
|
|
28
|
+
});
|
|
29
|
+
logger.info('OpenAI client initialized');
|
|
30
|
+
}
|
|
31
|
+
if (this.config.provider === 'anthropic' && this.config.anthropic?.apiKey) {
|
|
32
|
+
this.anthropic = new Anthropic({
|
|
33
|
+
apiKey: this.config.anthropic.apiKey,
|
|
34
|
+
});
|
|
35
|
+
logger.info('Anthropic client initialized');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async chat(messages, options) {
|
|
39
|
+
return this.withRetry(async () => {
|
|
40
|
+
const startTime = Date.now();
|
|
41
|
+
try {
|
|
42
|
+
if (this.config.provider === 'openai') {
|
|
43
|
+
return await this.chatOpenAI(messages, options);
|
|
44
|
+
}
|
|
45
|
+
else if (this.config.provider === 'anthropic') {
|
|
46
|
+
return await this.chatAnthropic(messages, options);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
throw new Error(`Unsupported LLM provider: ${this.config.provider}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
finally {
|
|
53
|
+
const duration = Date.now() - startTime;
|
|
54
|
+
logger.debug(`LLM call completed in ${duration}ms`);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
async analyzeImage(imageInput, prompt, isFilePath = false) {
|
|
59
|
+
return this.withRetry(async () => {
|
|
60
|
+
const startTime = Date.now();
|
|
61
|
+
try {
|
|
62
|
+
let imageBase64;
|
|
63
|
+
if (isFilePath) {
|
|
64
|
+
logger.info(`📂 读取图片文件: ${imageInput}`);
|
|
65
|
+
const imageBuffer = await readFile(imageInput);
|
|
66
|
+
imageBase64 = imageBuffer.toString('base64');
|
|
67
|
+
logger.info(`✅ 图片文件已读取 (${(imageBuffer.length / 1024).toFixed(2)} KB)`);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
imageBase64 = imageInput;
|
|
71
|
+
}
|
|
72
|
+
if (this.config.provider === 'openai') {
|
|
73
|
+
if (!this.openai) {
|
|
74
|
+
throw new Error('OpenAI client not initialized');
|
|
75
|
+
}
|
|
76
|
+
const model = this.config.openai?.model || 'gpt-4-vision-preview';
|
|
77
|
+
const isVisionModel = model.includes('vision') || model.includes('gpt-4o') || model.includes('gpt-4-turbo');
|
|
78
|
+
if (!isVisionModel) {
|
|
79
|
+
logger.warn(`⚠️ 当前模型 ${model} 不支持图片分析,建议使用 gpt-4-vision-preview 或 gpt-4o`);
|
|
80
|
+
throw new Error(`Model ${model} does not support image analysis. ` +
|
|
81
|
+
`Please use gpt-4-vision-preview, gpt-4o, or gpt-4-turbo. ` +
|
|
82
|
+
`Current config: OPENAI_MODEL=${model}, OPENAI_BASE_URL=${this.config.openai?.baseURL || 'default'}`);
|
|
83
|
+
}
|
|
84
|
+
logger.info(`🖼️ Using OpenAI Vision model: ${model}`);
|
|
85
|
+
const response = await this.openai.chat.completions.create({
|
|
86
|
+
model,
|
|
87
|
+
messages: [
|
|
88
|
+
{
|
|
89
|
+
role: 'user',
|
|
90
|
+
content: [
|
|
91
|
+
{ type: 'text', text: prompt },
|
|
92
|
+
{
|
|
93
|
+
type: 'image_url',
|
|
94
|
+
image_url: {
|
|
95
|
+
url: `data:image/png;base64,${imageBase64}`,
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
max_tokens: 1000,
|
|
102
|
+
});
|
|
103
|
+
return response.choices[0]?.message?.content || '';
|
|
104
|
+
}
|
|
105
|
+
else if (this.config.provider === 'anthropic') {
|
|
106
|
+
if (!this.anthropic) {
|
|
107
|
+
throw new Error('Anthropic client not initialized');
|
|
108
|
+
}
|
|
109
|
+
const model = this.config.anthropic?.model || 'claude-3-opus-20240229';
|
|
110
|
+
const isVisionModel = model.includes('claude-3') || model.includes('claude-2.1');
|
|
111
|
+
if (!isVisionModel) {
|
|
112
|
+
logger.warn(`⚠️ 当前模型 ${model} 可能不支持图片分析,建议使用 claude-3-opus 或 claude-3-sonnet`);
|
|
113
|
+
}
|
|
114
|
+
logger.info(`🖼️ Using Anthropic Vision model: ${model}`);
|
|
115
|
+
const response = await this.anthropic.messages.create({
|
|
116
|
+
model,
|
|
117
|
+
max_tokens: 1000,
|
|
118
|
+
messages: [
|
|
119
|
+
{
|
|
120
|
+
role: 'user',
|
|
121
|
+
content: [
|
|
122
|
+
{
|
|
123
|
+
type: 'image',
|
|
124
|
+
source: {
|
|
125
|
+
type: 'base64',
|
|
126
|
+
media_type: 'image/png',
|
|
127
|
+
data: imageBase64,
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
type: 'text',
|
|
132
|
+
text: prompt,
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
},
|
|
136
|
+
],
|
|
137
|
+
});
|
|
138
|
+
const textContent = response.content.find((c) => c.type === 'text');
|
|
139
|
+
return textContent?.text || '';
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
throw new Error(`Unsupported LLM provider for image analysis: ${this.config.provider}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
147
|
+
logger.error('❌ Image analysis failed:', errorMessage);
|
|
148
|
+
if (errorMessage.includes('does not support image analysis')) {
|
|
149
|
+
logger.error('💡 解决方案:');
|
|
150
|
+
logger.error(' 1. 修改 .env 文件中的 OPENAI_MODEL 为 gpt-4-vision-preview 或 gpt-4o');
|
|
151
|
+
logger.error(' 2. 或者切换到 Anthropic: DEFAULT_LLM_PROVIDER=anthropic');
|
|
152
|
+
logger.error(' 3. 当前配置不支持AI验证码检测,将使用降级方案');
|
|
153
|
+
}
|
|
154
|
+
throw error;
|
|
155
|
+
}
|
|
156
|
+
finally {
|
|
157
|
+
const duration = Date.now() - startTime;
|
|
158
|
+
logger.debug(`Image analysis completed in ${duration}ms`);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
async withRetry(fn) {
|
|
163
|
+
let lastError;
|
|
164
|
+
let delay = this.retryOptions.initialDelay;
|
|
165
|
+
for (let attempt = 0; attempt <= this.retryOptions.maxRetries; attempt++) {
|
|
166
|
+
try {
|
|
167
|
+
return await fn();
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
171
|
+
if (!this.shouldRetry(lastError) || attempt === this.retryOptions.maxRetries) {
|
|
172
|
+
throw lastError;
|
|
173
|
+
}
|
|
174
|
+
logger.warn(`LLM call failed (attempt ${attempt + 1}/${this.retryOptions.maxRetries + 1}): ${lastError.message}`);
|
|
175
|
+
logger.debug(`Retrying in ${delay}ms...`);
|
|
176
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
177
|
+
delay = Math.min(delay * this.retryOptions.backoffMultiplier, this.retryOptions.maxDelay);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
throw lastError || new Error('Unknown error');
|
|
181
|
+
}
|
|
182
|
+
shouldRetry(error) {
|
|
183
|
+
const message = error.message.toLowerCase();
|
|
184
|
+
const retryableErrors = [
|
|
185
|
+
'rate limit',
|
|
186
|
+
'timeout',
|
|
187
|
+
'network',
|
|
188
|
+
'econnreset',
|
|
189
|
+
'enotfound',
|
|
190
|
+
'etimedout',
|
|
191
|
+
'429',
|
|
192
|
+
'500',
|
|
193
|
+
'502',
|
|
194
|
+
'503',
|
|
195
|
+
'504',
|
|
196
|
+
];
|
|
197
|
+
return retryableErrors.some((pattern) => message.includes(pattern));
|
|
198
|
+
}
|
|
199
|
+
async chatOpenAI(messages, options) {
|
|
200
|
+
if (!this.openai) {
|
|
201
|
+
throw new Error('OpenAI client not initialized');
|
|
202
|
+
}
|
|
203
|
+
const response = await this.openai.chat.completions.create({
|
|
204
|
+
model: this.config.openai?.model || 'gpt-4-turbo-preview',
|
|
205
|
+
messages: messages.map((msg) => ({
|
|
206
|
+
role: msg.role,
|
|
207
|
+
content: msg.content,
|
|
208
|
+
})),
|
|
209
|
+
temperature: options?.temperature ?? 0.7,
|
|
210
|
+
max_tokens: options?.maxTokens ?? 4000,
|
|
211
|
+
});
|
|
212
|
+
const choice = response.choices[0];
|
|
213
|
+
if (!choice?.message?.content) {
|
|
214
|
+
throw new Error('No response from OpenAI');
|
|
215
|
+
}
|
|
216
|
+
return {
|
|
217
|
+
content: choice.message.content,
|
|
218
|
+
usage: response.usage
|
|
219
|
+
? {
|
|
220
|
+
promptTokens: response.usage.prompt_tokens,
|
|
221
|
+
completionTokens: response.usage.completion_tokens,
|
|
222
|
+
totalTokens: response.usage.total_tokens,
|
|
223
|
+
}
|
|
224
|
+
: undefined,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
async chatAnthropic(messages, options) {
|
|
228
|
+
if (!this.anthropic) {
|
|
229
|
+
throw new Error('Anthropic client not initialized');
|
|
230
|
+
}
|
|
231
|
+
const systemMessage = messages.find((msg) => msg.role === 'system');
|
|
232
|
+
const userMessages = messages.filter((msg) => msg.role !== 'system');
|
|
233
|
+
const response = await this.anthropic.messages.create({
|
|
234
|
+
model: this.config.anthropic?.model || 'claude-3-5-sonnet-20241022',
|
|
235
|
+
max_tokens: options?.maxTokens ?? 4000,
|
|
236
|
+
temperature: options?.temperature ?? 0.7,
|
|
237
|
+
system: systemMessage?.content,
|
|
238
|
+
messages: userMessages.map((msg) => ({
|
|
239
|
+
role: msg.role === 'assistant' ? 'assistant' : 'user',
|
|
240
|
+
content: msg.content,
|
|
241
|
+
})),
|
|
242
|
+
});
|
|
243
|
+
const content = response.content[0];
|
|
244
|
+
if (!content || content.type !== 'text') {
|
|
245
|
+
throw new Error('Unexpected response type from Anthropic');
|
|
246
|
+
}
|
|
247
|
+
return {
|
|
248
|
+
content: content.text,
|
|
249
|
+
usage: {
|
|
250
|
+
promptTokens: response.usage.input_tokens,
|
|
251
|
+
completionTokens: response.usage.output_tokens,
|
|
252
|
+
totalTokens: response.usage.input_tokens + response.usage.output_tokens,
|
|
253
|
+
},
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
generateCodeAnalysisPrompt(code, focus) {
|
|
257
|
+
const systemPrompt = `# Role
|
|
258
|
+
You are an expert JavaScript/TypeScript reverse engineer and code analyst with 10+ years of experience in:
|
|
259
|
+
- Static code analysis and AST manipulation
|
|
260
|
+
- Security vulnerability detection (OWASP Top 10)
|
|
261
|
+
- Framework and library identification (React, Vue, Angular, etc.)
|
|
262
|
+
- Code obfuscation and deobfuscation techniques
|
|
263
|
+
- Software architecture and design patterns
|
|
264
|
+
|
|
265
|
+
# Task
|
|
266
|
+
Perform deep static analysis on the provided JavaScript code to extract:
|
|
267
|
+
1. Technical stack (frameworks, bundlers, libraries)
|
|
268
|
+
2. Code structure (functions, classes, modules)
|
|
269
|
+
3. Business logic and data flow
|
|
270
|
+
4. Security vulnerabilities and risks
|
|
271
|
+
5. Code quality metrics
|
|
272
|
+
|
|
273
|
+
# Output Requirements
|
|
274
|
+
- Return ONLY valid JSON (no markdown, no explanations outside JSON)
|
|
275
|
+
- Follow the exact schema provided in the user message
|
|
276
|
+
- Use confidence scores (0.0-1.0) for uncertain detections
|
|
277
|
+
- Provide specific line numbers for security risks when possible
|
|
278
|
+
- Be precise and avoid hallucination
|
|
279
|
+
|
|
280
|
+
# Analysis Methodology
|
|
281
|
+
1. First, identify the code's purpose and main functionality
|
|
282
|
+
2. Then, detect frameworks and libraries by analyzing imports and API usage
|
|
283
|
+
3. Next, map out the code structure and call graph
|
|
284
|
+
4. Finally, perform security analysis using OWASP guidelines`;
|
|
285
|
+
const userPrompt = `# Analysis Focus
|
|
286
|
+
Primary focus: ${focus}
|
|
287
|
+
|
|
288
|
+
# Code to Analyze
|
|
289
|
+
\`\`\`javascript
|
|
290
|
+
${code.length > 5000 ? code.substring(0, 5000) + '\n\n// ... (code truncated for analysis)' : code}
|
|
291
|
+
\`\`\`
|
|
292
|
+
|
|
293
|
+
# Required Output Schema
|
|
294
|
+
Return a JSON object with this EXACT structure (all fields are required):
|
|
295
|
+
|
|
296
|
+
\`\`\`json
|
|
297
|
+
{
|
|
298
|
+
"techStack": {
|
|
299
|
+
"framework": "string | null (e.g., 'React 18.x', 'Vue 3.x', 'Angular 15.x')",
|
|
300
|
+
"bundler": "string | null (e.g., 'Webpack 5', 'Vite', 'Rollup')",
|
|
301
|
+
"libraries": ["array of library names with versions if detectable"],
|
|
302
|
+
"confidence": 0.95
|
|
303
|
+
},
|
|
304
|
+
"structure": {
|
|
305
|
+
"functions": [
|
|
306
|
+
{
|
|
307
|
+
"name": "function name",
|
|
308
|
+
"type": "arrow | declaration | expression | async",
|
|
309
|
+
"purpose": "brief description of what it does",
|
|
310
|
+
"complexity": "low | medium | high",
|
|
311
|
+
"lineNumber": 42
|
|
312
|
+
}
|
|
313
|
+
],
|
|
314
|
+
"classes": [
|
|
315
|
+
{
|
|
316
|
+
"name": "class name",
|
|
317
|
+
"purpose": "brief description",
|
|
318
|
+
"methods": ["method1", "method2"],
|
|
319
|
+
"lineNumber": 100
|
|
320
|
+
}
|
|
321
|
+
],
|
|
322
|
+
"imports": ["list of imported modules"],
|
|
323
|
+
"exports": ["list of exported symbols"]
|
|
324
|
+
},
|
|
325
|
+
"businessLogic": {
|
|
326
|
+
"mainFeatures": ["feature 1", "feature 2"],
|
|
327
|
+
"dataFlow": "description of how data flows through the code",
|
|
328
|
+
"apiEndpoints": ["list of API endpoints if any"],
|
|
329
|
+
"stateManagement": "Redux | Vuex | Context API | none | unknown"
|
|
330
|
+
},
|
|
331
|
+
"securityRisks": [
|
|
332
|
+
{
|
|
333
|
+
"type": "XSS | SQL Injection | CSRF | Insecure Deserialization | etc.",
|
|
334
|
+
"severity": "critical | high | medium | low",
|
|
335
|
+
"description": "detailed description of the vulnerability",
|
|
336
|
+
"location": "line 123 or function name",
|
|
337
|
+
"cwe": "CWE-79",
|
|
338
|
+
"recommendation": "how to fix it"
|
|
339
|
+
}
|
|
340
|
+
],
|
|
341
|
+
"qualityScore": 85,
|
|
342
|
+
"qualityMetrics": {
|
|
343
|
+
"maintainability": 80,
|
|
344
|
+
"readability": 75,
|
|
345
|
+
"testability": 70,
|
|
346
|
+
"performance": 90
|
|
347
|
+
},
|
|
348
|
+
"summary": "2-3 sentence summary of the code's purpose and quality"
|
|
349
|
+
}
|
|
350
|
+
\`\`\`
|
|
351
|
+
|
|
352
|
+
# Example Output (for reference)
|
|
353
|
+
\`\`\`json
|
|
354
|
+
{
|
|
355
|
+
"techStack": {
|
|
356
|
+
"framework": "React 18.2",
|
|
357
|
+
"bundler": "Webpack 5",
|
|
358
|
+
"libraries": ["axios@1.4.0", "lodash@4.17.21"],
|
|
359
|
+
"confidence": 0.92
|
|
360
|
+
},
|
|
361
|
+
"structure": {
|
|
362
|
+
"functions": [
|
|
363
|
+
{"name": "fetchUserData", "type": "async", "purpose": "Fetches user data from API", "complexity": "medium", "lineNumber": 15}
|
|
364
|
+
],
|
|
365
|
+
"classes": [],
|
|
366
|
+
"imports": ["react", "axios"],
|
|
367
|
+
"exports": ["UserComponent"]
|
|
368
|
+
},
|
|
369
|
+
"businessLogic": {
|
|
370
|
+
"mainFeatures": ["User authentication", "Data fetching"],
|
|
371
|
+
"dataFlow": "User input -> API call -> State update -> UI render",
|
|
372
|
+
"apiEndpoints": ["/api/users", "/api/auth"],
|
|
373
|
+
"stateManagement": "React Hooks (useState, useEffect)"
|
|
374
|
+
},
|
|
375
|
+
"securityRisks": [
|
|
376
|
+
{
|
|
377
|
+
"type": "XSS",
|
|
378
|
+
"severity": "high",
|
|
379
|
+
"description": "User input directly inserted into innerHTML without sanitization",
|
|
380
|
+
"location": "line 45",
|
|
381
|
+
"cwe": "CWE-79",
|
|
382
|
+
"recommendation": "Use textContent or DOMPurify.sanitize()"
|
|
383
|
+
}
|
|
384
|
+
],
|
|
385
|
+
"qualityScore": 72,
|
|
386
|
+
"qualityMetrics": {
|
|
387
|
+
"maintainability": 75,
|
|
388
|
+
"readability": 80,
|
|
389
|
+
"testability": 65,
|
|
390
|
+
"performance": 70
|
|
391
|
+
},
|
|
392
|
+
"summary": "React component for user management with API integration. Contains XSS vulnerability and lacks error handling."
|
|
393
|
+
}
|
|
394
|
+
\`\`\`
|
|
395
|
+
|
|
396
|
+
Now analyze the provided code and return ONLY the JSON output (no additional text).`;
|
|
397
|
+
return [
|
|
398
|
+
{ role: 'system', content: systemPrompt },
|
|
399
|
+
{ role: 'user', content: userPrompt },
|
|
400
|
+
];
|
|
401
|
+
}
|
|
402
|
+
generateCryptoDetectionPrompt(code) {
|
|
403
|
+
const systemPrompt = `# Role
|
|
404
|
+
You are a cryptography and security expert specializing in:
|
|
405
|
+
- Cryptographic algorithm identification (AES, RSA, DES, 3DES, Blowfish, etc.)
|
|
406
|
+
- JavaScript crypto library analysis (CryptoJS, JSEncrypt, Web Crypto API, crypto-js, forge, etc.)
|
|
407
|
+
- Security assessment based on NIST and OWASP standards
|
|
408
|
+
- Cryptographic parameter extraction (keys, IVs, modes, padding)
|
|
409
|
+
- Vulnerability detection in crypto implementations
|
|
410
|
+
|
|
411
|
+
# Expertise Areas
|
|
412
|
+
- Symmetric encryption: AES, DES, 3DES, Blowfish, ChaCha20
|
|
413
|
+
- Asymmetric encryption: RSA, ECC, ElGamal
|
|
414
|
+
- Hash functions: MD5, SHA-1, SHA-256, SHA-512, BLAKE2
|
|
415
|
+
- Encoding: Base64, Hex, URL encoding
|
|
416
|
+
- Key derivation: PBKDF2, scrypt, bcrypt
|
|
417
|
+
- Message authentication: HMAC, CMAC
|
|
418
|
+
|
|
419
|
+
# Task
|
|
420
|
+
Analyze the provided JavaScript code to:
|
|
421
|
+
1. Identify ALL cryptographic algorithms and their variants
|
|
422
|
+
2. Detect crypto libraries and their versions
|
|
423
|
+
3. Extract cryptographic parameters (keys, IVs, salts, modes, padding)
|
|
424
|
+
4. Assess security strength and identify vulnerabilities
|
|
425
|
+
5. Provide actionable security recommendations
|
|
426
|
+
|
|
427
|
+
# Analysis Standards
|
|
428
|
+
- Use NIST SP 800-175B for algorithm strength assessment
|
|
429
|
+
- Follow OWASP Cryptographic Storage Cheat Sheet
|
|
430
|
+
- Identify deprecated/weak algorithms (MD5, SHA-1, DES, RC4)
|
|
431
|
+
- Check for hardcoded keys and weak key generation`;
|
|
432
|
+
const userPrompt = `# Code to Analyze
|
|
433
|
+
\`\`\`javascript
|
|
434
|
+
${code.length > 4000 ? code.substring(0, 4000) + '\n\n// ... (code truncated)' : code}
|
|
435
|
+
\`\`\`
|
|
436
|
+
|
|
437
|
+
# Required Output Schema
|
|
438
|
+
Return ONLY valid JSON with this exact structure:
|
|
439
|
+
|
|
440
|
+
\`\`\`json
|
|
441
|
+
{
|
|
442
|
+
"algorithms": [
|
|
443
|
+
{
|
|
444
|
+
"name": "string (e.g., 'AES-256-CBC', 'RSA-2048', 'SHA-256')",
|
|
445
|
+
"type": "symmetric | asymmetric | hash | encoding | kdf | mac",
|
|
446
|
+
"variant": "string (e.g., 'CBC', 'GCM', 'PKCS1', 'OAEP')",
|
|
447
|
+
"confidence": 0.95,
|
|
448
|
+
"location": {
|
|
449
|
+
"line": 42,
|
|
450
|
+
"function": "encryptData",
|
|
451
|
+
"codeSnippet": "CryptoJS.AES.encrypt(...)"
|
|
452
|
+
},
|
|
453
|
+
"parameters": {
|
|
454
|
+
"keySize": "128 | 192 | 256 | 1024 | 2048 | 4096 | null",
|
|
455
|
+
"key": "hardcoded | derived | imported | unknown",
|
|
456
|
+
"keyValue": "actual key if hardcoded (first 20 chars) or null",
|
|
457
|
+
"iv": "present | absent | hardcoded | random",
|
|
458
|
+
"mode": "CBC | GCM | ECB | CTR | CFB | OFB | null",
|
|
459
|
+
"padding": "PKCS7 | PKCS5 | NoPadding | OAEP | PSS | null",
|
|
460
|
+
"salt": "present | absent",
|
|
461
|
+
"iterations": 10000
|
|
462
|
+
},
|
|
463
|
+
"usage": "encryption | decryption | hashing | signing | verification",
|
|
464
|
+
"securityIssues": ["issue 1", "issue 2"]
|
|
465
|
+
}
|
|
466
|
+
],
|
|
467
|
+
"libraries": [
|
|
468
|
+
{
|
|
469
|
+
"name": "CryptoJS | crypto-js | JSEncrypt | forge | sjcl | Web Crypto API | node:crypto",
|
|
470
|
+
"version": "4.1.1 | unknown",
|
|
471
|
+
"confidence": 0.92,
|
|
472
|
+
"detectionMethod": "import statement | CDN link | global object | API usage"
|
|
473
|
+
}
|
|
474
|
+
],
|
|
475
|
+
"securityAssessment": {
|
|
476
|
+
"overallStrength": "strong | medium | weak | critical",
|
|
477
|
+
"score": 75,
|
|
478
|
+
"weakAlgorithms": [
|
|
479
|
+
{
|
|
480
|
+
"algorithm": "MD5",
|
|
481
|
+
"reason": "Cryptographically broken, vulnerable to collision attacks",
|
|
482
|
+
"severity": "critical | high | medium | low",
|
|
483
|
+
"cwe": "CWE-327"
|
|
484
|
+
}
|
|
485
|
+
],
|
|
486
|
+
"hardcodedSecrets": [
|
|
487
|
+
{
|
|
488
|
+
"type": "encryption key | API key | password",
|
|
489
|
+
"location": "line 15",
|
|
490
|
+
"value": "first 10 chars...",
|
|
491
|
+
"severity": "critical"
|
|
492
|
+
}
|
|
493
|
+
],
|
|
494
|
+
"vulnerabilities": [
|
|
495
|
+
{
|
|
496
|
+
"type": "ECB mode usage | Weak key | No IV | Predictable IV | etc.",
|
|
497
|
+
"description": "detailed description",
|
|
498
|
+
"impact": "data leakage | authentication bypass | etc.",
|
|
499
|
+
"cvss": 7.5,
|
|
500
|
+
"cwe": "CWE-326"
|
|
501
|
+
}
|
|
502
|
+
],
|
|
503
|
+
"recommendations": [
|
|
504
|
+
{
|
|
505
|
+
"priority": "critical | high | medium | low",
|
|
506
|
+
"issue": "what's wrong",
|
|
507
|
+
"solution": "how to fix it",
|
|
508
|
+
"example": "code example if applicable"
|
|
509
|
+
}
|
|
510
|
+
]
|
|
511
|
+
},
|
|
512
|
+
"summary": "Brief summary of crypto usage and main security concerns"
|
|
513
|
+
}
|
|
514
|
+
\`\`\`
|
|
515
|
+
|
|
516
|
+
# Example Output
|
|
517
|
+
\`\`\`json
|
|
518
|
+
{
|
|
519
|
+
"algorithms": [
|
|
520
|
+
{
|
|
521
|
+
"name": "AES-256-CBC",
|
|
522
|
+
"type": "symmetric",
|
|
523
|
+
"variant": "CBC",
|
|
524
|
+
"confidence": 0.98,
|
|
525
|
+
"location": {"line": 23, "function": "encryptPassword", "codeSnippet": "CryptoJS.AES.encrypt(data, key)"},
|
|
526
|
+
"parameters": {
|
|
527
|
+
"keySize": "256",
|
|
528
|
+
"key": "hardcoded",
|
|
529
|
+
"keyValue": "mySecretKey12345...",
|
|
530
|
+
"iv": "absent",
|
|
531
|
+
"mode": "CBC",
|
|
532
|
+
"padding": "PKCS7",
|
|
533
|
+
"salt": "absent",
|
|
534
|
+
"iterations": null
|
|
535
|
+
},
|
|
536
|
+
"usage": "encryption",
|
|
537
|
+
"securityIssues": ["Hardcoded key", "No IV specified (using default)"]
|
|
538
|
+
}
|
|
539
|
+
],
|
|
540
|
+
"libraries": [
|
|
541
|
+
{"name": "CryptoJS", "version": "4.1.1", "confidence": 0.95, "detectionMethod": "CDN link"}
|
|
542
|
+
],
|
|
543
|
+
"securityAssessment": {
|
|
544
|
+
"overallStrength": "weak",
|
|
545
|
+
"score": 35,
|
|
546
|
+
"weakAlgorithms": [],
|
|
547
|
+
"hardcodedSecrets": [
|
|
548
|
+
{"type": "encryption key", "location": "line 10", "value": "mySecretKe...", "severity": "critical"}
|
|
549
|
+
],
|
|
550
|
+
"vulnerabilities": [
|
|
551
|
+
{
|
|
552
|
+
"type": "Hardcoded encryption key",
|
|
553
|
+
"description": "Encryption key is hardcoded in source code",
|
|
554
|
+
"impact": "Anyone with access to code can decrypt all data",
|
|
555
|
+
"cvss": 9.1,
|
|
556
|
+
"cwe": "CWE-321"
|
|
557
|
+
}
|
|
558
|
+
],
|
|
559
|
+
"recommendations": [
|
|
560
|
+
{
|
|
561
|
+
"priority": "critical",
|
|
562
|
+
"issue": "Hardcoded encryption key",
|
|
563
|
+
"solution": "Use environment variables or secure key management service (KMS)",
|
|
564
|
+
"example": "const key = process.env.ENCRYPTION_KEY;"
|
|
565
|
+
}
|
|
566
|
+
]
|
|
567
|
+
},
|
|
568
|
+
"summary": "Uses AES-256-CBC with CryptoJS but has critical security flaw: hardcoded encryption key. Immediate remediation required."
|
|
569
|
+
}
|
|
570
|
+
\`\`\`
|
|
571
|
+
|
|
572
|
+
Now analyze the code and return ONLY the JSON output.`;
|
|
573
|
+
return [
|
|
574
|
+
{ role: 'system', content: systemPrompt },
|
|
575
|
+
{ role: 'user', content: userPrompt },
|
|
576
|
+
];
|
|
577
|
+
}
|
|
578
|
+
generateDeobfuscationPrompt(code) {
|
|
579
|
+
const systemPrompt = `# Role
|
|
580
|
+
You are an expert JavaScript reverse engineer specializing in:
|
|
581
|
+
- Code deobfuscation and obfuscation pattern recognition
|
|
582
|
+
- Obfuscator tool identification (javascript-obfuscator, UglifyJS, Terser, Webpack, etc.)
|
|
583
|
+
- Control flow analysis and simplification
|
|
584
|
+
- Semantic code understanding and variable naming
|
|
585
|
+
- AST manipulation and code transformation
|
|
586
|
+
|
|
587
|
+
# Known Obfuscation Techniques
|
|
588
|
+
1. **String Array Obfuscation**: Strings stored in arrays with index-based access
|
|
589
|
+
2. **Control Flow Flattening**: Switch-case state machines replacing normal control flow
|
|
590
|
+
3. **Dead Code Injection**: Unreachable code blocks (if(false){...})
|
|
591
|
+
4. **Opaque Predicates**: Always-true/false conditions (if(5>3){...})
|
|
592
|
+
5. **Variable Name Mangling**: _0x1234, _0xabcd style names
|
|
593
|
+
6. **Function Inlining/Outlining**: Moving code between functions
|
|
594
|
+
7. **Encoding**: Hex, Unicode, Base64 encoded strings
|
|
595
|
+
8. **VM Protection**: Custom virtual machine interpreters
|
|
596
|
+
9. **Self-Defending**: Anti-debugging and anti-tampering code
|
|
597
|
+
|
|
598
|
+
# Task
|
|
599
|
+
Analyze the obfuscated code to:
|
|
600
|
+
1. Identify the obfuscation type and tool used
|
|
601
|
+
2. Understand the actual program logic
|
|
602
|
+
3. Suggest meaningful variable and function names
|
|
603
|
+
4. Provide deobfuscated code if possible
|
|
604
|
+
5. Explain the deobfuscation process step-by-step
|
|
605
|
+
|
|
606
|
+
# Constraints
|
|
607
|
+
- Preserve exact program functionality
|
|
608
|
+
- Do NOT guess or hallucinate functionality
|
|
609
|
+
- If uncertain, mark with confidence scores
|
|
610
|
+
- Provide partial results if full deobfuscation is not possible`;
|
|
611
|
+
const userPrompt = `# Obfuscated Code
|
|
612
|
+
\`\`\`javascript
|
|
613
|
+
${code.length > 3000 ? code.substring(0, 3000) + '\n\n// ... (code truncated)' : code}
|
|
614
|
+
\`\`\`
|
|
615
|
+
|
|
616
|
+
# Required Output Schema
|
|
617
|
+
Return ONLY valid JSON:
|
|
618
|
+
|
|
619
|
+
\`\`\`json
|
|
620
|
+
{
|
|
621
|
+
"obfuscationType": {
|
|
622
|
+
"primary": "string-array | control-flow-flattening | vm-protection | mixed | unknown",
|
|
623
|
+
"techniques": ["technique 1", "technique 2"],
|
|
624
|
+
"tool": "javascript-obfuscator | webpack | uglify | terser | custom | unknown",
|
|
625
|
+
"toolVersion": "string or null",
|
|
626
|
+
"confidence": 0.85
|
|
627
|
+
},
|
|
628
|
+
"analysis": {
|
|
629
|
+
"codeStructure": "description of overall structure",
|
|
630
|
+
"mainLogic": "what the code actually does",
|
|
631
|
+
"keyFunctions": [
|
|
632
|
+
{
|
|
633
|
+
"obfuscatedName": "_0x1234",
|
|
634
|
+
"purpose": "what it does",
|
|
635
|
+
"confidence": 0.9
|
|
636
|
+
}
|
|
637
|
+
],
|
|
638
|
+
"dataFlow": "how data flows through the code",
|
|
639
|
+
"externalDependencies": ["list of external APIs or libraries used"]
|
|
640
|
+
},
|
|
641
|
+
"suggestions": {
|
|
642
|
+
"variableRenames": {
|
|
643
|
+
"_0x1234": {"suggested": "userId", "reason": "stores user ID from API", "confidence": 0.95},
|
|
644
|
+
"_0x5678": {"suggested": "apiKey", "reason": "used in authentication header", "confidence": 0.88}
|
|
645
|
+
},
|
|
646
|
+
"functionRenames": {
|
|
647
|
+
"_0xabcd": {"suggested": "encryptPassword", "reason": "calls CryptoJS.AES.encrypt", "confidence": 0.92}
|
|
648
|
+
},
|
|
649
|
+
"simplifications": [
|
|
650
|
+
{
|
|
651
|
+
"type": "remove dead code | unflatten control flow | decode strings",
|
|
652
|
+
"description": "what to simplify",
|
|
653
|
+
"impact": "high | medium | low"
|
|
654
|
+
}
|
|
655
|
+
]
|
|
656
|
+
},
|
|
657
|
+
"deobfuscationSteps": [
|
|
658
|
+
"Step 1: Extract string array at line 1-5",
|
|
659
|
+
"Step 2: Replace string array calls with actual strings",
|
|
660
|
+
"Step 3: Simplify control flow in function _0x1234",
|
|
661
|
+
"Step 4: Rename variables based on usage context"
|
|
662
|
+
],
|
|
663
|
+
"deobfuscatedCode": "string or null (full deobfuscated code if possible)",
|
|
664
|
+
"partialResults": {
|
|
665
|
+
"stringArrayDecoded": {"_0x0": "hello", "_0x1": "world"},
|
|
666
|
+
"decodedFunctions": [
|
|
667
|
+
{
|
|
668
|
+
"original": "function _0x1234(){...}",
|
|
669
|
+
"deobfuscated": "function getUserData(){...}",
|
|
670
|
+
"confidence": 0.85
|
|
671
|
+
}
|
|
672
|
+
]
|
|
673
|
+
},
|
|
674
|
+
"limitations": ["what couldn't be deobfuscated and why"],
|
|
675
|
+
"summary": "Brief summary of obfuscation and deobfuscation results"
|
|
676
|
+
}
|
|
677
|
+
\`\`\`
|
|
678
|
+
|
|
679
|
+
# Example Output
|
|
680
|
+
\`\`\`json
|
|
681
|
+
{
|
|
682
|
+
"obfuscationType": {
|
|
683
|
+
"primary": "string-array",
|
|
684
|
+
"techniques": ["string-array", "variable-mangling", "dead-code-injection"],
|
|
685
|
+
"tool": "javascript-obfuscator",
|
|
686
|
+
"toolVersion": "4.0.0",
|
|
687
|
+
"confidence": 0.92
|
|
688
|
+
},
|
|
689
|
+
"analysis": {
|
|
690
|
+
"codeStructure": "IIFE with string array at top, followed by main logic",
|
|
691
|
+
"mainLogic": "Fetches user data from API and encrypts password before sending",
|
|
692
|
+
"keyFunctions": [
|
|
693
|
+
{"obfuscatedName": "_0x1a2b", "purpose": "Decodes strings from array", "confidence": 0.98},
|
|
694
|
+
{"obfuscatedName": "_0x3c4d", "purpose": "Makes API request", "confidence": 0.95}
|
|
695
|
+
],
|
|
696
|
+
"dataFlow": "User input -> validation -> encryption -> API call -> response handling",
|
|
697
|
+
"externalDependencies": ["fetch API", "CryptoJS"]
|
|
698
|
+
},
|
|
699
|
+
"suggestions": {
|
|
700
|
+
"variableRenames": {
|
|
701
|
+
"_0x1a2b": {"suggested": "decodeString", "reason": "accesses string array with index", "confidence": 0.98},
|
|
702
|
+
"_0x3c4d": {"suggested": "fetchUserData", "reason": "calls fetch() with /api/users", "confidence": 0.95}
|
|
703
|
+
},
|
|
704
|
+
"functionRenames": {
|
|
705
|
+
"_0x5e6f": {"suggested": "encryptPassword", "reason": "uses CryptoJS.AES.encrypt", "confidence": 0.92}
|
|
706
|
+
},
|
|
707
|
+
"simplifications": [
|
|
708
|
+
{"type": "decode strings", "description": "Replace all string array calls with actual strings", "impact": "high"},
|
|
709
|
+
{"type": "remove dead code", "description": "Remove if(false) blocks at lines 45-60", "impact": "medium"}
|
|
710
|
+
]
|
|
711
|
+
},
|
|
712
|
+
"deobfuscationSteps": [
|
|
713
|
+
"Step 1: Identified string array: ['hello', 'world', 'api', 'user']",
|
|
714
|
+
"Step 2: Replaced _0x1a2b(0) with 'hello', _0x1a2b(1) with 'world'",
|
|
715
|
+
"Step 3: Removed dead code blocks",
|
|
716
|
+
"Step 4: Renamed functions based on their actual purpose"
|
|
717
|
+
],
|
|
718
|
+
"deobfuscatedCode": "// Partially deobfuscated\nfunction fetchUserData(userId) {\n const apiUrl = 'https://api.example.com/users/' + userId;\n return fetch(apiUrl);\n}",
|
|
719
|
+
"partialResults": {
|
|
720
|
+
"stringArrayDecoded": {"_0x0": "hello", "_0x1": "world", "_0x2": "api"},
|
|
721
|
+
"decodedFunctions": [
|
|
722
|
+
{"original": "function _0x3c4d(_0x1){...}", "deobfuscated": "function fetchUserData(userId){...}", "confidence": 0.95}
|
|
723
|
+
]
|
|
724
|
+
},
|
|
725
|
+
"limitations": ["VM-protected section at lines 100-200 could not be fully deobfuscated", "Some variable names are uncertain due to lack of context"],
|
|
726
|
+
"summary": "Code uses javascript-obfuscator with string array and dead code injection. Successfully decoded 80% of the code. Main functionality is user data fetching with password encryption."
|
|
727
|
+
}
|
|
728
|
+
\`\`\`
|
|
729
|
+
|
|
730
|
+
Now analyze the obfuscated code and return ONLY the JSON output.`;
|
|
731
|
+
return [
|
|
732
|
+
{ role: 'system', content: systemPrompt },
|
|
733
|
+
{ role: 'user', content: userPrompt },
|
|
734
|
+
];
|
|
735
|
+
}
|
|
736
|
+
generateTaintAnalysisPrompt(code, sources, sinks) {
|
|
737
|
+
const systemPrompt = `# Role
|
|
738
|
+
You are a security researcher specializing in:
|
|
739
|
+
- Taint analysis and data flow tracking
|
|
740
|
+
- OWASP Top 10 vulnerability detection
|
|
741
|
+
- Source-Sink-Sanitizer analysis
|
|
742
|
+
- XSS, SQL Injection, Command Injection detection
|
|
743
|
+
- Secure coding practices
|
|
744
|
+
|
|
745
|
+
# Task
|
|
746
|
+
Analyze data flow from sources (user input) to sinks (dangerous operations) to identify security vulnerabilities.
|
|
747
|
+
|
|
748
|
+
# Methodology
|
|
749
|
+
1. Identify all data sources (user input, network, storage)
|
|
750
|
+
2. Track data flow through variables, functions, and operations
|
|
751
|
+
3. Identify sanitizers (validation, encoding, escaping)
|
|
752
|
+
4. Detect dangerous sinks (eval, innerHTML, SQL queries)
|
|
753
|
+
5. Report vulnerable paths where tainted data reaches sinks without sanitization`;
|
|
754
|
+
const userPrompt = `# Code to Analyze
|
|
755
|
+
\`\`\`javascript
|
|
756
|
+
${code.length > 4000 ? code.substring(0, 4000) + '\n\n// ... (truncated)' : code}
|
|
757
|
+
\`\`\`
|
|
758
|
+
|
|
759
|
+
# Detected Sources
|
|
760
|
+
${sources.map(s => `- ${s}`).join('\n')}
|
|
761
|
+
|
|
762
|
+
# Detected Sinks
|
|
763
|
+
${sinks.map(s => `- ${s}`).join('\n')}
|
|
764
|
+
|
|
765
|
+
# Required Output
|
|
766
|
+
Return JSON with taint paths and vulnerabilities:
|
|
767
|
+
|
|
768
|
+
\`\`\`json
|
|
769
|
+
{
|
|
770
|
+
"taintPaths": [
|
|
771
|
+
{
|
|
772
|
+
"source": {"type": "user_input", "location": "line 10", "variable": "userInput"},
|
|
773
|
+
"sink": {"type": "eval", "location": "line 50", "variable": "code"},
|
|
774
|
+
"path": ["userInput -> processData -> sanitize? -> code -> eval"],
|
|
775
|
+
"sanitized": false,
|
|
776
|
+
"vulnerability": "Code Injection",
|
|
777
|
+
"severity": "critical",
|
|
778
|
+
"cwe": "CWE-94"
|
|
779
|
+
}
|
|
780
|
+
],
|
|
781
|
+
"summary": "Found X vulnerable paths"
|
|
782
|
+
}
|
|
783
|
+
\`\`\`
|
|
784
|
+
|
|
785
|
+
Return ONLY the JSON output.`;
|
|
786
|
+
return [
|
|
787
|
+
{ role: 'system', content: systemPrompt },
|
|
788
|
+
{ role: 'user', content: userPrompt },
|
|
789
|
+
];
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
//# sourceMappingURL=LLMService.js.map
|