BUG BOUNTYFIELD MANUAL
Reusable module
Markdown
0 / 6 checkedChecks last until this page reloads.

Object storage, signed URLs and delivery boundaries

Follow one private canary through upload, signing, CDN delivery and expiry without enumerating real objects.

Investigation sequence
  1. 01Create private canaries
  2. 02Map origin and delivery
  3. 03Compare anonymous and tenant access
  4. 04Test capability scope
  5. 05Verify cleanup and expiry

At each step: retain the control → record the observation → continue only while the next boundary is understood.

Used in these playbooks#

Setup and invariant#

Create two tiny text objects in controlled storage, one private object per tenant, containing different random markers. Record bucket/account, exact keys, region, encryption requirements, application ownership and delivery host. Obtain the intended read, write, share and revocation rules. Only an entitled caller may mint or exercise the capability promised by the product. Reuse authorization testing for tenant changes; this module adds cloud storage and delivery behavior.

Procedure#

  1. Separate the access paths. Draw upload API → signer → storage object → CDN → browser. Add direct origin access, access points and background exports if the product uses them. Decide whether a file is meant to be public before calling anonymous retrieval a finding.

  2. Establish object-specific baselines. The owner must retrieve the exact marker; an unauthenticated client and the other tenant should fail where privacy is promised. Inspect owner-provided policy and effective public-access controls. A permissive bucket statement can be overridden by account or other public-access blocks; a block-status response does not examine every application sharing path. S3 public-access controls

  3. Inspect signed capability issuance. Ask tenant A to create its normal download or upload capability. Then change only the owned fixture's target key to B's key through the application's supported request. Compare authorization before signing and before asynchronous result release. Properly issued presigned URLs are intentionally usable by their holders; that property alone is not an authorization bug. S3 presigned URLs

  4. Test the promised restrictions. Compare the allowed method/object with a changed method or the other synthetic key. Check the agreed expiry using timestamps and a single later request, allowing for documented credential lifetime and clock behavior. For write tests, allocate a separate disposable key and explicit permission; never overwrite an existing customer file. Capture the owner-confirmed object version and marker before and after.

  5. Compare delivery and origin. Request the private fixture through the intended authenticated CDN path, then directly from its owned origin without credentials. The direct path should enforce the documented protection. A publicly intended origin is a valid control, not a bypass. CloudFront origin access control applies differently to normal S3 origins and website endpoints; match the actual configuration. CloudFront origin restrictions

Command card#

The first command reads at most 64 bytes of the exact fixture through unsigned S3 access. It performs no listing. Credentials, URLs and output files should stay private.

aws s3api get-object --bucket OWNED_BUCKET \
  --key bounty/private-canary.txt --range bytes=0-63 \
  --expected-bucket-owner YOUR_ACCOUNT_ID --no-sign-request \
  --no-cli-pager --cli-connect-timeout 5 --cli-read-timeout 10 \
  ./anonymous-canary.bin

aws --profile lab-owner s3 presign \
  s3://OWNED_BUCKET/bounty/private-canary.txt \
  --expires-in 60 --region YOUR_REGION \
  --cli-connect-timeout 5 --cli-read-timeout 10

curl -q --silent --show-error --max-time 10 --max-filesize 1024 \
  --dump-header ./delivery.headers \
  --output ./delivery-canary.txt \
  https://OWNED_DELIVERY_HOST/bounty/private-canary.txt

Use the second command only to establish an intentionally issued positive control. Do not paste its bearer URL into reports or shared shell history. The curl command follows no redirects: inspect any redirect destination before testing it. Expected evidence is the marker or an access denial, not merely HTTP 200. S3 GetObject CLI, presign CLI

Interpretation and completion#

Report the precise failed boundary: anonymous private read, unauthorized capability issuance, cross-tenant overwrite, or direct-origin bypass. A 403 cannot distinguish every encryption, ownership and permission cause; an HTML login page is not object exposure. Avoid speculative findings based only on predictable keys or a reusable valid share URL. For URL-driven storage imports, reuse SSRF boundaries.

  • Object owner, privacy promise and marker recorded.
  • Anonymous, entitled and other-tenant cases compared.
  • Signature lifetime distinguished from application-session lifetime.
  • Origin and delivery tested against the same fixture.
  • Fixture versions removed; temporary shares revoked where supported.
  • Cached copies handled according to the owner's cleanup procedure.

For Azure SAS types and Entra versus Shared Key access, or GCP object ACLs and uniform bucket-level access, use Azure and GCP boundaries alongside this shared canary procedure.

Vulnerability reverse references#

Nearby shared procedures#

Object, function, and property authorization · Authentication, recovery, federation, and session lifecycle · Trace input into queries, commands, and templates · Server-side fetching and network trust boundaries · Browser execution, cross-origin reads, and forged actions · Uploads, downloads, paths, archives, and XML · Workflow invariants, replay, idempotency, and races · REST, GraphQL, gRPC, WebSocket, and SSE permission parity