fix: cache path traversal via sibling-prefix bypass in serve_cache_file (#25086)
serve_cache_file gated the resolved path with file_path.startswith(os.path.abspath(CACHE_DIR)) without a trailing os.sep, so any path resolving to a sibling whose name starts with the cache-dir basename (e.g. cache_backup, cached_models) passed the prefix check. Authenticated users could read files from such siblings via /cache/../<sibling>/<file>. Appending os.sep to the prefix closes the bypass; deep traversal and absolute paths were already correctly blocked. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
07cbc91a8e
commit
b0fa4384ea
@@ -2935,7 +2935,10 @@ async def serve_cache_file(
|
||||
XSS from user-generated HTML stored in the cache directory.
|
||||
"""
|
||||
file_path = os.path.abspath(os.path.join(CACHE_DIR, path))
|
||||
if not file_path.startswith(os.path.abspath(CACHE_DIR)):
|
||||
# trailing os.sep is required: without it, a path resolving to a sibling
|
||||
# whose name starts with the cache-dir basename (e.g. cache_backup) passes
|
||||
cache_root = os.path.abspath(CACHE_DIR) + os.sep
|
||||
if not file_path.startswith(cache_root):
|
||||
raise HTTPException(status_code=404, detail='File not found')
|
||||
if not os.path.isfile(file_path):
|
||||
raise HTTPException(status_code=404, detail='File not found')
|
||||
|
||||
Reference in New Issue
Block a user