( value: string | null | undefined, paramName = 'ID' )
| 500 | * ``` |
| 501 | */ |
| 502 | export function validateMicrosoftGraphId( |
| 503 | value: string | null | undefined, |
| 504 | paramName = 'ID' |
| 505 | ): ValidationResult { |
| 506 | if (value === null || value === undefined || value === '') { |
| 507 | return { |
| 508 | isValid: false, |
| 509 | error: `${paramName} is required`, |
| 510 | } |
| 511 | } |
| 512 | |
| 513 | const pathTraversalPatterns = [ |
| 514 | '../', |
| 515 | '..\\', |
| 516 | '%2e%2e%2f', |
| 517 | '%2e%2e/', |
| 518 | '..%2f', |
| 519 | '%2e%2e%5c', |
| 520 | '%2e%2e\\', |
| 521 | '..%5c', |
| 522 | '%252e%252e%252f', |
| 523 | ] |
| 524 | |
| 525 | const lowerValue = value.toLowerCase() |
| 526 | for (const pattern of pathTraversalPatterns) { |
| 527 | if (lowerValue.includes(pattern)) { |
| 528 | logger.warn('Path traversal attempt in Microsoft Graph ID', { |
| 529 | paramName, |
| 530 | value: value.substring(0, 100), |
| 531 | }) |
| 532 | return { |
| 533 | isValid: false, |
| 534 | error: `${paramName} contains invalid path traversal sequence`, |
| 535 | } |
| 536 | } |
| 537 | } |
| 538 | |
| 539 | if (/[\x00-\x1f\x7f]/.test(value) || value.includes('%00')) { |
| 540 | logger.warn('Control characters in Microsoft Graph ID', { paramName }) |
| 541 | return { |
| 542 | isValid: false, |
| 543 | error: `${paramName} contains invalid control characters`, |
| 544 | } |
| 545 | } |
| 546 | |
| 547 | if (value.includes('\n') || value.includes('\r')) { |
| 548 | return { |
| 549 | isValid: false, |
| 550 | error: `${paramName} contains invalid newline characters`, |
| 551 | } |
| 552 | } |
| 553 | |
| 554 | return { isValid: true, sanitized: value } |
| 555 | } |
| 556 | |
| 557 | /** |
| 558 | * Validates SharePoint site IDs used in Microsoft Graph API. |
no test coverage detected