* Validate file path for security - prevents null byte injection and path traversal attacks. * * External URLs (`http`/`https`) are fetched over HTTP — with SSRF protection applied * downstream in `fetchExternalUrlToWorkspace` (DNS resolution + private/reserved IP blocking) * — and are never res
(filePath: string)
| 435 | * since that prefix is expected. |
| 436 | */ |
| 437 | function validateFilePath(filePath: string): { isValid: boolean; error?: string } { |
| 438 | if (filePath.includes('\0')) { |
| 439 | return { isValid: false, error: 'Invalid path: null byte detected' } |
| 440 | } |
| 441 | |
| 442 | if ( |
| 443 | (filePath.startsWith('http://') || filePath.startsWith('https://')) && |
| 444 | !isInternalFileUrl(filePath) |
| 445 | ) { |
| 446 | return { isValid: true } |
| 447 | } |
| 448 | |
| 449 | if (filePath.includes('..')) { |
| 450 | return { isValid: false, error: 'Access denied: path traversal detected' } |
| 451 | } |
| 452 | |
| 453 | if (filePath.includes('~')) { |
| 454 | return { isValid: false, error: 'Invalid path: tilde character not allowed' } |
| 455 | } |
| 456 | |
| 457 | if (filePath.startsWith('/') && !isInternalFileUrl(filePath)) { |
| 458 | return { isValid: false, error: 'Path outside allowed directory' } |
| 459 | } |
| 460 | |
| 461 | if (/^[A-Za-z]:\\/.test(filePath)) { |
| 462 | return { isValid: false, error: 'Path outside allowed directory' } |
| 463 | } |
| 464 | |
| 465 | return { isValid: true } |
| 466 | } |
| 467 | |
| 468 | /** |
| 469 | * Handle external URL. |
no test coverage detected