fix: resolve relative folder paths against anime dir in delete_series
The folder column in anime_series stores the relative folder name
(e.g. 'Beyblade Burst (2016)'), not an absolute path. The old
delete_series code called os.path.abspath(folder_path) directly,
which joins a relative path against the process current working
directory. Inside the container the FastAPI app runs with CWD=/app
while the anime directory is /data, so 'Beyblade Burst (2016)'
resolved to '/app/Beyblade Burst (2016)' and the is_safe_path check
correctly (but unhelpfully) flagged it as outside the /data base,
skipping the folder delete while still removing the row.
Fix: resolve relative folder paths against the configured anime
directory before validating against the base. Absolute paths still
work unchanged.
Also harden is_safe_path() the same way so a relative target is
treated as relative to base_path, not to the process CWD. Path
traversal ('../etc/passwd') is still rejected.
Adds two regression tests:
- is_safe_path with chdir to '/' and relative target resolves
against the base
- delete_series with chdir to '/', relative folder in DB,
succeeds and removes the folder
This commit is contained in:
@@ -1749,9 +1749,22 @@ class AnimeService:
|
||||
|
||||
# --- Filesystem deletion ---
|
||||
if delete_folder and folder_path:
|
||||
# Resolve absolute path and validate it is within base directory
|
||||
abs_folder = _os.path.abspath(folder_path)
|
||||
# Resolve absolute path and validate it is within base directory.
|
||||
#
|
||||
# Important: `folder_path` stored in the database is the relative
|
||||
# folder name (e.g. "Beyblade Burst (2016)"), not an absolute path.
|
||||
# If we feed a relative path to os.path.abspath() it gets joined
|
||||
# against the process's current working directory — which may be
|
||||
# /app inside the container while the anime directory is /data,
|
||||
# producing e.g. "/app/Beyblade Burst (2016)" and tripping the
|
||||
# safe-path check below for what is actually a valid deletion.
|
||||
# Resolve relative paths against the configured anime directory
|
||||
# so the safety check operates on the real intended target.
|
||||
base_dir = _os.path.abspath(self._directory)
|
||||
if _os.path.isabs(folder_path):
|
||||
abs_folder = _os.path.abspath(folder_path)
|
||||
else:
|
||||
abs_folder = _os.path.abspath(_os.path.join(base_dir, folder_path))
|
||||
|
||||
if not is_safe_path(base_dir, abs_folder):
|
||||
logger.warning(
|
||||
|
||||
Reference in New Issue
Block a user