fix(api): reject backslash traversal in safe_cache_key

This commit is contained in:
imSp4rky
2026-07-16 23:22:14 -06:00
parent cd0b9e1709
commit a856d14d25
2 changed files with 30 additions and 2 deletions
+25
View File
@@ -0,0 +1,25 @@
"""Regression tests for peer-input sanitizers (``core/api/sanitize.py``)."""
from __future__ import annotations
from unshackle.core.api.sanitize import safe_cache_key
def test_safe_cache_key_rejects_backslash_traversal():
# On POSIX, backslash is a plain character, so pathlib.Path treats
# "..\\..\\secret" as one filename; written as "<key>.json" it escapes the
# cache dir on Windows. PureWindowsPath handling must reject it everywhere.
assert safe_cache_key("..\\..\\secret") is None
assert safe_cache_key("sub\\dir") is None
def test_safe_cache_key_rejects_forward_slash_and_dotdot():
assert safe_cache_key("../secret") is None
assert safe_cache_key("a/b") is None
assert safe_cache_key("..") is None
assert safe_cache_key(".") is None
assert safe_cache_key("") is None
def test_safe_cache_key_accepts_plain_filename():
assert safe_cache_key("valid-key_123") == "valid-key_123"
+5 -2
View File
@@ -2,7 +2,7 @@
from __future__ import annotations
from pathlib import Path
from pathlib import PureWindowsPath
from typing import Optional
@@ -17,9 +17,12 @@ def safe_cache_key(key: object) -> Optional[str]:
Cache keys are written as ``<key>.json`` inside a fixed directory. A key containing a
path separator, ``..``, or an absolute path would let the peer write outside that
directory, so anything that is not already a plain filename is rejected.
PureWindowsPath treats both ``/`` and ``\\`` as separators, so a key like
``..\\..\\secret`` is rejected even on POSIX (where backslash is a plain character).
"""
text = str(key)
name = Path(text).name
name = PureWindowsPath(text).name
if not name or name != text or name in {".", ".."}:
return None
return name