Skip to main content

Upload Policy Hardening

Signed upload policies that allow prefix-scoped keys or unrestricted content types, enabling object overwrite and stored XSS attacks.

Background

Direct client-to-S3 uploads via presigned URLs are common for user-facing features like avatar uploads and document inboxes. Two common misconfigurations create exploitable gaps:

  1. Prefix-scoped keys: A starts-with condition on the object key lets attackers write to any path under the prefix, enabling cross-tenant overwrites on shared buckets.
  2. Unrestricted content types: Without a content-type condition, attackers can upload SVGs with embedded JavaScript or HTML files, causing stored XSS when served from the bucket's domain.

Based on: HackerOne presigned upload patterns documented in Intigriti S3 guide

Resources

upload-api-user-avatars (s3_upload_policy) -- prefix-scoped key mode AND no content-type restriction. Both upload hardening controls fire.

upload-api-document-inbox (s3_upload_policy) -- exact key mode but no content-type restriction. Only the content-type control fires.

upload-api-profile-photos (s3_upload_policy) -- exact key mode with content-type restriction. Safe -- no controls fire.

Triggered Controls

ControlResourceDescription
CTL.S3.WRITE.SCOPE.001upload-api-user-avatarsSigned Upload Must Bind To Exact Object Key
CTL.S3.WRITE.CONTENT.001upload-api-user-avatarsSigned Upload Must Restrict Content Types
CTL.S3.WRITE.CONTENT.001upload-api-document-inboxSigned Upload Must Restrict Content Types

Expected Findings

3 violations across 2 resources.