Harden S3 auth boundaries

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-05-16 10:11:04 +02:00
parent eac20f7fda
commit 2425cd524e
10 changed files with 477 additions and 6 deletions

View File

@@ -196,6 +196,10 @@ func parseCopySource(raw string) (string, string, error) {
}
func (h *Handler) authorizeCopySource(r *http.Request, bucket, key string) error {
return h.authorizeObjectAction(r, auth.ActionGetObject, bucket, key)
}
func (h *Handler) authorizeObjectAction(r *http.Request, action auth.Action, bucket, key string) error {
if h.authSvc == nil || !h.authSvc.Config().Enabled {
return nil
}
@@ -206,7 +210,7 @@ func (h *Handler) authorizeCopySource(r *http.Request, bucket, key string) error
}
return h.authSvc.Authorize(authCtx.AccessKeyID, auth.RequestTarget{
Action: auth.ActionGetObject,
Action: action,
Bucket: bucket,
Key: key,
})
@@ -307,6 +311,10 @@ func (h *Handler) handlePostObject(w http.ResponseWriter, r *http.Request) {
r.Body = http.MaxBytesReader(w, r.Body, maxXMLBodyBytes)
var req models.CompleteMultipartUploadRequest
if err := xml.NewDecoder(r.Body).Decode(&req); err != nil {
if errors.Is(err, auth.ErrSignatureDoesNotMatch) {
writeMappedS3Error(w, r, err)
return
}
var maxErr *http.MaxBytesError
if errors.As(err, &maxErr) {
writeS3Error(w, r, s3ErrEntityTooLarge, r.URL.Path)
@@ -664,6 +672,10 @@ func (h *Handler) handlePostBucket(w http.ResponseWriter, r *http.Request) {
var req models.DeleteObjectsRequest
if err := xml.NewDecoder(bodyReader).Decode(&req); err != nil {
if errors.Is(err, auth.ErrSignatureDoesNotMatch) {
writeMappedS3Error(w, r, err)
return
}
var maxErr *http.MaxBytesError
if errors.As(err, &maxErr) {
writeS3Error(w, r, s3ErrEntityTooLarge, r.URL.Path)
@@ -699,6 +711,15 @@ func (h *Handler) handlePostBucket(w http.ResponseWriter, r *http.Request) {
})
continue
}
if err := h.authorizeObjectAction(r, auth.ActionDeleteObject, bucket, obj.Key); err != nil {
apiErr := mapToS3Error(err)
response.Errors = append(response.Errors, models.DeleteError{
Key: obj.Key,
Code: apiErr.Code,
Message: apiErr.Message,
})
continue
}
keys = append(keys, obj.Key)
}