crawlforge-mcp-server 3.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/CLAUDE.md +315 -0
- package/LICENSE +21 -0
- package/README.md +181 -0
- package/package.json +115 -0
- package/server.js +1963 -0
- package/setup.js +112 -0
- package/src/constants/config.js +615 -0
- package/src/core/ActionExecutor.js +1104 -0
- package/src/core/AlertNotificationSystem.js +601 -0
- package/src/core/AuthManager.js +315 -0
- package/src/core/ChangeTracker.js +2306 -0
- package/src/core/JobManager.js +687 -0
- package/src/core/LLMsTxtAnalyzer.js +753 -0
- package/src/core/LocalizationManager.js +1615 -0
- package/src/core/PerformanceManager.js +828 -0
- package/src/core/ResearchOrchestrator.js +1327 -0
- package/src/core/SnapshotManager.js +1037 -0
- package/src/core/StealthBrowserManager.js +1795 -0
- package/src/core/WebhookDispatcher.js +745 -0
- package/src/core/analysis/ContentAnalyzer.js +749 -0
- package/src/core/analysis/LinkAnalyzer.js +972 -0
- package/src/core/cache/CacheManager.js +821 -0
- package/src/core/connections/ConnectionPool.js +553 -0
- package/src/core/crawlers/BFSCrawler.js +845 -0
- package/src/core/integrations/PerformanceIntegration.js +377 -0
- package/src/core/llm/AnthropicProvider.js +135 -0
- package/src/core/llm/LLMManager.js +415 -0
- package/src/core/llm/LLMProvider.js +97 -0
- package/src/core/llm/OpenAIProvider.js +127 -0
- package/src/core/processing/BrowserProcessor.js +986 -0
- package/src/core/processing/ContentProcessor.js +505 -0
- package/src/core/processing/PDFProcessor.js +448 -0
- package/src/core/processing/StreamProcessor.js +673 -0
- package/src/core/queue/QueueManager.js +98 -0
- package/src/core/workers/WorkerPool.js +585 -0
- package/src/core/workers/worker.js +743 -0
- package/src/monitoring/healthCheck.js +600 -0
- package/src/monitoring/metrics.js +761 -0
- package/src/optimization/wave3-optimizations.js +932 -0
- package/src/security/security-patches.js +120 -0
- package/src/security/security-tests.js +355 -0
- package/src/security/wave3-security.js +652 -0
- package/src/tools/advanced/BatchScrapeTool.js +1089 -0
- package/src/tools/advanced/ScrapeWithActionsTool.js +669 -0
- package/src/tools/crawl/crawlDeep.js +449 -0
- package/src/tools/crawl/mapSite.js +400 -0
- package/src/tools/extract/analyzeContent.js +624 -0
- package/src/tools/extract/extractContent.js +329 -0
- package/src/tools/extract/processDocument.js +503 -0
- package/src/tools/extract/summarizeContent.js +376 -0
- package/src/tools/llmstxt/generateLLMsTxt.js +570 -0
- package/src/tools/research/deepResearch.js +706 -0
- package/src/tools/search/adapters/duckduckgoSearch.js +398 -0
- package/src/tools/search/adapters/googleSearch.js +236 -0
- package/src/tools/search/adapters/searchProviderFactory.js +96 -0
- package/src/tools/search/queryExpander.js +543 -0
- package/src/tools/search/ranking/ResultDeduplicator.js +676 -0
- package/src/tools/search/ranking/ResultRanker.js +497 -0
- package/src/tools/search/searchWeb.js +482 -0
- package/src/tools/tracking/trackChanges.js +1355 -0
- package/src/utils/CircuitBreaker.js +515 -0
- package/src/utils/ErrorHandlingConfig.js +342 -0
- package/src/utils/HumanBehaviorSimulator.js +569 -0
- package/src/utils/Logger.js +568 -0
- package/src/utils/MemoryMonitor.js +173 -0
- package/src/utils/RetryManager.js +386 -0
- package/src/utils/contentUtils.js +588 -0
- package/src/utils/domainFilter.js +612 -0
- package/src/utils/inputValidation.js +766 -0
- package/src/utils/rateLimiter.js +196 -0
- package/src/utils/robotsChecker.js +91 -0
- package/src/utils/securityMiddleware.js +416 -0
- package/src/utils/sitemapParser.js +678 -0
- package/src/utils/ssrfProtection.js +640 -0
- package/src/utils/urlNormalizer.js +168 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Critical Security Patches for Wave 3 Features
|
|
3
|
+
*
|
|
4
|
+
* This file contains emergency patches for critical vulnerabilities
|
|
5
|
+
* identified in the security audit. Apply these patches immediately
|
|
6
|
+
* before any production deployment.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import Wave3Security from './wave3-security.js';
|
|
10
|
+
const { SSRFProtection, PathSecurity, InputSecurity, CryptoSecurity, BrowserSecurity } = Wave3Security;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* CRITICAL PATCH 1: SSRF Protection for Research Tool
|
|
14
|
+
* Fixes: CVE-001 - Server-Side Request Forgery
|
|
15
|
+
*/
|
|
16
|
+
export function patchResearchOrchestrator(ResearchOrchestrator) {
|
|
17
|
+
const originalConductResearch = ResearchOrchestrator.prototype.conductResearch;
|
|
18
|
+
|
|
19
|
+
ResearchOrchestrator.prototype.conductResearch = async function(topic, options = {}) {
|
|
20
|
+
// Input validation
|
|
21
|
+
if (typeof topic !== 'string' || topic.length < 3 || topic.length > 500) {
|
|
22
|
+
throw new Error('Invalid topic: must be string between 3-500 characters');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Sanitize topic to prevent script injection
|
|
26
|
+
const sanitizedTopic = InputSecurity.sanitizeString(topic);
|
|
27
|
+
|
|
28
|
+
// Validate and limit research parameters
|
|
29
|
+
const secureOptions = {
|
|
30
|
+
...options,
|
|
31
|
+
maxUrls: Math.min(options.maxUrls || 10, 50),
|
|
32
|
+
timeLimit: Math.min(options.timeLimit || 60000, 120000),
|
|
33
|
+
maxDepth: Math.min(Math.max(options.maxDepth || 3, 1), 5),
|
|
34
|
+
concurrency: Math.min(options.concurrency || 3, 5)
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
return originalConductResearch.call(this, sanitizedTopic, secureOptions);
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* CRITICAL PATCH 2: Browser Security Hardening
|
|
43
|
+
* Fixes: CVE-002, CVE-007 - Script Injection and Browser Security
|
|
44
|
+
*/
|
|
45
|
+
export function patchStealthBrowserManager(StealthBrowserManager) {
|
|
46
|
+
// Override dangerous browser args
|
|
47
|
+
const originalLaunchStealthBrowser = StealthBrowserManager.prototype.launchStealthBrowser;
|
|
48
|
+
|
|
49
|
+
StealthBrowserManager.prototype.launchStealthBrowser = async function(config = {}) {
|
|
50
|
+
// Force secure browser configuration
|
|
51
|
+
const secureConfig = {
|
|
52
|
+
...config,
|
|
53
|
+
level: config.level === 'advanced' ? 'medium' : config.level
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// Override with secure browser args
|
|
57
|
+
this.secureArgs = BrowserSecurity.getSecureBrowserArgs();
|
|
58
|
+
|
|
59
|
+
return originalLaunchStealthBrowser.call(this, secureConfig);
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* CRITICAL PATCH 3: Path Traversal Protection
|
|
65
|
+
* Fixes: CVE-003 - Arbitrary File System Access
|
|
66
|
+
*/
|
|
67
|
+
export function patchSnapshotManager(SnapshotManager) {
|
|
68
|
+
// Secure file operations
|
|
69
|
+
const originalWriteSnapshotFile = SnapshotManager.prototype.writeSnapshotFile;
|
|
70
|
+
|
|
71
|
+
SnapshotManager.prototype.writeSnapshotFile = async function(snapshotId, content) {
|
|
72
|
+
// Validate snapshot ID
|
|
73
|
+
const safeSnapshotId = PathSecurity.validateSnapshotId(snapshotId);
|
|
74
|
+
|
|
75
|
+
// Validate content size
|
|
76
|
+
InputSecurity.validateContentSize(content);
|
|
77
|
+
|
|
78
|
+
// Ensure safe file path
|
|
79
|
+
const safePath = PathSecurity.sanitizePath(`${safeSnapshotId}.snap`, this.options.storageDir);
|
|
80
|
+
|
|
81
|
+
return originalWriteSnapshotFile.call(this, safeSnapshotId, content);
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// Override generateSnapshotId to use cryptographically secure generation
|
|
85
|
+
SnapshotManager.prototype.generateSnapshotId = function(url, timestamp) {
|
|
86
|
+
return CryptoSecurity.generateSecureId(16);
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Apply all critical patches
|
|
92
|
+
*/
|
|
93
|
+
export function applyAllSecurityPatches(components) {
|
|
94
|
+
console.log('š Applying Wave 3 security patches...');
|
|
95
|
+
|
|
96
|
+
if (components.ResearchOrchestrator) {
|
|
97
|
+
patchResearchOrchestrator(components.ResearchOrchestrator);
|
|
98
|
+
console.log('ā
ResearchOrchestrator patched');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (components.StealthBrowserManager) {
|
|
102
|
+
patchStealthBrowserManager(components.StealthBrowserManager);
|
|
103
|
+
console.log('ā
StealthBrowserManager patched');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (components.SnapshotManager) {
|
|
107
|
+
patchSnapshotManager(components.SnapshotManager);
|
|
108
|
+
console.log('ā
SnapshotManager patched');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
console.log('š”ļø All Wave 3 security patches applied successfully');
|
|
112
|
+
console.log('ā ļø Remember to run security tests before deployment');
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export default {
|
|
116
|
+
patchResearchOrchestrator,
|
|
117
|
+
patchStealthBrowserManager,
|
|
118
|
+
patchSnapshotManager,
|
|
119
|
+
applyAllSecurityPatches
|
|
120
|
+
};
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wave 3 Security Test Suite
|
|
3
|
+
* Validates security patches and tests for vulnerabilities
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import Wave3Security from './wave3-security.js';
|
|
7
|
+
const { SecurityTesting, SSRFProtection, PathSecurity, InputSecurity } = Wave3Security;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Test SSRF Protection
|
|
11
|
+
*/
|
|
12
|
+
export async function testSSRFProtection() {
|
|
13
|
+
console.log('š§Ŗ Testing SSRF Protection...');
|
|
14
|
+
|
|
15
|
+
const maliciousUrls = [
|
|
16
|
+
'http://localhost:3000/admin',
|
|
17
|
+
'http://127.0.0.1:22',
|
|
18
|
+
'http://169.254.169.254/latest/meta-data/',
|
|
19
|
+
'file:///etc/passwd',
|
|
20
|
+
'ftp://internal.server.com',
|
|
21
|
+
'http://10.0.0.1/secret',
|
|
22
|
+
'https://metadata.google.internal/'
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
const results = SecurityTesting.testSecurityFunction(
|
|
26
|
+
SSRFProtection.validateUrl.bind(SSRFProtection),
|
|
27
|
+
maliciousUrls
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
const blocked = results.filter(r => r.blocked).length;
|
|
31
|
+
const total = results.length;
|
|
32
|
+
|
|
33
|
+
console.log(`ā
SSRF Test: ${blocked}/${total} malicious URLs blocked`);
|
|
34
|
+
|
|
35
|
+
if (blocked !== total) {
|
|
36
|
+
console.error('ā SSRF Protection insufficient!');
|
|
37
|
+
results.filter(r => !r.blocked).forEach(r => {
|
|
38
|
+
console.error(` šØ Not blocked: ${r.payload}`);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return { passed: blocked === total, blocked, total };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Test Path Traversal Protection
|
|
47
|
+
*/
|
|
48
|
+
export function testPathTraversal() {
|
|
49
|
+
console.log('š§Ŗ Testing Path Traversal Protection...');
|
|
50
|
+
|
|
51
|
+
const maliciousPaths = [
|
|
52
|
+
'../../../etc/passwd',
|
|
53
|
+
'..\\..\\..\\windows\\system32\\config\\sam',
|
|
54
|
+
'/etc/shadow',
|
|
55
|
+
'C:\\Windows\\System32\\drivers\\etc\\hosts',
|
|
56
|
+
'....//....//....//etc/passwd',
|
|
57
|
+
'../../../../../../../etc/passwd',
|
|
58
|
+
'..\\..\\..\\..\\..\\..\\/etc/passwd'
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
const results = SecurityTesting.testSecurityFunction(
|
|
62
|
+
PathSecurity.validateSnapshotId.bind(PathSecurity),
|
|
63
|
+
maliciousPaths
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
const blocked = results.filter(r => r.blocked).length;
|
|
67
|
+
const total = results.length;
|
|
68
|
+
|
|
69
|
+
console.log(`ā
Path Traversal Test: ${blocked}/${total} malicious paths blocked`);
|
|
70
|
+
|
|
71
|
+
if (blocked !== total) {
|
|
72
|
+
console.error('ā Path Traversal Protection insufficient!');
|
|
73
|
+
results.filter(r => !r.blocked).forEach(r => {
|
|
74
|
+
console.error(` šØ Not blocked: ${r.payload}`);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return { passed: blocked === total, blocked, total };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Test Input Validation
|
|
83
|
+
*/
|
|
84
|
+
export function testInputValidation() {
|
|
85
|
+
console.log('š§Ŗ Testing Input Validation...');
|
|
86
|
+
|
|
87
|
+
const maliciousInputs = [
|
|
88
|
+
'<script>alert("XSS")</script>',
|
|
89
|
+
'javascript:alert("XSS")',
|
|
90
|
+
'<img src="x" onerror="alert(\'XSS\')">',
|
|
91
|
+
'<svg onload="alert(\'XSS\')"></svg>',
|
|
92
|
+
'${7*7}',
|
|
93
|
+
'#{7*7}',
|
|
94
|
+
'{{7*7}}',
|
|
95
|
+
'<%= 7*7 %>'
|
|
96
|
+
];
|
|
97
|
+
|
|
98
|
+
const results = maliciousInputs.map(input => {
|
|
99
|
+
try {
|
|
100
|
+
const sanitized = InputSecurity.sanitizeHtml(input);
|
|
101
|
+
const isBlocked = !sanitized.includes('<script') &&
|
|
102
|
+
!sanitized.includes('javascript:') &&
|
|
103
|
+
!sanitized.includes('onerror=') &&
|
|
104
|
+
!sanitized.includes('onload=');
|
|
105
|
+
return { input, blocked: isBlocked, sanitized };
|
|
106
|
+
} catch (error) {
|
|
107
|
+
return { input, blocked: true, error: error.message };
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
const blocked = results.filter(r => r.blocked).length;
|
|
112
|
+
const total = results.length;
|
|
113
|
+
|
|
114
|
+
console.log(`ā
Input Validation Test: ${blocked}/${total} malicious inputs neutralized`);
|
|
115
|
+
|
|
116
|
+
return { passed: blocked === total, blocked, total };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Test Resource Limits
|
|
121
|
+
*/
|
|
122
|
+
export function testResourceLimits() {
|
|
123
|
+
console.log('š§Ŗ Testing Resource Limits...');
|
|
124
|
+
|
|
125
|
+
const tests = [
|
|
126
|
+
{
|
|
127
|
+
name: 'Large Content',
|
|
128
|
+
test: () => {
|
|
129
|
+
const largeContent = 'x'.repeat(100 * 1024 * 1024); // 100MB
|
|
130
|
+
try {
|
|
131
|
+
InputSecurity.validateContentSize(largeContent);
|
|
132
|
+
return false; // Should have thrown
|
|
133
|
+
} catch (error) {
|
|
134
|
+
return error.message.includes('Content too large');
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
name: 'Long String',
|
|
140
|
+
test: () => {
|
|
141
|
+
const longString = 'x'.repeat(20000);
|
|
142
|
+
try {
|
|
143
|
+
InputSecurity.sanitizeString(longString, 10000);
|
|
144
|
+
return false; // Should have thrown
|
|
145
|
+
} catch (error) {
|
|
146
|
+
return error.message.includes('String too long');
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
name: 'Large Array',
|
|
152
|
+
test: () => {
|
|
153
|
+
const largeArray = new Array(200).fill('item');
|
|
154
|
+
try {
|
|
155
|
+
InputSecurity.sanitizeArray(largeArray, 100);
|
|
156
|
+
return false; // Should have thrown
|
|
157
|
+
} catch (error) {
|
|
158
|
+
return error.message.includes('Array too long');
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
];
|
|
163
|
+
|
|
164
|
+
let passed = 0;
|
|
165
|
+
tests.forEach(test => {
|
|
166
|
+
if (test.test()) {
|
|
167
|
+
console.log(` ā
${test.name}: PASS`);
|
|
168
|
+
passed++;
|
|
169
|
+
} else {
|
|
170
|
+
console.log(` ā ${test.name}: FAIL`);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
console.log(`ā
Resource Limits Test: ${passed}/${tests.length} tests passed`);
|
|
175
|
+
|
|
176
|
+
return { passed: passed === tests.length, passedCount: passed, total: tests.length };
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Test Cryptographic Functions
|
|
181
|
+
*/
|
|
182
|
+
export function testCryptographicSecurity() {
|
|
183
|
+
console.log('š§Ŗ Testing Cryptographic Security...');
|
|
184
|
+
|
|
185
|
+
const tests = [
|
|
186
|
+
{
|
|
187
|
+
name: 'Secure ID Generation',
|
|
188
|
+
test: () => {
|
|
189
|
+
const id1 = Wave3Security.CryptoSecurity.generateSecureId();
|
|
190
|
+
const id2 = Wave3Security.CryptoSecurity.generateSecureId();
|
|
191
|
+
|
|
192
|
+
// Should be different
|
|
193
|
+
if (id1 === id2) return false;
|
|
194
|
+
|
|
195
|
+
// Should be hex and right length
|
|
196
|
+
if (!/^[a-f0-9]{64}$/.test(id1)) return false;
|
|
197
|
+
if (!/^[a-f0-9]{64}$/.test(id2)) return false;
|
|
198
|
+
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
name: 'Timing Safe Comparison',
|
|
204
|
+
test: () => {
|
|
205
|
+
const hash1 = 'abcd1234';
|
|
206
|
+
const hash2 = 'abcd1234';
|
|
207
|
+
const hash3 = 'efgh5678';
|
|
208
|
+
|
|
209
|
+
// Same hashes should match
|
|
210
|
+
if (!Wave3Security.CryptoSecurity.timingSafeCompare(hash1, hash2)) return false;
|
|
211
|
+
|
|
212
|
+
// Different hashes should not match
|
|
213
|
+
if (Wave3Security.CryptoSecurity.timingSafeCompare(hash1, hash3)) return false;
|
|
214
|
+
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
name: 'Webhook Signature',
|
|
220
|
+
test: () => {
|
|
221
|
+
const payload = JSON.stringify({ test: 'data' });
|
|
222
|
+
const secret = 'test-secret';
|
|
223
|
+
|
|
224
|
+
const signature1 = Wave3Security.CryptoSecurity.generateWebhookSignature(payload, secret);
|
|
225
|
+
const signature2 = Wave3Security.CryptoSecurity.generateWebhookSignature(payload, secret);
|
|
226
|
+
|
|
227
|
+
// Should be consistent
|
|
228
|
+
if (signature1 !== signature2) return false;
|
|
229
|
+
|
|
230
|
+
// Should validate correctly
|
|
231
|
+
if (!Wave3Security.CryptoSecurity.validateWebhookSignature(payload, signature1, secret)) return false;
|
|
232
|
+
|
|
233
|
+
// Should reject wrong signature
|
|
234
|
+
if (Wave3Security.CryptoSecurity.validateWebhookSignature(payload, 'wrong', secret)) return false;
|
|
235
|
+
|
|
236
|
+
return true;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
];
|
|
240
|
+
|
|
241
|
+
let passed = 0;
|
|
242
|
+
tests.forEach(test => {
|
|
243
|
+
if (test.test()) {
|
|
244
|
+
console.log(` ā
${test.name}: PASS`);
|
|
245
|
+
passed++;
|
|
246
|
+
} else {
|
|
247
|
+
console.log(` ā ${test.name}: FAIL`);
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
console.log(`ā
Cryptographic Security Test: ${passed}/${tests.length} tests passed`);
|
|
252
|
+
|
|
253
|
+
return { passed: passed === tests.length, passedCount: passed, total: tests.length };
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Run Full Security Test Suite
|
|
258
|
+
*/
|
|
259
|
+
export async function runFullSecurityTests() {
|
|
260
|
+
console.log('š”ļø Running Wave 3 Security Test Suite...\n');
|
|
261
|
+
|
|
262
|
+
const results = [];
|
|
263
|
+
|
|
264
|
+
// Test SSRF Protection
|
|
265
|
+
results.push(await testSSRFProtection());
|
|
266
|
+
console.log('');
|
|
267
|
+
|
|
268
|
+
// Test Path Traversal Protection
|
|
269
|
+
results.push(testPathTraversal());
|
|
270
|
+
console.log('');
|
|
271
|
+
|
|
272
|
+
// Test Input Validation
|
|
273
|
+
results.push(testInputValidation());
|
|
274
|
+
console.log('');
|
|
275
|
+
|
|
276
|
+
// Test Resource Limits
|
|
277
|
+
results.push(testResourceLimits());
|
|
278
|
+
console.log('');
|
|
279
|
+
|
|
280
|
+
// Test Cryptographic Security
|
|
281
|
+
results.push(testCryptographicSecurity());
|
|
282
|
+
console.log('');
|
|
283
|
+
|
|
284
|
+
// Summary
|
|
285
|
+
const totalPassed = results.filter(r => r.passed).length;
|
|
286
|
+
const totalTests = results.length;
|
|
287
|
+
|
|
288
|
+
console.log('šÆ Security Test Summary:');
|
|
289
|
+
console.log(` Passed: ${totalPassed}/${totalTests} test suites`);
|
|
290
|
+
|
|
291
|
+
if (totalPassed === totalTests) {
|
|
292
|
+
console.log('ā
ALL SECURITY TESTS PASSED! Wave 3 appears secure.');
|
|
293
|
+
} else {
|
|
294
|
+
console.log('ā SECURITY TESTS FAILED! Do not deploy to production.');
|
|
295
|
+
console.log(' Review failed tests and apply additional patches.');
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
return {
|
|
299
|
+
allPassed: totalPassed === totalTests,
|
|
300
|
+
passed: totalPassed,
|
|
301
|
+
total: totalTests,
|
|
302
|
+
results
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Quick Security Health Check
|
|
308
|
+
*/
|
|
309
|
+
export function quickSecurityCheck() {
|
|
310
|
+
console.log('š Quick Security Health Check...');
|
|
311
|
+
|
|
312
|
+
const checks = [
|
|
313
|
+
{
|
|
314
|
+
name: 'SSRF Protection Available',
|
|
315
|
+
check: () => typeof SSRFProtection.validateUrl === 'function'
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
name: 'Path Security Available',
|
|
319
|
+
check: () => typeof PathSecurity.validateSnapshotId === 'function'
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
name: 'Input Sanitization Available',
|
|
323
|
+
check: () => typeof InputSecurity.sanitizeString === 'function'
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
name: 'Crypto Security Available',
|
|
327
|
+
check: () => typeof Wave3Security.CryptoSecurity.generateSecureId === 'function'
|
|
328
|
+
}
|
|
329
|
+
];
|
|
330
|
+
|
|
331
|
+
let passed = 0;
|
|
332
|
+
checks.forEach(check => {
|
|
333
|
+
if (check.check()) {
|
|
334
|
+
console.log(` ā
${check.name}`);
|
|
335
|
+
passed++;
|
|
336
|
+
} else {
|
|
337
|
+
console.log(` ā ${check.name}`);
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
console.log(`\nšÆ Health Check: ${passed}/${checks.length} security functions available`);
|
|
342
|
+
|
|
343
|
+
return passed === checks.length;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// Export test functions
|
|
347
|
+
export default {
|
|
348
|
+
testSSRFProtection,
|
|
349
|
+
testPathTraversal,
|
|
350
|
+
testInputValidation,
|
|
351
|
+
testResourceLimits,
|
|
352
|
+
testCryptographicSecurity,
|
|
353
|
+
runFullSecurityTests,
|
|
354
|
+
quickSecurityCheck
|
|
355
|
+
};
|