Skip to content

Commit

Permalink
Error out for invalid object name with '.' and '..' (#1431)
Browse files Browse the repository at this point in the history
Signed-off-by: Bala.FA <bala@minio.io>
  • Loading branch information
balamurugana authored Aug 17, 2024
1 parent 76a51ae commit 67c0c8b
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 18 deletions.
36 changes: 18 additions & 18 deletions minio/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
from .helpers import (_DEFAULT_USER_AGENT, MAX_MULTIPART_COUNT,
MAX_MULTIPART_OBJECT_SIZE, MAX_PART_SIZE, MIN_PART_SIZE,
BaseURL, DictType, ObjectWriteResult, ProgressType,
ThreadPool, check_bucket_name, check_non_empty_string,
ThreadPool, check_bucket_name, check_object_name,
check_sse, check_ssec, genheaders, get_part_info,
headers_to_strings, is_valid_policy_type, makedirs,
md5sum_hash, queryencode, read_part_data, sha256_hash)
Expand Down Expand Up @@ -594,7 +594,7 @@ def select_object_content(
print(result.stats())
"""
check_bucket_name(bucket_name, s3_check=self._base_url.is_aws_host)
check_non_empty_string(object_name)
check_object_name(object_name)
if not isinstance(request, SelectRequest):
raise ValueError("request must be SelectRequest type")
body = marshal(request)
Expand Down Expand Up @@ -1107,7 +1107,7 @@ def fget_object(
)
"""
check_bucket_name(bucket_name, s3_check=self._base_url.is_aws_host)
check_non_empty_string(object_name)
check_object_name(object_name)

if os.path.isdir(file_path):
raise ValueError(f"file {file_path} is a directory")
Expand Down Expand Up @@ -1227,7 +1227,7 @@ def get_object(
response.release_conn()
"""
check_bucket_name(bucket_name, s3_check=self._base_url.is_aws_host)
check_non_empty_string(object_name)
check_object_name(object_name)
check_ssec(ssec)

headers = cast(DictType, ssec.headers() if ssec else {})
Expand Down Expand Up @@ -1315,7 +1315,7 @@ def copy_object(
print(result.object_name, result.version_id)
"""
check_bucket_name(bucket_name, s3_check=self._base_url.is_aws_host)
check_non_empty_string(object_name)
check_object_name(object_name)
if not isinstance(source, CopySource):
raise ValueError("source must be CopySource type")
check_sse(sse)
Expand Down Expand Up @@ -1535,7 +1535,7 @@ def compose_object(
print(result.object_name, result.version_id)
"""
check_bucket_name(bucket_name, s3_check=self._base_url.is_aws_host)
check_non_empty_string(object_name)
check_object_name(object_name)
if not isinstance(sources, (list, tuple)) or not sources:
raise ValueError("sources must be non-empty list or tuple type")
i = 0
Expand Down Expand Up @@ -1808,7 +1808,7 @@ def put_object(
)
"""
check_bucket_name(bucket_name, s3_check=self._base_url.is_aws_host)
check_non_empty_string(object_name)
check_object_name(object_name)
check_sse(sse)
if tags is not None and not isinstance(tags, Tags):
raise ValueError("tags must be Tags type")
Expand Down Expand Up @@ -2031,7 +2031,7 @@ def stat_object(
"""

check_bucket_name(bucket_name, s3_check=self._base_url.is_aws_host)
check_non_empty_string(object_name)
check_object_name(object_name)
check_ssec(ssec)

headers = cast(DictType, ssec.headers() if ssec else {})
Expand Down Expand Up @@ -2089,7 +2089,7 @@ def remove_object(
)
"""
check_bucket_name(bucket_name, s3_check=self._base_url.is_aws_host)
check_non_empty_string(object_name)
check_object_name(object_name)
self._execute(
"DELETE",
bucket_name,
Expand Down Expand Up @@ -2252,7 +2252,7 @@ def get_presigned_url(
print(url)
"""
check_bucket_name(bucket_name, s3_check=self._base_url.is_aws_host)
check_non_empty_string(object_name)
check_object_name(object_name)
if expires.total_seconds() < 1 or expires.total_seconds() > 604800:
raise ValueError("expires must be between 1 second to 7 days")

Expand Down Expand Up @@ -2636,7 +2636,7 @@ def delete_object_tags(
client.delete_object_tags("my-bucket", "my-object")
"""
check_bucket_name(bucket_name, s3_check=self._base_url.is_aws_host)
check_non_empty_string(object_name)
check_object_name(object_name)
query_params = {"versionId": version_id} if version_id else {}
query_params["tagging"] = ""
self._execute(
Expand Down Expand Up @@ -2664,7 +2664,7 @@ def get_object_tags(
tags = client.get_object_tags("my-bucket", "my-object")
"""
check_bucket_name(bucket_name, s3_check=self._base_url.is_aws_host)
check_non_empty_string(object_name)
check_object_name(object_name)
query_params = {"versionId": version_id} if version_id else {}
query_params["tagging"] = ""
try:
Expand Down Expand Up @@ -2703,7 +2703,7 @@ def set_object_tags(
client.set_object_tags("my-bucket", "my-object", tags)
"""
check_bucket_name(bucket_name, s3_check=self._base_url.is_aws_host)
check_non_empty_string(object_name)
check_object_name(object_name)
if not isinstance(tags, Tags):
raise ValueError("tags must be Tags type")
body = marshal(Tagging(tags))
Expand Down Expand Up @@ -2735,7 +2735,7 @@ def enable_object_legal_hold(
client.enable_object_legal_hold("my-bucket", "my-object")
"""
check_bucket_name(bucket_name, s3_check=self._base_url.is_aws_host)
check_non_empty_string(object_name)
check_object_name(object_name)
body = marshal(LegalHold(True))
query_params = {"versionId": version_id} if version_id else {}
query_params["legal-hold"] = ""
Expand Down Expand Up @@ -2765,7 +2765,7 @@ def disable_object_legal_hold(
client.disable_object_legal_hold("my-bucket", "my-object")
"""
check_bucket_name(bucket_name, s3_check=self._base_url.is_aws_host)
check_non_empty_string(object_name)
check_object_name(object_name)
body = marshal(LegalHold(False))
query_params = {"versionId": version_id} if version_id else {}
query_params["legal-hold"] = ""
Expand Down Expand Up @@ -2798,7 +2798,7 @@ def is_object_legal_hold_enabled(
print("legal hold is not enabled on my-object")
"""
check_bucket_name(bucket_name, s3_check=self._base_url.is_aws_host)
check_non_empty_string(object_name)
check_object_name(object_name)
query_params = {"versionId": version_id} if version_id else {}
query_params["legal-hold"] = ""
try:
Expand Down Expand Up @@ -2889,7 +2889,7 @@ def get_object_retention(
config = client.get_object_retention("my-bucket", "my-object")
"""
check_bucket_name(bucket_name, s3_check=self._base_url.is_aws_host)
check_non_empty_string(object_name)
check_object_name(object_name)
query_params = {"versionId": version_id} if version_id else {}
query_params["retention"] = ""
try:
Expand Down Expand Up @@ -2927,7 +2927,7 @@ def set_object_retention(
client.set_object_retention("my-bucket", "my-object", config)
"""
check_bucket_name(bucket_name, s3_check=self._base_url.is_aws_host)
check_non_empty_string(object_name)
check_object_name(object_name)
if not isinstance(config, Retention):
raise ValueError("config must be Retention type")
body = marshal(config)
Expand Down
10 changes: 10 additions & 0 deletions minio/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,16 @@ def check_non_empty_string(string: str | bytes):
raise TypeError() from exc


def check_object_name(object_name: str):
"""Check whether given object name is valid."""
check_non_empty_string(object_name)
tokens = object_name.split("/")
if "." in tokens or ".." in tokens:
raise ValueError(
"object name with '.' or '..' path segment is not supported",
)


def is_valid_policy_type(policy: str | bytes):
"""
Validate if policy is type str
Expand Down

0 comments on commit 67c0c8b

Please sign in to comment.