Before understanding the findings, you need the mental model.
┌─────────────────────────────────┐
│ HOST MACHINE │
│ (physical server, cloud infra) │
│ │
│ ┌──────────┐ ┌──────────┐ │
│ │ microVM │ │ microVM │ │
│ │ Sandbox A│ │ Sandbox B│ │
│ │(Customer)│ │(Customer)│ │
│ └──────────┘ └──────────┘ │
└─────────────────────────────────┘
Key concept: Multiple customers share one physical host. The sandbox is supposed to create an isolation boundary — what happens inside should stay inside.
Vercel uses Firecracker microVMs — lightweight virtual machines designed specifically for security isolation.
This is the single most important idea in the entire article.
A trust boundary is the line between code/data you control and code/data you do NOT control.
Host should NEVER trust input from the Guest
because the Guest runs UNTRUSTED customer code
FLAWED DESIGN:
┌─────────────────────────────────────────┐
│ Guest (sandbox) takes a snapshot │
│ Guest reports back: {url, size, checksum}│
│ Host TRUSTS this response ✗ │
└─────────────────────────────────────────┘
FIXED DESIGN:
┌─────────────────────────────────────────┐
│ Guest (sandbox) takes a snapshot │
│ Host generates its OWN storage path │
│ Host validates everything server-side ✓ │
└─────────────────────────────────────────┘
Think of it like this: Imagine a bank letting customers write their own account balances on a form and trusting those numbers. That is exactly what trusting guest-reported values means.
What is a zero day?
A vulnerability that is unknown to the vendor and has no patch available — zero days to fix it.
What happened:
Attacker's microVM
│
│ sends specially crafted packets
▼
Linux Kernel Networking Stack
│
├──► Leak host memory into outgoing packets
├──► Crash the entire host machine
└──► Execute code with FULL admin privileges on host
Why is this especially dangerous?
Almost every major cloud provider (AWS, Google, Azure, etc.) uses this same Linux kernel layer. One bug = shared risk across the entire industry.
Severity scale:
| Impact | Level |
|---|---|
| Read your own sandbox data | Low |
| Read another customer's data | High |
| Control the host machine | Critical |
Found by: A Vercel intern (important lesson — threats come from anywhere)
The flaw:
Sandbox A gets deleted
│
│ disk blocks get "recycled"
▼
Sandbox B gets created
│
│ can READ old disk blocks from Sandbox A
▼
Sandbox B reads Sandbox A's leftover data ✗
Real-world analogy: Like renting a hotel room and finding the previous guest's documents still in the safe because staff forgot to clear it.
This is the most instructive example because it shows how vulnerabilities chain together.
Step-by-step attack breakdown:
Step 1: Researcher owns Account A and Account B
Step 2: Account A takes a snapshot
Guest reports back: {storage_url_A, size, checksum}
Host TRUSTS this ← THE FLAW
Step 3: Researcher intercepts the response inside their sandbox
Rewrites it: {storage_url_B, size, checksum}
(swapping Account B's storage location)
Step 4: Restoring "Account A's snapshot" actually
loads Account B's entire filesystem
Result: Full read/write access to another account's files
Why the attack had limits:
To target a STRANGER you would need their snapshot storage key
= random 96-bit identifier
= never exposed through the API
= only exists inside the victim's own sandbox
∴ No demonstrated path to target arbitrary victims
But the fix was still urgent because:
A security boundary that depends on a secret staying secret is not a real boundary. Secrets can leak. Design must assume they will.
Trail of Bits gave three recommendations. These are universal security design principles you should memorize.
BEFORE: Host ←── trusts ──── Guest values
AFTER: Host derives values server-side
OR signs them with keys guest cannot reach
Practical rule: Every value crossing from guest → host must be treated as attacker-controlled input.
The problem:
Network Policy
│
├──► Subsystem A parses it → decision X
├──► Subsystem B parses it → decision Y ← different answer!
└──► Subsystem C parses it → decision Z
Why this is dangerous: Attackers find the subsystem that makes the most permissive decision and exploit the gap.
The fix:
Network Policy
│
└──► ONE canonicalization routine
│
└──► ONE decision component
│
└──► Consistent enforcement everywhere
Real-world analogy: Imagine a nightclub with three different bouncers using three different guest lists. An attacker finds the most lenient bouncer.
This is a defense-in-depth mindset:
Do not assume your isolation is perfect. Build layers so that when (not if) a vulnerability is found, the damage is contained.
Vercel's implementation:
Layer 1: Firecracker microVM isolation
Layer 2: Host kernels kept up to date
Layer 3: Nested virtualization disabled (reduces attack surface)
Layer 4: Firecracker's jailer = restricted permissions per microVM
Mental model — Swiss cheese defense:
Each layer has holes, but holes rarely line up
┌──┐ ┌──┐ ┌──┐ ┌──┐
│ ○ │ │ ○ │ │ │ ← attacker needs ALL holes to align
└──┘ └──┘ └──┘ └──┘
This is how security research should work ethically.
1. Researcher finds vulnerability
│
▼
2. Researcher contacts vendor PRIVATELY
│
▼
3. Vendor + Researcher collaborate on fix
│
▼
4. Vendor notifies affected industry partners
(AWS, other cloud providers in this case)
│
▼
5. Patch is developed and reviewed
│
▼
6. Patch ships publicly
│
▼
7. Vulnerability details published
(CVE assigned, public disclosure)
Why not disclose immediately?
Publishing details before a patch exists gives every attacker a roadmap with no defense available.
1,285 total reports
│
├── 877 duplicates (68%) ← same bugs found repeatedly
├── 319 not applicable (25%) ← misunderstood scope
├── 57 valid (4.4%) ← real vulnerabilities
└── 32 informative (2.5%) ← useful but not exploitable
Key insight: High duplicate rate means researchers converge on the same obvious attack surfaces. Unique findings come from diverse approaches.
Severity breakdown of valid findings:
| Severity | Count | Meaning |
|---|---|---|
| Critical | 1 | System-wide compromise possible |
| High | 5 | Significant data/access risk |
| Medium | 9 | Limited impact vulnerabilities |
| Low | 42 | Minor policy gaps |
$242,000 paid — mostly for that one Critical finding, demonstrating how severity drives bounty value.
| Concept | Key Takeaway |
|---|---|
| Trust Boundary | Never trust input from the guest side |
| Defense in Depth | Multiple layers; assume one will fail |
| Zero Day | Unknown vulnerability; no patch exists yet |
| Responsible Disclosure | Fix first, publish after |
| One Policy, One Decider | Inconsistent enforcement creates exploitable gaps |
| Attack Surface | Less code/features = fewer places to attack |