# Dangling bucket origin takeover

Subdomain, CDN origin, or script src pointing at a deleted or never-registered cloud storage bucket

_Area: Web infrastructure and server-side requests. Seen in 4 disclosed reports; one confirmed bounty: $500; latest 2023-12-07. Updated 2026-10-23._

## How it works
A web property references a cloud storage bucket (S3, GCS) by name — as a CDN origin, a subdomain target, or a hardcoded script/JSON URL. The bucket is later deleted or was never created, but the reference remains. Bucket names are global and first-come, so anyone who learns the name can register it and control what the property serves. The broken assumption is that a name in config or HTML still resolves to content the owner controls.

## Where it shows up
- CDN/subdomain origin configs naming a bucket; the host returns S3 XML errors (NoSuchBucket, PermanentRedirect) revealing the bucket name and region [E2](https://bugbountylibrary.com/r/h1%3A2262939.md)[E3](https://bugbountylibrary.com/r/h1%3A1297689.md)
- Hardcoded `s3.amazonaws.com` or `storage.googleapis.com` URLs in HTML/JS, especially legacy or third-party widget endpoints [E1](https://bugbountylibrary.com/r/h1%3A1598347.md)[E4](https://bugbountylibrary.com/r/h1%3A1398706.md)
- Proxied SaaS widgets (`/read/page_widget/ID`) whose HTML loads external scripts from buckets [E1](https://bugbountylibrary.com/r/h1%3A1598347.md)
- Region mismatch between distribution and bucket, so a claim in the wrong region still works [E2](https://bugbountylibrary.com/r/h1%3A2262939.md)

## How to review
For every bucket reference, confirm the bucket exists and is owned by the organization, in the region the origin expects. The invariant: each referenced name must resolve to owner-controlled storage, or the reference must be removed. Check CDN origin settings, subdomain CNAMEs, and grep static assets for storage hostnames; then test whether the name is registered. Treat any storage error response as a signal to verify ownership, not just a broken link.

## Variants seen
- Deleted bucket behind a legacy third-party widget script tag, yielding stored XSS on the apex domain [E1](https://bugbountylibrary.com/r/h1%3A1598347.md)
- CloudFront origin pointing at a never-registered bucket with wrong region, serving cached content and forged checksums [E2](https://bugbountylibrary.com/r/h1%3A2262939.md)
- Deleted bucket behind a www subdomain via CDN, enabling content control and TLS cert issuance [E3](https://bugbountylibrary.com/r/h1%3A1297689.md)
- Unclaimed GCS bucket loaded as JS/JSON by a dashboard, leading to XSS [E4](https://bugbountylibrary.com/r/h1%3A1398706.md)

## Impact and severity
Led to stored XSS and credential phishing on apex domains [E1](https://bugbountylibrary.com/r/h1%3A1598347.md), content and checksum forgery [E2](https://bugbountylibrary.com/r/h1%3A2262939.md), subdomain takeover with TLS certs [E3](https://bugbountylibrary.com/r/h1%3A1297689.md), and dashboard XSS [E4](https://bugbountylibrary.com/r/h1%3A1398706.md). Severity rises when the reference sits on the apex domain, feeds cached responses, or supplies integrity-relevant data like checksums.

## Why fixes fail
Removing the visible page but leaving the widget or origin reference in place keeps the dangling name live [E1](https://bugbountylibrary.com/r/h1%3A1598347.md); fixing region alone does not reclaim an unowned bucket [E2](https://bugbountylibrary.com/r/h1%3A2262939.md).

## Evidence
- E1: https://bugbountylibrary.com/r/h1%3A1598347.md
- E2: https://bugbountylibrary.com/r/h1%3A2262939.md
- E3: https://bugbountylibrary.com/r/h1%3A1297689.md
- E4: https://bugbountylibrary.com/r/h1%3A1398706.md
