mirror of
https://github.com/versity/versitygw.git
synced 2026-01-07 04:06:23 +00:00
fix: fixes the bucket/object tagging key/value name validation
Fixes #1579 S3 enforces a specific rule for validating bucket and object tag key/value names. This PR integrates the regexp pattern used by S3 for tag validation. Official S3 documentation for tag validation rules: [AWS S3 Tag](https://docs.aws.amazon.com/AmazonS3/latest/API/API_control_Tag.html) There are two types of tagging inputs for buckets and objects: 1. **On existing buckets/objects** — used in the `PutObjectTagging` and `PutBucketTagging` actions, where tags are provided in the request body. 2. **On object creation** — used in the `PutObject`, `CreateMultipartUpload`, and `CopyObject` actions, where tags are provided in the request headers and must be URL-encoded. This implementation ensures correct validation for both types of tag inputs.
This commit is contained in:
@@ -658,6 +658,11 @@ const (
|
||||
TagLimitObject TagLimit = 10
|
||||
)
|
||||
|
||||
// The tag key/value validation pattern comes from
|
||||
// AWS S3 docs
|
||||
// https://docs.aws.amazon.com/AmazonS3/latest/API/API_control_Tag.html
|
||||
var tagRule = regexp.MustCompile(`^([\p{L}\p{Z}\p{N}_.:/=+\-@]*)$`)
|
||||
|
||||
// Parses and validates tagging
|
||||
func ParseTagging(data []byte, limit TagLimit) (map[string]string, error) {
|
||||
var tagging s3response.TaggingInput
|
||||
@@ -682,18 +687,30 @@ func ParseTagging(data []byte, limit TagLimit) (map[string]string, error) {
|
||||
tagSet := make(map[string]string, tLen)
|
||||
|
||||
for _, tag := range tagging.TagSet.Tags {
|
||||
// validate tag key
|
||||
// validate tag key length
|
||||
if len(tag.Key) == 0 || len(tag.Key) > 128 {
|
||||
debuglogger.Logf("tag key should 0 < tag.Key <= 128, key: %v", tag.Key)
|
||||
return nil, s3err.GetAPIError(s3err.ErrInvalidTagKey)
|
||||
}
|
||||
|
||||
// validate tag value
|
||||
// validate tag key string chars
|
||||
if !tagRule.MatchString(tag.Key) {
|
||||
debuglogger.Logf("invalid tag key: %s", tag.Key)
|
||||
return nil, s3err.GetAPIError(s3err.ErrInvalidTagKey)
|
||||
}
|
||||
|
||||
// validate tag value length
|
||||
if len(tag.Value) > 256 {
|
||||
debuglogger.Logf("invalid long tag value: (length): %v, (value): %v", len(tag.Value), tag.Value)
|
||||
return nil, s3err.GetAPIError(s3err.ErrInvalidTagValue)
|
||||
}
|
||||
|
||||
// validate tag value string chars
|
||||
if !tagRule.MatchString(tag.Value) {
|
||||
debuglogger.Logf("invalid tag value: %s", tag.Value)
|
||||
return nil, s3err.GetAPIError(s3err.ErrInvalidTagValue)
|
||||
}
|
||||
|
||||
// make sure there are no duplicate keys
|
||||
_, ok := tagSet[tag.Key]
|
||||
if ok {
|
||||
|
||||
Reference in New Issue
Block a user