TASK-016: Validate delete_log_path query parameter with allowlist

- Extract path validation logic into shared helper function in
  backend/app/utils/path_utils.py (validate_log_path)
- Refactor AddLogPathRequest to use the helper function
- Apply the same validation to DELETE /api/config/jails/{name}/logpath
  endpoint by validating the log_path query parameter
- Return HTTP 422 with descriptive error if validation fails
- Add comprehensive unit tests for path validation
- Update Backend-Development.md with usage examples

This prevents path-traversal attacks on the delete_log_path endpoint
by ensuring all log paths are within allowlisted directories.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-04-26 14:04:21 +02:00
parent d66493f135
commit 94bdabe622
7 changed files with 236 additions and 67 deletions

View File

@@ -0,0 +1,40 @@
"""Path validation utilities."""
from pathlib import Path
from app.config import get_settings
def validate_log_path(log_path: str) -> str:
"""Validate that a log path is within allowed directories.
Resolves the path to its canonical form (resolving symlinks) and checks
that it is relative to one of the allowed log directories from settings.
Args:
log_path: The log path to validate.
Returns:
The validated log path (unchanged).
Raises:
ValueError: If the path is outside allowed log directories.
"""
settings = get_settings()
try:
resolved_path = Path(log_path).resolve()
except (OSError, RuntimeError) as e:
raise ValueError(f"Cannot resolve path {log_path!r}: {e}") from e
for allowed_dir in settings.allowed_log_dirs:
allowed_path = Path(allowed_dir).resolve()
try:
resolved_path.relative_to(allowed_path)
return log_path
except ValueError:
continue
allowed_dirs_str = ", ".join(settings.allowed_log_dirs)
raise ValueError(
f"Log path {log_path!r} is outside allowed directories: {allowed_dirs_str}"
)