fix(security): address Greptile review comments for path traversal protection

- guardrail_endpoints.py: Fix edge case where file named exactly in the
  categories directory could be rejected. Added 'or resolved_path == resolved_categories_dir'
  to the boundary check.

- presidio.py: Add directory boundary check to _validate_recognizer_file_path
  to prevent absolute path attacks. The resolved path must now stay within
  the current working directory, similar to the guardrail_endpoints.py pattern.

These changes address the security review comments from Greptile on PR #20286.
This commit is contained in:
shin-bot-litellm 2026-02-07 08:45:41 +00:00
parent 5c03220c56
commit 737595729b
2 changed files with 10 additions and 1 deletions

View file

@ -766,7 +766,7 @@ async def get_category_yaml(category_name: str):
# Resolve to absolute path and verify it stays within categories_dir
resolved_path = os.path.realpath(category_file_path)
resolved_categories_dir = os.path.realpath(categories_dir)
if not resolved_path.startswith(resolved_categories_dir + os.sep):
if not (resolved_path.startswith(resolved_categories_dir + os.sep) or resolved_path == resolved_categories_dir):
raise HTTPException(
status_code=400, detail="Invalid category name."
)

View file

@ -152,6 +152,7 @@ class _OPTIONAL_PresidioPIIMasking(CustomGuardrail):
1. No path traversal sequences (../)
2. File must have .json extension
3. Path is resolved to absolute and checked
4. Path must stay within the current working directory (directory boundary check)
"""
import os
@ -176,6 +177,14 @@ class _OPTIONAL_PresidioPIIMasking(CustomGuardrail):
f"Invalid file path: resolved path must be a .json file. file_path={file_path}"
)
# Directory boundary check: ensure the resolved path stays within the
# current working directory to prevent absolute path attacks
base_dir = os.path.realpath(os.getcwd())
if not (resolved_path.startswith(base_dir + os.sep) or resolved_path == base_dir):
raise ValueError(
f"Invalid file path: path must be within the working directory. file_path={file_path}"
)
return resolved_path
def validate_environment(