refactoring-backend #3
@@ -1,32 +1,3 @@
|
||||
## TASK-016 — `delete_log_path` query parameter unvalidated
|
||||
|
||||
**Severity:** Medium
|
||||
|
||||
### Where found
|
||||
`backend/app/routers/jail_config.py` — `DELETE /api/config/jails/{name}/logpath` — `log_path: str = Query(...)`.
|
||||
|
||||
### Why this is needed
|
||||
The `log_path` query parameter is passed directly to the fail2ban socket command `["set", name, "dellogpath", log_path]` without any path validation. An attacker could pass traversal strings or paths to sensitive files, instructing fail2ban to stop monitoring them and potentially confusing fail2ban's internal state.
|
||||
|
||||
### Goal
|
||||
Apply the same allowlist validation as `add_log_path` (TASK-014) to `delete_log_path`.
|
||||
|
||||
### What to do
|
||||
1. Extract the log path validation logic from TASK-014 into a shared helper function in `backend/app/utils/path_utils.py` (e.g., `validate_log_path(path: str, allowed_dirs: list[str]) -> str`).
|
||||
2. Call the helper from both `AddLogPathRequest` validator and the `delete_log_path` route handler.
|
||||
3. Return 422 with a descriptive error if validation fails.
|
||||
|
||||
### Possible traps and issues
|
||||
- Query parameters cannot have Pydantic field validators directly in FastAPI — use a `Depends` dependency that validates and returns the resolved path, or validate explicitly at the start of the route handler.
|
||||
|
||||
### Docs changes needed
|
||||
- `Backend-Development.md` — path validation helper usage.
|
||||
|
||||
### Doc references
|
||||
- [Backend-Development.md](Backend-Development.md) — input validation patterns
|
||||
|
||||
---
|
||||
|
||||
## TASK-017 — `ip LIKE ?` without escaping `%` and `_` wildcards
|
||||
|
||||
**Severity:** Medium
|
||||
|
||||
@@ -6,14 +6,14 @@ module implementations, making the backend easier to test and extend.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Iterable, Sequence
|
||||
from collections.abc import Sequence
|
||||
from typing import Any, Protocol
|
||||
|
||||
import aiosqlite
|
||||
|
||||
from app.models.auth import Session
|
||||
from app.models.ban import BanOrigin
|
||||
from app.repositories.fail2ban_db_repo import BanIpCount, BanRecord, HistoryRecord, JailBanCount
|
||||
from app.repositories.fail2ban_db_repo import BanRecord, HistoryRecord, JailBanCount
|
||||
from app.repositories.geo_cache_repo import GeoCacheRow
|
||||
from app.repositories.import_log_repo import ImportLogRow
|
||||
|
||||
|
||||
@@ -15,11 +15,8 @@ traversal attacks.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from app.utils.async_utils import run_blocking
|
||||
from app.exceptions import (
|
||||
ConfigDirError,
|
||||
ConfigFileExistsError,
|
||||
ConfigFileNameError,
|
||||
ConfigFileNotFoundError,
|
||||
ConfigFileWriteError,
|
||||
@@ -34,7 +31,6 @@ import structlog
|
||||
from app.models.file_config import (
|
||||
ConfFileContent,
|
||||
ConfFileCreateRequest,
|
||||
ConfFileEntry,
|
||||
ConfFilesResponse,
|
||||
ConfFileUpdateRequest,
|
||||
JailConfigFile,
|
||||
|
||||
Reference in New Issue
Block a user