fix: reject empty versionId query parameter in object actions

S3 returns `InvalidArgument` when an object action receives a `versionId` query parameter with no value. The gateway silently treated it as an unversioned request instead.

Added a shared `versionId` validation helper and apply it to the object actions that accept the parameter, so malformed requests are rejected up front rather than reaching the backend.
This commit is contained in:
niksis02
2026-09-10 16:35:05 +04:00
parent be3ec8ba4d
commit 1e0d7b218d
23 changed files with 437 additions and 6 deletions
+40
View File
@@ -40,6 +40,14 @@ func (c S3ApiController) GetObjectTagging(ctx fiber.Ctx) (*Response, error) {
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
if err := utils.ValidateVersionId(ctx); err != nil {
return &Response{
MetaOpts: &MetaOptions{
BucketOwner: parsedAcl.Owner,
},
}, err
}
action := auth.GetObjectTaggingAction
if versionId != "" {
action = auth.GetObjectVersionTaggingAction
@@ -101,6 +109,14 @@ func (c S3ApiController) GetObjectRetention(ctx fiber.Ctx) (*Response, error) {
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
if err := utils.ValidateVersionId(ctx); err != nil {
return &Response{
MetaOpts: &MetaOptions{
BucketOwner: parsedAcl.Owner,
},
}, err
}
err := c.verifyAccess(ctx, auth.AccessOptions{
Acl: parsedAcl,
AclPermission: auth.PermissionRead,
@@ -147,6 +163,14 @@ func (c S3ApiController) GetObjectLegalHold(ctx fiber.Ctx) (*Response, error) {
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
if err := utils.ValidateVersionId(ctx); err != nil {
return &Response{
MetaOpts: &MetaOptions{
BucketOwner: parsedAcl.Owner,
},
}, err
}
err := c.verifyAccess(ctx, auth.AccessOptions{
Acl: parsedAcl,
AclPermission: auth.PermissionRead,
@@ -289,6 +313,14 @@ func (c S3ApiController) GetObjectAttributes(ctx fiber.Ctx) (*Response, error) {
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
if err := utils.ValidateVersionId(ctx); err != nil {
return &Response{
MetaOpts: &MetaOptions{
BucketOwner: parsedAcl.Owner,
},
}, err
}
action := auth.GetObjectAttributesAction
if versionId != "" {
action = auth.GetObjectVersionAttributesAction
@@ -412,6 +444,14 @@ func (c S3ApiController) GetObject(ctx fiber.Ctx) (*Response, error) {
}, s3err.GetAPIError(s3err.ErrAnonymousResponseHeaders)
}
if err := utils.ValidateVersionId(ctx); err != nil {
return &Response{
MetaOpts: &MetaOptions{
BucketOwner: parsedAcl.Owner,
},
}, err
}
action := auth.GetObjectAction
if ctx.Request().URI().QueryArgs().Has("versionId") {
action = auth.GetObjectVersionAction