Skip to content

Commit 025f834

Browse files
authored
Refactor _load_files_in_dir for type hints and safety
Refactor _load_files_in_dir to use dict type hints and PurePosixPath for path validation.
1 parent e273365 commit 025f834

1 file changed

Lines changed: 17 additions & 4 deletions

File tree

src/google/adk/skills/_utils.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ def _load_skill_from_gcs_dir(
401401
f" name '{skill_name_expected}'."
402402
)
403403

404-
def _load_files_in_dir(subdir: str) -> Dict[str, Union[str, bytes]]:
404+
def _load_files_in_dir(subdir: str) -> dict[str, str | bytes]:
405405
prefix = f"{skill_dir_prefix}{subdir}/"
406406
blobs = bucket.list_blobs(prefix=prefix)
407407
result = {}
@@ -411,17 +411,30 @@ def _load_files_in_dir(subdir: str) -> Dict[str, Union[str, bytes]]:
411411
if not relative_path:
412412
continue
413413

414-
# Prevent path traversal via malicious GCS blob names
415-
normalized = os.path.normpath(relative_path)
416-
if normalized.startswith('..') or os.path.isabs(normalized):
414+
# Use PurePosixPath for platform-independent GCS path validation
415+
p = pathlib.PurePosixPath(relative_path)
416+
417+
# Reject absolute paths and traversal sequences
418+
if p.is_absolute() or ".." in p.parts:
417419
raise ValueError(
418420
f"Unsafe path in skill resource: {relative_path!r}"
419421
)
420422

423+
normalized = p.as_posix()
424+
425+
# Prevent silent file overwrites via path aliasing
426+
if normalized in result:
427+
raise ValueError(
428+
f"Duplicate normalized path detected: {normalized!r}"
429+
)
430+
431+
# NOTE: Final path safety enforced during materialization
432+
# via realpath + commonpath checks in skill_toolset.py
421433
try:
422434
result[normalized] = blob.download_as_text()
423435
except UnicodeDecodeError:
424436
result[normalized] = blob.download_as_bytes()
437+
425438
return result
426439

427440
references = _load_files_in_dir("references")

0 commit comments

Comments
 (0)