Validate and sanitize log file path to prevent security issues.
(self, file_path)
| 591 | return False |
| 592 | |
| 593 | def _validate_log_file_path(self, file_path): |
| 594 | """Validate and sanitize log file path to prevent security issues.""" |
| 595 | if not file_path or not isinstance(file_path, str): |
| 596 | raise ValueError("File path must be a non-empty string") |
| 597 | |
| 598 | sanitized_path = ''.join(char for char in file_path if ord(char) >= 32 and char != '\x7f') |
| 599 | |
| 600 | if not sanitized_path: |
| 601 | raise ValueError("File path contains only invalid characters") |
| 602 | |
| 603 | try: |
| 604 | path_obj = Path(sanitized_path) |
| 605 | |
| 606 | resolved_path = path_obj.resolve() |
| 607 | |
| 608 | resolved_str = str(resolved_path).lower() |
| 609 | forbidden_paths = ['/etc/', '/bin/', '/sbin/', '/usr/bin/', '/usr/sbin/', |
| 610 | '/boot/', '/dev/', '/proc/', '/sys/', '/root/'] |
| 611 | |
| 612 | for forbidden in forbidden_paths: |
| 613 | if resolved_str.startswith(forbidden): |
| 614 | raise ValueError(f"Access to system directory '{forbidden}' is not allowed") |
| 615 | |
| 616 | filename = path_obj.name |
| 617 | if not filename or filename in ('.', '..'): |
| 618 | raise ValueError("Invalid filename") |
| 619 | |
| 620 | suspicious_patterns = ['..', '~/', '$', '`', ';', '|', '&', '<', '>', '*', '?'] |
| 621 | for pattern in suspicious_patterns: |
| 622 | if pattern in filename: |
| 623 | raise ValueError(f"Filename contains suspicious pattern: '{pattern}'") |
| 624 | |
| 625 | valid_extensions = ['.log', '.txt', '.out'] |
| 626 | if not any(filename.lower().endswith(ext) for ext in valid_extensions): |
| 627 | logging.warning(f"Log file '{filename}' does not have a standard log extension") |
| 628 | |
| 629 | return str(resolved_path) |
| 630 | |
| 631 | except (OSError, RuntimeError) as e: |
| 632 | raise ValueError(f"Invalid file path: {e}") |
| 633 | except Exception as e: |
| 634 | raise ValueError(f"Path validation failed: {e}") |
| 635 | |
| 636 | def _looks_like_filename(self, token): |
| 637 | """Check if a token looks like a filename with proper validation.""" |
no test coverage detected