vibecodingmachine-core 2026.2.20-438 → 2026.2.26-1739
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 +240 -0
- package/package.json +10 -2
- package/src/agents/Agent.js +300 -0
- package/src/agents/AgentAdditionService.js +311 -0
- package/src/agents/AgentCheckService.js +690 -0
- package/src/agents/AgentInstallationService.js +140 -0
- package/src/agents/AgentSetupService.js +467 -0
- package/src/agents/AgentStatus.js +183 -0
- package/src/agents/AgentVerificationService.js +634 -0
- package/src/agents/ConfigurationSchemaValidator.js +543 -0
- package/src/agents/EnvironmentConfigurationManager.js +602 -0
- package/src/agents/InstallationErrorHandler.js +372 -0
- package/src/agents/InstallationLog.js +363 -0
- package/src/agents/InstallationMethod.js +510 -0
- package/src/agents/InstallationOrchestrator.js +352 -0
- package/src/agents/InstallationProgressReporter.js +372 -0
- package/src/agents/InstallationRetryManager.js +322 -0
- package/src/agents/InstallationType.js +254 -0
- package/src/agents/OperationTypes.js +310 -0
- package/src/agents/PerformanceMetricsCollector.js +493 -0
- package/src/agents/SecurityValidationService.js +534 -0
- package/src/agents/VerificationTest.js +354 -0
- package/src/agents/VerificationType.js +226 -0
- package/src/agents/WindowsPermissionHandler.js +518 -0
- package/src/agents/config/AgentConfigManager.js +393 -0
- package/src/agents/config/AgentDefaultsRegistry.js +373 -0
- package/src/agents/config/ConfigValidator.js +281 -0
- package/src/agents/discovery/AgentDiscoveryService.js +707 -0
- package/src/agents/logging/AgentLogger.js +511 -0
- package/src/agents/status/AgentStatusManager.js +481 -0
- package/src/agents/storage/FileManager.js +454 -0
- package/src/agents/verification/AgentCommunicationTester.js +474 -0
- package/src/agents/verification/BaseVerifier.js +430 -0
- package/src/agents/verification/CommandVerifier.js +480 -0
- package/src/agents/verification/FileOperationVerifier.js +453 -0
- package/src/agents/verification/ResultAnalyzer.js +707 -0
- package/src/agents/verification/TestRequirementManager.js +495 -0
- package/src/agents/verification/VerificationRunner.js +433 -0
- package/src/agents/windows/BaseWindowsInstaller.js +441 -0
- package/src/agents/windows/ChocolateyInstaller.js +509 -0
- package/src/agents/windows/DirectInstaller.js +443 -0
- package/src/agents/windows/InstallerFactory.js +391 -0
- package/src/agents/windows/NpmInstaller.js +505 -0
- package/src/agents/windows/PowerShellInstaller.js +458 -0
- package/src/agents/windows/WinGetInstaller.js +390 -0
- package/src/analysis/analysis-reporter.js +132 -0
- package/src/analysis/boundary-detector.js +712 -0
- package/src/analysis/categorizer.js +340 -0
- package/src/analysis/codebase-scanner.js +384 -0
- package/src/analysis/line-counter.js +513 -0
- package/src/analysis/priority-calculator.js +679 -0
- package/src/analysis/report/analysis-report.js +250 -0
- package/src/analysis/report/package-analyzer.js +278 -0
- package/src/analysis/report/recommendation-generator.js +382 -0
- package/src/analysis/report/statistics-generator.js +515 -0
- package/src/analysis/reports/analysis-report-model.js +101 -0
- package/src/analysis/reports/recommendation-generator.js +283 -0
- package/src/analysis/reports/report-generators.js +191 -0
- package/src/analysis/reports/statistics-calculator.js +231 -0
- package/src/analysis/reports/trend-analyzer.js +219 -0
- package/src/analysis/strategy-generator.js +814 -0
- package/src/auto-mode/AutoModeBusinessLogic.js +836 -0
- package/src/config/refactoring-config.js +307 -0
- package/src/health-tracking/json-storage.js +38 -2
- package/src/ide-integration/applescript-manager-core.js +233 -0
- package/src/ide-integration/applescript-manager.cjs +357 -28
- package/src/ide-integration/applescript-manager.js +89 -3599
- package/src/ide-integration/cdp-manager.js +306 -0
- package/src/ide-integration/claude-code-cli-manager.cjs +1 -1
- package/src/ide-integration/continuation-handler.js +337 -0
- package/src/ide-integration/ide-status-checker.js +292 -0
- package/src/ide-integration/macos-ide-manager.js +627 -0
- package/src/ide-integration/macos-text-sender.js +528 -0
- package/src/ide-integration/response-reader.js +548 -0
- package/src/ide-integration/windows-automation-manager.js +121 -0
- package/src/ide-integration/windows-ide-manager.js +373 -0
- package/src/index.cjs +25 -3
- package/src/index.js +15 -1
- package/src/llm/direct-llm-manager.cjs +90 -2
- package/src/models/compliance-report.js +538 -0
- package/src/models/file-analysis.js +681 -0
- package/src/models/refactoring-plan.js +770 -0
- package/src/monitoring/alert-system.js +834 -0
- package/src/monitoring/compliance-progress-tracker.js +437 -0
- package/src/monitoring/continuous-scan-notifications.js +661 -0
- package/src/monitoring/continuous-scanner.js +279 -0
- package/src/monitoring/file-monitor/file-analyzer.js +262 -0
- package/src/monitoring/file-monitor/file-monitor.js +237 -0
- package/src/monitoring/file-monitor/watcher.js +194 -0
- package/src/monitoring/file-monitor.js +17 -0
- package/src/monitoring/notification-manager.js +437 -0
- package/src/monitoring/scanner-core.js +368 -0
- package/src/monitoring/scanner-events.js +214 -0
- package/src/monitoring/violation-notification-system.js +515 -0
- package/src/refactoring/boundaries/cohesion-analyzer.js +316 -0
- package/src/refactoring/boundaries/extraction-result.js +285 -0
- package/src/refactoring/boundaries/extraction-strategies.js +392 -0
- package/src/refactoring/boundaries/module-boundary.js +209 -0
- package/src/refactoring/boundary/boundary-detector.js +741 -0
- package/src/refactoring/boundary/boundary-types.js +405 -0
- package/src/refactoring/boundary/extraction-strategies.js +554 -0
- package/src/refactoring/boundary-extraction-result.js +77 -0
- package/src/refactoring/boundary-extraction-strategies.js +330 -0
- package/src/refactoring/boundary-extractor.js +384 -0
- package/src/refactoring/boundary-types.js +46 -0
- package/src/refactoring/circular/circular-dependency.js +88 -0
- package/src/refactoring/circular/cycle-detection.js +147 -0
- package/src/refactoring/circular/dependency-node.js +82 -0
- package/src/refactoring/circular/dependency-result.js +107 -0
- package/src/refactoring/circular/dependency-types.js +58 -0
- package/src/refactoring/circular/graph-builder.js +213 -0
- package/src/refactoring/circular/resolution-strategy.js +72 -0
- package/src/refactoring/circular/strategy-generator.js +229 -0
- package/src/refactoring/circular-dependency-resolver-original.js +809 -0
- package/src/refactoring/circular-dependency-resolver.js +200 -0
- package/src/refactoring/code-mover.js +761 -0
- package/src/refactoring/file-splitter.js +696 -0
- package/src/refactoring/functionality-validator.js +816 -0
- package/src/refactoring/import-manager.js +774 -0
- package/src/refactoring/module-boundary.js +107 -0
- package/src/refactoring/refactoring-executor.js +672 -0
- package/src/refactoring/refactoring-rollback.js +614 -0
- package/src/refactoring/test-validator.js +631 -0
- package/src/requirement-management/default-requirement-manager.js +321 -0
- package/src/requirement-management/requirement-file-parser.js +159 -0
- package/src/requirement-management/requirement-sequencer.js +221 -0
- package/src/rui/commands/AgentCommandParser.js +600 -0
- package/src/rui/commands/AgentCommands.js +487 -0
- package/src/rui/commands/AgentResponseFormatter.js +832 -0
- package/src/scripts/verify-full-compliance.js +269 -0
- package/src/sync/sync-engine-core.js +1 -0
- package/src/sync/sync-engine-remote-handlers.js +135 -0
- package/src/task-generation/automated-task-generator.js +351 -0
- package/src/task-generation/prioritizer.js +287 -0
- package/src/task-generation/task-list-updater.js +215 -0
- package/src/task-generation/task-management-integration.js +480 -0
- package/src/task-generation/task-manager-integration.js +270 -0
- package/src/task-generation/violation-task-generator.js +474 -0
- package/src/task-management/continuous-scan-integration.js +342 -0
- package/src/timeout-management/index.js +12 -3
- package/src/timeout-management/response-time-tracker.js +167 -0
- package/src/timeout-management/timeout-calculator.js +159 -0
- package/src/timeout-management/timeout-config-manager.js +172 -0
- package/src/utils/ast-analyzer.js +417 -0
- package/src/utils/current-requirement-manager.js +276 -0
- package/src/utils/current-requirement-operations.js +472 -0
- package/src/utils/dependency-mapper.js +456 -0
- package/src/utils/download-with-progress.js +4 -2
- package/src/utils/electron-update-checker.js +4 -1
- package/src/utils/file-size-analyzer.js +272 -0
- package/src/utils/import-updater.js +280 -0
- package/src/utils/refactoring-tools.js +512 -0
- package/src/utils/report-generator.js +569 -0
- package/src/utils/reports/report-analysis.js +218 -0
- package/src/utils/reports/report-types.js +55 -0
- package/src/utils/reports/summary-generators.js +102 -0
- package/src/utils/requirement-file-management.js +157 -0
- package/src/utils/requirement-helpers/requirement-file-ops.js +392 -0
- package/src/utils/requirement-helpers/requirement-mover.js +414 -0
- package/src/utils/requirement-helpers/requirement-parser.js +326 -0
- package/src/utils/requirement-helpers/requirement-status.js +320 -0
- package/src/utils/requirement-helpers-new.js +55 -0
- package/src/utils/requirement-helpers-refactored.js +367 -0
- package/src/utils/requirement-helpers.js +291 -1191
- package/src/utils/requirement-movement-operations.js +450 -0
- package/src/utils/requirement-movement.js +312 -0
- package/src/utils/requirement-parsing-helpers.js +56 -0
- package/src/utils/requirement-statistics.js +200 -0
- package/src/utils/requirement-text-utils.js +58 -0
- package/src/utils/rollback/rollback-handlers.js +125 -0
- package/src/utils/rollback/rollback-operation.js +63 -0
- package/src/utils/rollback/rollback-recorder.js +166 -0
- package/src/utils/rollback/rollback-state-manager.js +175 -0
- package/src/utils/rollback/rollback-types.js +33 -0
- package/src/utils/rollback/rollback-utils.js +110 -0
- package/src/utils/rollback-manager-original.js +569 -0
- package/src/utils/rollback-manager.js +202 -0
- package/src/utils/smoke-test-cli.js +362 -0
- package/src/utils/smoke-test-gui.js +351 -0
- package/src/utils/smoke-test-orchestrator.js +321 -0
- package/src/utils/smoke-test-runner.js +60 -0
- package/src/utils/smoke-test-web.js +347 -0
- package/src/utils/specification-helpers.js +39 -13
- package/src/utils/specification-migration.js +97 -0
- package/src/utils/test-runner.js +579 -0
- package/src/utils/validation-framework.js +518 -0
- package/src/validation/compliance-analyzer.js +197 -0
- package/src/validation/compliance-report-generator.js +343 -0
- package/src/validation/compliance-reporter.js +711 -0
- package/src/validation/compliance-rules.js +127 -0
- package/src/validation/constitution-validator-new.js +196 -0
- package/src/validation/constitution-validator.js +17 -0
- package/src/validation/file-validators.js +170 -0
- package/src/validation/line-limit/file-analyzer.js +201 -0
- package/src/validation/line-limit/line-limit-validator.js +208 -0
- package/src/validation/line-limit/validation-result.js +144 -0
- package/src/validation/line-limit-core.js +225 -0
- package/src/validation/line-limit-reporter.js +134 -0
- package/src/validation/line-limit-result.js +125 -0
- package/src/validation/line-limit-validator.js +41 -0
- package/src/validation/metrics-calculator.js +660 -0
- package/src/sync/sync-engine-backup.js +0 -559
|
@@ -0,0 +1,534 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Security Validation Service
|
|
3
|
+
*
|
|
4
|
+
* Provides security validation for downloaded packages and files.
|
|
5
|
+
* Follows constitutional requirements: <555 lines, test-first approach.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const crypto = require('crypto');
|
|
9
|
+
const fs = require('fs').promises;
|
|
10
|
+
const path = require('path');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Security Validation Service class
|
|
14
|
+
*/
|
|
15
|
+
class SecurityValidationService {
|
|
16
|
+
/**
|
|
17
|
+
* Create security validation service instance
|
|
18
|
+
* @param {Object} options - Service options
|
|
19
|
+
*/
|
|
20
|
+
constructor(options = {}) {
|
|
21
|
+
this.logger = options.logger || null;
|
|
22
|
+
this.strictMode = options.strictMode !== false; // Default to strict
|
|
23
|
+
this.maxFileSize = options.maxFileSize || 100 * 1024 * 1024; // 100MB
|
|
24
|
+
this.allowedExtensions = options.allowedExtensions || [
|
|
25
|
+
'.exe', '.msi', '.zip', '.tar', '.gz', '.js', '.json'
|
|
26
|
+
];
|
|
27
|
+
this.blockedPatterns = options.blockedPatterns || [
|
|
28
|
+
/\.exe$/i, // Executables (require special handling)
|
|
29
|
+
/\.bat$/i, // Batch files
|
|
30
|
+
/\.cmd$/i, // Command files
|
|
31
|
+
/\.scr$/i, // Screensavers (often malicious)
|
|
32
|
+
/\.vbs$/i, // VBScript files
|
|
33
|
+
/\.ps1$/i // PowerShell scripts (require validation)
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
// Known malicious signatures (simplified)
|
|
37
|
+
this.maliciousSignatures = [
|
|
38
|
+
'eval(',
|
|
39
|
+
'document.write(',
|
|
40
|
+
'setTimeout(',
|
|
41
|
+
'setInterval(',
|
|
42
|
+
'Function(',
|
|
43
|
+
'require(\'child_process\')',
|
|
44
|
+
'require(\'fs\')',
|
|
45
|
+
'spawn(',
|
|
46
|
+
'exec('
|
|
47
|
+
];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Validate downloaded file
|
|
52
|
+
* @param {string} filePath - Path to downloaded file
|
|
53
|
+
* @param {Object} context - Validation context
|
|
54
|
+
* @returns {Promise<Object>} - Validation result
|
|
55
|
+
*/
|
|
56
|
+
async validateFile(filePath, context = {}) {
|
|
57
|
+
const result = {
|
|
58
|
+
valid: true,
|
|
59
|
+
warnings: [],
|
|
60
|
+
errors: [],
|
|
61
|
+
security: {
|
|
62
|
+
fileSize: 0,
|
|
63
|
+
fileHash: null,
|
|
64
|
+
fileExtension: null,
|
|
65
|
+
maliciousContent: false,
|
|
66
|
+
suspiciousPatterns: [],
|
|
67
|
+
permissions: null
|
|
68
|
+
},
|
|
69
|
+
metadata: {
|
|
70
|
+
fileName: path.basename(filePath),
|
|
71
|
+
filePath,
|
|
72
|
+
validationTime: new Date().toISOString(),
|
|
73
|
+
context
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
// Check file exists
|
|
79
|
+
const stats = await fs.stat(filePath);
|
|
80
|
+
if (!stats.isFile()) {
|
|
81
|
+
result.valid = false;
|
|
82
|
+
result.errors.push('File does not exist or is not a regular file');
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// File size validation
|
|
87
|
+
result.security.fileSize = stats.size;
|
|
88
|
+
if (stats.size > this.maxFileSize) {
|
|
89
|
+
result.valid = false;
|
|
90
|
+
result.errors.push(`File size (${stats.size} bytes) exceeds maximum allowed size (${this.maxFileSize} bytes)`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// File extension validation
|
|
94
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
95
|
+
result.security.fileExtension = ext;
|
|
96
|
+
|
|
97
|
+
if (!this.allowedExtensions.includes(ext)) {
|
|
98
|
+
result.warnings.push(`File extension '${ext}' is not in the allowed list`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Check for blocked patterns
|
|
102
|
+
for (const pattern of this.blockedPatterns) {
|
|
103
|
+
if (pattern.test(filePath)) {
|
|
104
|
+
result.warnings.push(`File name matches blocked pattern: ${pattern}`);
|
|
105
|
+
result.security.suspiciousPatterns.push(pattern.toString());
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Read file for content validation
|
|
110
|
+
const content = await fs.readFile(filePath);
|
|
111
|
+
|
|
112
|
+
// Calculate file hash
|
|
113
|
+
result.security.fileHash = this.calculateHash(content);
|
|
114
|
+
|
|
115
|
+
// Content validation
|
|
116
|
+
await this.validateContent(content, result);
|
|
117
|
+
|
|
118
|
+
// Permission validation (Windows specific)
|
|
119
|
+
if (process.platform === 'win32') {
|
|
120
|
+
await this.validateFilePermissions(filePath, result);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Log validation result
|
|
124
|
+
if (this.logger) {
|
|
125
|
+
this.logger.info('File security validation completed', {
|
|
126
|
+
filePath,
|
|
127
|
+
valid: result.valid,
|
|
128
|
+
errorsCount: result.errors.length,
|
|
129
|
+
warningsCount: result.warnings.length,
|
|
130
|
+
fileSize: result.security.fileSize,
|
|
131
|
+
fileHash: result.security.fileHash
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
} catch (error) {
|
|
136
|
+
result.valid = false;
|
|
137
|
+
result.errors.push(`Validation error: ${error.message}`);
|
|
138
|
+
|
|
139
|
+
if (this.logger) {
|
|
140
|
+
this.logger.error('File security validation failed', {
|
|
141
|
+
filePath,
|
|
142
|
+
error: error.message
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return result;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Validate file content
|
|
152
|
+
* @param {Buffer} content - File content
|
|
153
|
+
* @param {Object} result - Validation result to update
|
|
154
|
+
*/
|
|
155
|
+
async validateContent(content, result) {
|
|
156
|
+
const contentString = content.toString('utf8', 0, Math.min(content.length, 1024 * 1024)); // First 1MB
|
|
157
|
+
|
|
158
|
+
// Check for malicious signatures
|
|
159
|
+
for (const signature of this.maliciousSignatures) {
|
|
160
|
+
if (contentString.includes(signature)) {
|
|
161
|
+
result.valid = false;
|
|
162
|
+
result.errors.push(`Suspicious content detected: ${signature}`);
|
|
163
|
+
result.security.maliciousContent = true;
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Check for suspicious patterns
|
|
169
|
+
const suspiciousPatterns = [
|
|
170
|
+
/base64/i,
|
|
171
|
+
/atob/i,
|
|
172
|
+
/btoa/i,
|
|
173
|
+
/\\x[0-9a-f]{2}/gi,
|
|
174
|
+
/%[0-9a-f]{2}/gi,
|
|
175
|
+
/document\.cookie/i,
|
|
176
|
+
/localStorage/i,
|
|
177
|
+
/sessionStorage/i
|
|
178
|
+
];
|
|
179
|
+
|
|
180
|
+
for (const pattern of suspiciousPatterns) {
|
|
181
|
+
if (pattern.test(contentString)) {
|
|
182
|
+
result.warnings.push(`Suspicious pattern detected: ${pattern}`);
|
|
183
|
+
result.security.suspiciousPatterns.push(pattern.toString());
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Check for executable headers
|
|
188
|
+
if (content.length >= 2) {
|
|
189
|
+
const header = content.readUInt16LE(0);
|
|
190
|
+
const executableHeaders = [
|
|
191
|
+
0x5A4D, // MZ (PE executable)
|
|
192
|
+
0x4D5A, // ZM (PE executable, little-endian)
|
|
193
|
+
0x7F45, // ELF executable
|
|
194
|
+
0xCAFEBABE, // Java class file
|
|
195
|
+
0x89504E47 // PNG file (should not be executable)
|
|
196
|
+
];
|
|
197
|
+
|
|
198
|
+
if (executableHeaders.includes(header)) {
|
|
199
|
+
result.warnings.push('File appears to be an executable binary');
|
|
200
|
+
result.security.suspiciousPatterns.push('Executable header detected');
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Validate file permissions (Windows)
|
|
207
|
+
* @param {string} filePath - File path
|
|
208
|
+
* @param {Object} result - Validation result to update
|
|
209
|
+
*/
|
|
210
|
+
async validateFilePermissions(filePath, result) {
|
|
211
|
+
try {
|
|
212
|
+
// Check if file is writable (potential security risk)
|
|
213
|
+
await fs.access(filePath, fs.constants.W_OK);
|
|
214
|
+
|
|
215
|
+
// Check file attributes (Windows specific)
|
|
216
|
+
const stats = await fs.stat(filePath);
|
|
217
|
+
result.security.permissions = {
|
|
218
|
+
readable: true,
|
|
219
|
+
writable: true,
|
|
220
|
+
executable: false
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
// Warn about executable files
|
|
224
|
+
if (stats.mode & 0o111) {
|
|
225
|
+
result.warnings.push('File has executable permissions set');
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
} catch (error) {
|
|
229
|
+
result.warnings.push(`Could not validate file permissions: ${error.message}`);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Validate package signature
|
|
235
|
+
* @param {string} filePath - Path to package file
|
|
236
|
+
* @param {Object} expectedSignature - Expected signature
|
|
237
|
+
* @returns {Promise<Object>} - Signature validation result
|
|
238
|
+
*/
|
|
239
|
+
async validatePackageSignature(filePath, expectedSignature = null) {
|
|
240
|
+
const result = {
|
|
241
|
+
valid: true,
|
|
242
|
+
errors: [],
|
|
243
|
+
warnings: [],
|
|
244
|
+
signature: null,
|
|
245
|
+
verified: false
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
try {
|
|
249
|
+
const content = await fs.readFile(filePath);
|
|
250
|
+
const actualHash = this.calculateHash(content);
|
|
251
|
+
result.signature = actualHash;
|
|
252
|
+
|
|
253
|
+
if (expectedSignature) {
|
|
254
|
+
if (actualHash === expectedSignature.hash) {
|
|
255
|
+
result.verified = true;
|
|
256
|
+
} else {
|
|
257
|
+
result.valid = false;
|
|
258
|
+
result.errors.push(`Package signature mismatch. Expected: ${expectedSignature.hash}, Actual: ${actualHash}`);
|
|
259
|
+
}
|
|
260
|
+
} else {
|
|
261
|
+
result.warnings.push('No expected signature provided for verification');
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (this.logger) {
|
|
265
|
+
this.logger.info('Package signature validation completed', {
|
|
266
|
+
filePath,
|
|
267
|
+
signature: actualHash,
|
|
268
|
+
verified: result.verified
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
} catch (error) {
|
|
273
|
+
result.valid = false;
|
|
274
|
+
result.errors.push(`Signature validation error: ${error.message}`);
|
|
275
|
+
|
|
276
|
+
if (this.logger) {
|
|
277
|
+
this.logger.error('Package signature validation failed', {
|
|
278
|
+
filePath,
|
|
279
|
+
error: error.message
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
return result;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Validate download source
|
|
289
|
+
* @param {string} url - Download URL
|
|
290
|
+
* @returns {Object} - Source validation result
|
|
291
|
+
*/
|
|
292
|
+
validateDownloadSource(url) {
|
|
293
|
+
const result = {
|
|
294
|
+
valid: true,
|
|
295
|
+
warnings: [],
|
|
296
|
+
errors: [],
|
|
297
|
+
trustLevel: 'UNKNOWN'
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
try {
|
|
301
|
+
const urlObj = new URL(url);
|
|
302
|
+
|
|
303
|
+
// Check protocol
|
|
304
|
+
if (!['https:', 'http:'].includes(urlObj.protocol)) {
|
|
305
|
+
result.valid = false;
|
|
306
|
+
result.errors.push(`Unsupported protocol: ${urlObj.protocol}`);
|
|
307
|
+
return result;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Check for HTTPS
|
|
311
|
+
if (urlObj.protocol !== 'https:') {
|
|
312
|
+
result.warnings.push('Download uses HTTP instead of HTTPS');
|
|
313
|
+
result.trustLevel = 'LOW';
|
|
314
|
+
} else {
|
|
315
|
+
result.trustLevel = 'MEDIUM';
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// Check domain reputation (simplified)
|
|
319
|
+
const trustedDomains = [
|
|
320
|
+
'github.com',
|
|
321
|
+
'npmjs.org',
|
|
322
|
+
'microsoft.com',
|
|
323
|
+
'anthropic.com',
|
|
324
|
+
'google.com',
|
|
325
|
+
'winget.run',
|
|
326
|
+
'chocolatey.org'
|
|
327
|
+
];
|
|
328
|
+
|
|
329
|
+
const domain = urlObj.hostname.toLowerCase();
|
|
330
|
+
if (trustedDomains.some(trusted => domain.includes(trusted))) {
|
|
331
|
+
result.trustLevel = 'HIGH';
|
|
332
|
+
} else {
|
|
333
|
+
result.warnings.push(`Download from untrusted domain: ${domain}`);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// Check for suspicious URL patterns
|
|
337
|
+
const suspiciousPatterns = [
|
|
338
|
+
/bit\.ly/i,
|
|
339
|
+
/tinyurl\.com/i,
|
|
340
|
+
/shortened/i,
|
|
341
|
+
/redirect/i
|
|
342
|
+
];
|
|
343
|
+
|
|
344
|
+
for (const pattern of suspiciousPatterns) {
|
|
345
|
+
if (pattern.test(url)) {
|
|
346
|
+
result.warnings.push(`Suspicious URL pattern detected: ${pattern}`);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
} catch (error) {
|
|
351
|
+
result.valid = false;
|
|
352
|
+
result.errors.push(`URL validation error: ${error.message}`);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return result;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Calculate file hash
|
|
360
|
+
* @param {Buffer} content - File content
|
|
361
|
+
* @returns {string} - SHA-256 hash
|
|
362
|
+
*/
|
|
363
|
+
calculateHash(content) {
|
|
364
|
+
return crypto.createHash('sha256').update(content).digest('hex');
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Validate multiple files
|
|
369
|
+
* @param {Array<string>} filePaths - Array of file paths
|
|
370
|
+
* @param {Object} context - Validation context
|
|
371
|
+
* @returns {Promise<Object>} - Batch validation result
|
|
372
|
+
*/
|
|
373
|
+
async validateFiles(filePaths, context = {}) {
|
|
374
|
+
const results = {
|
|
375
|
+
valid: true,
|
|
376
|
+
files: [],
|
|
377
|
+
summary: {
|
|
378
|
+
total: filePaths.length,
|
|
379
|
+
valid: 0,
|
|
380
|
+
invalid: 0,
|
|
381
|
+
warnings: 0,
|
|
382
|
+
errors: 0
|
|
383
|
+
}
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
for (const filePath of filePaths) {
|
|
387
|
+
const fileResult = await this.validateFile(filePath, context);
|
|
388
|
+
results.files.push(fileResult);
|
|
389
|
+
|
|
390
|
+
if (fileResult.valid) {
|
|
391
|
+
results.summary.valid++;
|
|
392
|
+
} else {
|
|
393
|
+
results.summary.invalid++;
|
|
394
|
+
results.valid = false;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
results.summary.warnings += fileResult.warnings.length;
|
|
398
|
+
results.summary.errors += fileResult.errors.length;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
if (this.logger) {
|
|
402
|
+
this.logger.info('Batch file validation completed', {
|
|
403
|
+
totalFiles: results.summary.total,
|
|
404
|
+
validFiles: results.summary.valid,
|
|
405
|
+
invalidFiles: results.summary.invalid,
|
|
406
|
+
totalWarnings: results.summary.warnings,
|
|
407
|
+
totalErrors: results.summary.errors
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
return results;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Create security report
|
|
416
|
+
* @param {Array<Object>} validationResults - Array of validation results
|
|
417
|
+
* @returns {Object} - Security report
|
|
418
|
+
*/
|
|
419
|
+
createSecurityReport(validationResults) {
|
|
420
|
+
const report = {
|
|
421
|
+
timestamp: new Date().toISOString(),
|
|
422
|
+
summary: {
|
|
423
|
+
totalFiles: validationResults.length,
|
|
424
|
+
validFiles: 0,
|
|
425
|
+
invalidFiles: 0,
|
|
426
|
+
totalWarnings: 0,
|
|
427
|
+
totalErrors: 0,
|
|
428
|
+
highRiskFiles: 0,
|
|
429
|
+
mediumRiskFiles: 0,
|
|
430
|
+
lowRiskFiles: 0
|
|
431
|
+
},
|
|
432
|
+
details: validationResults,
|
|
433
|
+
recommendations: []
|
|
434
|
+
};
|
|
435
|
+
|
|
436
|
+
for (const result of validationResults) {
|
|
437
|
+
if (result.valid) {
|
|
438
|
+
report.summary.validFiles++;
|
|
439
|
+
} else {
|
|
440
|
+
report.summary.invalidFiles++;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
report.summary.totalWarnings += result.warnings.length;
|
|
444
|
+
report.summary.totalErrors += result.errors.length;
|
|
445
|
+
|
|
446
|
+
// Assess risk level
|
|
447
|
+
const riskLevel = this.assessRiskLevel(result);
|
|
448
|
+
if (riskLevel === 'HIGH') {
|
|
449
|
+
report.summary.highRiskFiles++;
|
|
450
|
+
} else if (riskLevel === 'MEDIUM') {
|
|
451
|
+
report.summary.mediumRiskFiles++;
|
|
452
|
+
} else {
|
|
453
|
+
report.summary.lowRiskFiles++;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
// Generate recommendations
|
|
458
|
+
report.recommendations = this.generateRecommendations(report);
|
|
459
|
+
|
|
460
|
+
return report;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Assess risk level for validation result
|
|
465
|
+
* @param {Object} result - Validation result
|
|
466
|
+
* @returns {string} - Risk level
|
|
467
|
+
*/
|
|
468
|
+
assessRiskLevel(result) {
|
|
469
|
+
if (result.security.maliciousContent) {
|
|
470
|
+
return 'HIGH';
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
if (result.errors.length > 0) {
|
|
474
|
+
return 'HIGH';
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
if (result.warnings.length > 3) {
|
|
478
|
+
return 'MEDIUM';
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
if (result.warnings.length > 0) {
|
|
482
|
+
return 'LOW';
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
return 'LOW';
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Generate security recommendations
|
|
490
|
+
* @param {Object} report - Security report
|
|
491
|
+
* @returns {Array<string>} - Recommendations
|
|
492
|
+
*/
|
|
493
|
+
generateRecommendations(report) {
|
|
494
|
+
const recommendations = [];
|
|
495
|
+
|
|
496
|
+
if (report.summary.highRiskFiles > 0) {
|
|
497
|
+
recommendations.push('Review and remove high-risk files immediately');
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
if (report.summary.mediumRiskFiles > 0) {
|
|
501
|
+
recommendations.push('Investigate medium-risk files before proceeding');
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
if (report.summary.totalWarnings > report.summary.totalFiles) {
|
|
505
|
+
recommendations.push('Consider reviewing download sources and security policies');
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
if (report.summary.invalidFiles > 0) {
|
|
509
|
+
recommendations.push('Fix validation errors before using files');
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
recommendations.push('Regularly update security validation rules');
|
|
513
|
+
recommendations.push('Use HTTPS downloads from trusted sources');
|
|
514
|
+
recommendations.push('Verify package signatures when available');
|
|
515
|
+
|
|
516
|
+
return recommendations;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* Get current configuration
|
|
521
|
+
* @returns {Object} - Current configuration
|
|
522
|
+
*/
|
|
523
|
+
getConfiguration() {
|
|
524
|
+
return {
|
|
525
|
+
strictMode: this.strictMode,
|
|
526
|
+
maxFileSize: this.maxFileSize,
|
|
527
|
+
allowedExtensions: this.allowedExtensions,
|
|
528
|
+
blockedPatterns: this.blockedPatterns.length,
|
|
529
|
+
maliciousSignatures: this.maliciousSignatures.length
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
module.exports = SecurityValidationService;
|