Cache Poisoning Case Studies Part 1: Foundational Attacks Behind a $100K+ Vulnerability Class
The first part of a three-section deep dive analyzing early real-world cache poisoning bugs across HackerOne, GitHub, Shopify, and private programs.
Disclaimer
This research-driven article is for educational and defensive security purposes only. All case studies are based on publicly disclosed bug bounty reports and ethical security research.
Do not reproduce these techniques on systems without explicit authorization.
Introduction
Cache poisoning has become one of the most powerful and profitable bug classes in modern web security. Although it once appeared niche, cache poisoning has evolved into a high-impact attack vector affecting CDNs, cloud platforms, server frameworks, and multi-tenant SaaS providers.
This Part 1 of the three-part series covers the foundational attacks - the first documented real-world cache poisoning incidents that paved the way for later, more sophisticated techniques. These early reports demonstrate not only how straightforward misconfigurations can lead to devastating effects, but also how attackers learned to weaponize headers, request behaviors, and cache key inconsistencies to breach platforms with millions of users.
These case studies lay the groundwork for advanced exploitation techniques covered in Part 2 and Part 3.

Understanding Web Cache Poisoning
Before diving into each case, it’s worth revisiting what cache poisoning is:
Web cache poisoning occurs when an attacker manipulates a reverse proxy, CDN, or server-side cache into storing a malicious response, which is then served to other users.
Beginner Breakout: Why Caches Exist
Caches accelerate performance by storing responses to common requests such as:
- Static files (JS, CSS, images)
- API responses
- HTML pages
If the cache returns the wrong content - malicious or invalid - all users are affected until the cache expires.
Why Cache Poisoning Is Dangerous
Because:
- It scales automatically
- Affects many users with one request
- Often bypasses authentication
- Can convert reflected bugs into stored bugs
- Can break entire applications (DoS)
- Can lead to XSS, redirection, content injection, OAuth token leak, and more
Case Study #1 - HackerOne’s Early Days: The First Documented Cache Poison
Program: HackerOne
Bounty: Undisclosed
Year: 2014
Report ID: #487
This case is historically important because it is one of the earliest documented cache poisoning reports on a mainstream bug bounty platform.
The Vulnerability
HackerOne trusted the X-Forwarded-Host header without validation. Since the header wasn’t part of the cache key, attackers could poison the cache.
Attack Request
After a single malicious request, anyone visiting hackerone.com was redirected to evil.com.
Why It Worked
- The application blindly trusted proxy headers.
- The header was not included in the cache key.
- Poisoning persisted for subsequent visitors.
Extracted Techniques
- Test legacy headers (
X-Forwarded-*). - Confirm poison persistence after removing headers.
- Always demonstrate real impact (redirect chains, spoofed hostnames).

Case Study #2 - GitHub’s $4,850 Repository DoS Through Content-Type Poisoning
Program: GitHub
Reporter: Iustin Ladunca
Bounty: $4,850
Impact: Repository DoS for unauthenticated users
The Vulnerability
GitHub treated the Content-Type header as part of its redirect logic but did not include it in the cache key for unauthenticated users.
Attack Vector
Authenticated users were protected due to cookie-based cache keys, but all unauthenticated traffic shared a single cache entry.
Using PURGE (Amplifier)
GitHub mistakenly allowed the PURGE method, making the attack trivial to weaponize.
Extracted Techniques
- Always test behavior differences for authenticated vs unauthenticated users.
- Check for support of dangerous methods like
PURGE. - Cacheable error responses = high-value targets.



Case Study #3 - Shopify’s $6,300 Multi-Host Cache Poison
Program: Shopify
Reporter: Iustin Ladunca
Initial Bounty: $1,300
Final Bounty: $6,300
Report ID: #977851
This attack is notable for its persistence across multiple hosts.
Attack Code (Looped Poisoning)
Key Learnings
- Some caches need multiple hits before poisoning.
- Once poisoned, the malicious value persisted even without the header.
- The vulnerability extended across multiple Shopify properties, increasing bounty.
Extracted Techniques
- Test for multi-host impact - many companies use shared caching layers.
- Loop poisoning requests to force cache overwrite.
- Document impact across localized hosts for larger bounties.

Case Study #4 - Private Program’s $3,000 Stored XSS Chain
Program: Private
Severity: Critical
Bounty: $3,000
This case demonstrates how cache poisoning can convert a reflected XSS into a stored XSS affecting many users.
Attack Request
Server responded with a 301 redirect which included a poisoned host value.
The redirect was cached, and all users were served:
- JavaScript from
attacker.com - Malicious payloads executed on all subdomains
Impact
- Malware injection
- Session hijacking
- Account takeover
- Stored XSS across 21 subdomains
Extracted Techniques
- Target JavaScript files - they are universally cached.
- Test redirect (301/302) responses with unkeyed headers.
- Map shared JS dependencies for multi-domain attacks.


Case Study #5 - GitLab Cache Poisoning via Google Cloud Storage
Program: GitLab
Reporter: Iustin Ladunca
Report ID: #1160407
GitLab stored static files on GCP buckets, which introduced a unique attack surface.
Attack Vector
This forced GCP to override GET → HEAD, returning:
The empty body was cached, effectively breaking the site.
Why It Worked
- GCP Storage supports method overrides.
- GitLab's cache lacked method-awareness.
- HEAD responses overwrote GET cache entries.
Extracted Techniques
- Method override headers are highly dangerous.
- Test cloud platform behavior (GCP, AWS, Azure).
- Empty-body attacks can DoS entire applications.

Case Study #6 - HackerOne’s $2,500 Static File DoS
Program: HackerOne
Bounty: $2,500
Note: DoS was typically out of scope but rewarded due to novelty.
Vulnerability
Rails Rack middleware trusted X-Forwarded-Scheme.
By poisoning static files, attackers created infinite redirect loops.
Attack
Server returned a 301 redirect which cached globally, breaking images for all users.
Extracted Techniques
- Framework-specific headers (Rails, Django, Laravel) often introduce weaknesses.
- Redirect loops result in high-impact DoS.
- Even static files can be high-severity cache poison targets.

Case Study #7 - Cloudflare’s Capitalized Host Header Bug
Reporter: Iustin Ladunca
Bounty Range: $500–$3,000 per affected program
Scope: 20+ vulnerable programs
This bug was CDN-wide, enabling massive horizontal exploitation.
Attack Pattern
Cloudflare normalized host headers before caching but forwarded them raw to origin servers.
Why It Was Devastating
- Default Cloudflare config vulnerable
- No special setup needed
- Millions of sites potentially affected
- One request could poison countless customers
Extracted Techniques
- Case manipulation (uppercase, mixed case) is mandatory testing.
- CDN-level bugs scale horizontally - create automated scanners.
- Focus on differences between origin and CDN processing.

Case Study #8 - Red Hat’s Open Graph Stored XSS
Program: Red Hat
Reporter: James Kettle (PortSwigger)
This bug highlighted meta-tag poisoning and its amplification via social media.
Attack
The poisoned header appeared in Open Graph metadata, then cached.
Why It’s Critical
- Social networks embed Open Graph tags.
- Cached poisoned tags executed XSS for anyone opening shared links.
- Amplifiable via Twitter, Facebook, LinkedIn.
Extracted Techniques
- Meta tags (
og:image,og:url, etc.) are high-value injection points. - “no-cache” headers can still be cached depending on CDN rules.
- Use cache busters (
?dontpoisoneveryone=1) to stay safe during testing.

Defensive Perspective
Cache poisoning is preventable when organizations enforce strong, layered defenses.
Application-Level Defenses
- Validate all inbound headers.
- Reject unrecognized headers explicitly.
- Include all relevant inputs in cache keys.
CDN-Level Defenses
- Normalize header behavior consistently.
- Block dangerous headers (
X-Forwarded-*,X-HTTP-Method-Override). - Prevent caching of error responses unless necessary.
Architecture-Level Defenses
- Avoid shared cache pools across tenants.
- Use strict content-type validation.
- Disable method override functionality.
Real-World Impact Summary (Part 1)
| Case Study | Impact Type | Severity |
|---|---|---|
| HackerOne (2014) | Global redirect | High |
| GitHub DoS | Unauth DoS | Medium–High |
| Shopify multi-host | Persistent poisoning | High |
| Private program XSS | Stored XSS | Critical |
| GitLab GCP | Application DoS | High |
| HackerOne static | Redirect loop | Medium |
| Cloudflare | CDN-wide cache poison | Critical |
| Red Hat social XSS | Mass victim exposure | Critical |
Final Thoughts on Part 1
The earliest cache poisoning attacks were deceptively simple - using common headers like X-Forwarded-Host or malformed content types - yet their real-world consequences were severe. These foundational reports laid the groundwork for the more advanced, framework-specific, multi-layer, and supply-chain attacks examined in Part 2 and Part 3.
If Part 1 shows anything, it's this:
Cache poisoning is not just a bug - it's an architectural blind spot.
References
- PortSwigger Research
- HackerOne Reports (Public)
- Shopify, GitLab, GitHub public disclosure archives
- CDN vendor documentation (Cloudflare, Fastly, Akamai)