Skip to content

Commit 9f1b9ab

Browse files
Aryamanz29claude
andcommitted
fix: prevent path traversal in FileClient.upload_file
Add a check for '..' components in the file path passed to FileUpload.validate_file_path, raising a new INVALID_UPLOAD_FILE_PATH_TRAVERSAL error (ATLAN-PYTHON-400-077) if detected. Also use Path.resolve() to normalize the path before opening, preventing directory traversal attacks. Closes SEC-147 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent d7b30bd commit 9f1b9ab

3 files changed

Lines changed: 22 additions & 1 deletion

File tree

pyatlan/client/common/file.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# SPDX-License-Identifier: Apache-2.0
22
# Copyright 2025 Atlan Pte. Ltd.
3+
from pathlib import Path
34
from typing import Any
45

56
from pyatlan.client.constants import (
@@ -54,10 +55,16 @@ def validate_file_path(file_path: str) -> Any:
5455
5556
:param file_path: path to the file to upload
5657
:returns: opened file object
58+
:raises INVALID_UPLOAD_FILE_PATH_TRAVERSAL: if path traversal is detected
5759
:raises INVALID_UPLOAD_FILE_PATH: if file not found
5860
"""
61+
path = Path(file_path)
62+
if ".." in path.parts:
63+
raise ErrorCode.INVALID_UPLOAD_FILE_PATH_TRAVERSAL.exception_with_parameters(
64+
file_path
65+
)
5966
try:
60-
return open(file_path, "rb")
67+
return open(path.resolve(), "rb")
6168
except FileNotFoundError as err:
6269
raise ErrorCode.INVALID_UPLOAD_FILE_PATH.exception_with_parameters(
6370
str(err.strerror), file_path

pyatlan/errors.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,13 @@ class ErrorCode(Enum):
675675
"Set multi_valued=False when creating rich text attributes.",
676676
InvalidRequestError,
677677
)
678+
INVALID_UPLOAD_FILE_PATH_TRAVERSAL = (
679+
400,
680+
"ATLAN-PYTHON-400-077",
681+
"Path traversal detected in file path: {0}.",
682+
"Ensure the file path does not contain '..' components.",
683+
InvalidRequestError,
684+
)
678685
AUTHENTICATION_PASSTHROUGH = (
679686
401,
680687
"ATLAN-PYTHON-401-000",

tests/unit/test_file_client.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,13 @@ def test_file_client_methods_validation_error(client, method, params):
161161
"Error: No such file or directory, Path: some/invalid/file_path.png"
162162
),
163163
],
164+
[
165+
"../../etc/passwd",
166+
(
167+
"ATLAN-PYTHON-400-077 Path traversal detected in file path: "
168+
r"\.\.\/\.\.\/etc\/passwd"
169+
),
170+
],
164171
],
165172
)
166173
def test_file_client_upload_file_raises_invalid_request_error(

0 commit comments

Comments
 (0)