From 191a858e727ba055ed3da1756719537c7a1cd067 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Wed, 28 Jan 2026 16:20:58 -0800 Subject: [PATCH] s3tables: Fix parseTableFromARN() namespace and table name validation - Remove dead URL unescape for namespace (regex [a-z0-9_]+ cannot contain percent-escapes) - Add URL decoding and validation of extracted table name via validateTableName() to prevent callers from bypassing request validation done in other paths --- weed/s3api/s3tables/utils.go | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/weed/s3api/s3tables/utils.go b/weed/s3api/s3tables/utils.go index 6fac9bb48..f70273139 100644 --- a/weed/s3api/s3tables/utils.go +++ b/weed/s3api/s3tables/utils.go @@ -46,18 +46,22 @@ func parseTableFromARN(arn string) (bucketName, namespace, tableName string, err return "", "", "", fmt.Errorf("invalid table ARN: %s", arn) } - // URL decode the namespace from the ARN path component - namespaceUnescaped, err := url.PathUnescape(matches[2]) + // Namespace is already constrained by the regex; validate it directly. + namespace = matches[2] + _, err = validateNamespace([]string{namespace}) if err != nil { - return "", "", "", fmt.Errorf("invalid namespace encoding in ARN: %v", err) + return "", "", "", fmt.Errorf("invalid namespace in ARN: %v", err) } - _, err = validateNamespace([]string{namespaceUnescaped}) + // URL decode and validate the table name from the ARN path component + tableNameUnescaped, err := url.PathUnescape(matches[3]) if err != nil { - return "", "", "", fmt.Errorf("invalid namespace in ARN: %v", err) + return "", "", "", fmt.Errorf("invalid table name encoding in ARN: %v", err) } - - return matches[1], namespaceUnescaped, matches[3], nil + if _, err := validateTableName(tableNameUnescaped); err != nil { + return "", "", "", fmt.Errorf("invalid table name in ARN: %v", err) + } + return matches[1], namespace, tableNameUnescaped, nil } // Path helpers