Source code for imednet.utils.security

"""
Security utilities.
"""

import re
from typing import Any

from imednet.errors import ClientError, PathTraversalValidationError

_WINDOWS_ABSOLUTE_PATH_RE = re.compile(r"^[A-Za-z]:[/\\]")


[docs]def sanitize_csv_formula(value: Any) -> Any: """ Sanitize a value to prevent CSV/Excel Formula Injection. Prefixes strings starting with =, +, -, or @ (even after whitespace) with a single quote. Lists and tuples are recursively sanitized. """ if isinstance(value, str) and value.lstrip().startswith(("=", "+", "-", "@")): return f"'{value}" elif isinstance(value, list): return [sanitize_csv_formula(v) for v in value] elif isinstance(value, tuple): return tuple(sanitize_csv_formula(v) for v in value) return value
[docs]def validate_header_value(value: str) -> None: """ Validate that a header value does not contain newline characters. Args: value: The header value to validate. Raises: ClientError: If the value contains newline characters. """ if "\n" in value or "\r" in value: raise ClientError(f"Header value must not contain newlines: {value!r}")
[docs]def validate_partition_key(key: str) -> None: """Reject partition keys that could escape or reshape the target directory.""" if "\x00" in key: raise PathTraversalValidationError(f"Partition key must not contain null bytes: {key!r}") if key.startswith(("/", "\\")) or _WINDOWS_ABSOLUTE_PATH_RE.match(key): raise PathTraversalValidationError( f"Partition key must not use absolute path modifiers: {key!r}" ) if "../" in key or "..\\" in key or key == "..": raise PathTraversalValidationError( f"Partition key must not contain parent-directory traversal: {key!r}" ) if "/" in key or "\\" in key: raise PathTraversalValidationError( f"Partition key must not contain path separators: {key!r}" )