fix(security): address code review feedback on validation logic

- Improve comment documentation for defense-in-depth validation
- Fix test assertion to properly validate basename sanitization
- Note regex pattern duplication for future refactoring

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-02-10 10:28:39 +00:00
parent 489aa67a13
commit a3d0af2efc
2 changed files with 13 additions and 12 deletions
+7 -7
View File
@@ -129,16 +129,16 @@ def extract_metadata_with_gpt(self, filename: str, cleaned_text: str, file_id: i
import re import re
filename = metadata.get("filename", "") filename = metadata.get("filename", "")
if filename: if filename:
# Check if filename contains only safe characters (alphanumeric, dash, underscore, period, space) # Check if filename contains only safe characters AND explicitly check for ".."
# This matches the sanitize_filename behavior but validates before use # Defense in depth: While the regex [\w\-\. ]+ already excludes / and \,
if not re.match(r'^[\w\-\. ]+$', filename): # we explicitly reject ".." to guard against:
# 1. Potential locale-specific \w behavior
# 2. Files literally named ".." which are valid but problematic
# 3. Future code changes that might relax the regex
if not re.match(r'^[\w\-\. ]+$', filename) or ".." in filename:
logger.warning(f"[{task_id}] Invalid filename format from GPT: '{filename}', using fallback") logger.warning(f"[{task_id}] Invalid filename format from GPT: '{filename}', using fallback")
# Reset to empty to trigger fallback to original filename # Reset to empty to trigger fallback to original filename
metadata["filename"] = "" metadata["filename"] = ""
# Additional check: ensure no path traversal patterns
elif ".." in filename or "/" in filename or "\\" in filename:
logger.warning(f"[{task_id}] Path traversal attempt in GPT filename: '{filename}', using fallback")
metadata["filename"] = ""
logger.info(f"[{task_id}] Extracted metadata: {metadata}") logger.info(f"[{task_id}] Extracted metadata: {metadata}")
log_task_progress( log_task_progress(
+6 -5
View File
@@ -220,7 +220,8 @@ class TestExtractMetadataFilenameValidation:
"""Test that invalid filename formats are rejected.""" """Test that invalid filename formats are rejected."""
import re import re
# Valid pattern from sanitize_filename: alphanumeric, dash, underscore, period, space # Valid pattern from extract_metadata_with_gpt.py
# TODO: Consider extracting this to a shared constant to avoid duplication
valid_pattern = r'^[\w\-\. ]+$' valid_pattern = r'^[\w\-\. ]+$'
# Test valid filenames # Test valid filenames
@@ -376,10 +377,10 @@ class TestFileUploadSecurity:
# os.path.basename should extract just the filename # os.path.basename should extract just the filename
basename = os.path.basename(malicious) basename = os.path.basename(malicious)
# Verify no path traversal remains # Verify no path traversal remains in basename
assert ".." not in basename or malicious.endswith("..") assert ".." not in basename, f"Path traversal not removed: {malicious} -> {basename}"
assert "/" not in basename assert "/" not in basename, f"Path separator not removed: {malicious} -> {basename}"
assert "\\" not in basename assert "\\" not in basename, f"Path separator not removed: {malicious} -> {basename}"
def test_sanitize_after_basename(self): def test_sanitize_after_basename(self):
"""Test that sanitization happens after basename extraction.""" """Test that sanitization happens after basename extraction."""