TASK-015: Add validation for GlobalConfigUpdate.log_target and log_level

- Add LogLevel Literal type: CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG
- Add log_target validation to accept special values (STDOUT, STDERR, SYSLOG)
  or validated file paths within allowed directories
- Update GlobalConfigResponse to use LogLevel type
- Add field_validator for log_target in both GlobalConfigUpdate and
  GlobalConfigResponse following the same pattern as AddLogPathRequest
- Add @autouse fixture to test_config_service.py to mock get_settings
- Update existing tests to use uppercase log level values
- Add 12 comprehensive tests for new validation in test_models.py
- Update Features.md to document valid log_target and log_level values
- Add section to Backend-Development.md documenting Literal types and
  field_validator patterns with examples

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-04-26 13:57:22 +02:00
parent b9e046bd66
commit d66493f135
6 changed files with 306 additions and 45 deletions

View File

@@ -1,38 +1,3 @@
## TASK-014 — `add_log_path` passes arbitrary paths to fail2ban — no allowlist
**Severity:** High
### Where found
`backend/app/services/config_service.py``add_log_path()`. `backend/app/models/config.py``AddLogPathRequest.log_path: str`.
### Why this is needed
An authenticated user can instruct fail2ban to monitor any file path on the system (e.g., `log_path: "/etc/shadow"`). fail2ban runs as root and opens the file for reading. Even if fail2ban cannot meaningfully parse it, repeated log monitoring of sensitive files can leak their contents via fail2ban's own logging, and the feature represents an unintended read primitive into arbitrary root-readable files.
### Goal
Restrict monitored log paths to a configurable set of safe directories.
### What to do
1. Add a `@field_validator("log_path")` to `AddLogPathRequest` that:
- Calls `Path(log_path).resolve()` to canonicalize.
- Checks `resolved.is_relative_to(Path("/var/log"))` or any path in `settings.allowed_log_dirs` (a new configurable list).
- Raises `ValueError` if the path is outside allowed prefixes.
2. Add `BANGUI_ALLOWED_LOG_DIRS` to `Settings` as `list[str]` defaulting to `["/var/log", "/config/log"]`.
3. Note: use `is_relative_to()`, not `startswith()` — the latter is bypassable with `/var/log_evil`.
### Possible traps and issues
- The validator runs on the Pydantic model before the service is called — the resolved path check happens at request time, not at the OS level. The allowed list must match the actual Docker volume mount paths.
- Custom log file locations (e.g., `/home/app/logs`) need to be added to `BANGUI_ALLOWED_LOG_DIRS`.
### Docs changes needed
- `Features.md` — document the log path restrictions.
- `Backend-Development.md` — input validation for path parameters.
### Doc references
- [Features.md](Features.md) — jail log monitoring
- [Backend-Development.md](Backend-Development.md) — path validation
---
## TASK-015 — `GlobalConfigUpdate.log_target`/`log_level` have no validation
**Severity:** High