T05 · Unauthorized Access and Privilege Escalation
- Location
plugin-evidence-vault/src/tools/index.ts:115- Finding
Caller-Controlled Source Path Enables Arbitrary Local File Ingestion and S3 Upload
- Content
View full analysis
{ this.validateChannel(params.channel); try { const stats = await fs.stat(params.filePath); const mimeType = this.detectMimeType(params.filePath, params.filename); const input: IngestInput = { filePath: params.filePath, filename: params.filename, mimeType, size: stats.size, caseId: params.caseId, sourceContext: { channel: params.channel ?? 'unknown', sender: params.sender ?? 'unknown', messageId: params.messageId, sessionId: params.sessionId, }, retentionPolicy: params.retentionDays ? { retentionDays: params.retentionDays, legalHold: false, deleteAfter: new Date( Date.now() + params.retentionDays * 24 * 60 * 60 * 1000 ).toISOString(), } : undefined, metadata: params.metadata, }; return this.driver.ingest(input); } catch (error) { ``` ```ts // plugin-evidence-vault/src/drivers/filesystem.ts:193-202 const sha256 = await hashFile(input.filePath); await fs.copyFile(input.filePath, targetPath); try { await fs.chmod(targetPath, 0o444); } catch { // Ignore chmod errors on Windows } ``` ```ts // plugin-evidence-vault/src/drivers/s3.ts:228-244 const sha256 = await hashFile(input.filePath); const fileContent = await fs.readFile(input.filePath); const s3Key = this.getS3Key(sanitizedCaseId, `originals/${storedFilename}`); await this.s3Client.send( new PutObjectCommand({ Bucket: this.s3Config.bucket, ...[truncated 2485 chars]- Remediation
View remediation
