I have written a few posts about why I ended up on Azure Static Web Apps instead of Vercel. The short version is familiarity and bias: I have been in the Azure ecosystem for years, and it integrates cleanly with everything else I run at work. But I want to be honest about something. I was close. A previous company I worked at used Vercel and it was genuinely good. The developer experience is hard to argue with. If my background had been different, this blog would probably be hosted there.

Then on 19 April 2026, Vercel published a security bulletin I ended up reading three times. Not because it was badly written. Because each read revealed another layer of something uncomfortable about how modern hosting actually works, and about choices I nearly made.1

This is not a Vercel pile-on. They responded quickly, brought in Mandiant, notified law enforcement, and were reasonably transparent about the attack chain. What I want to do is use this incident as a lens on something the industry consistently underweights: the gap between security posture and security architecture. And what vibe coding culture has quietly done to widen that gap.

๐Ÿ”ด

The incident, briefly: Vercel confirmed on April 19, 2026 that attackers accessed internal systems and customer environment variables. The breach did not originate at Vercel. It originated at a third-party AI tool called Context.ai, which had itself been compromised weeks earlier. Stolen data was listed for sale on BreachForums for $2 million.

The attack chain

How a Roblox Script Nearly Poisoned the JavaScript Ecosystem

This is the part security researchers are calling textbook. The chain of events is clean, almost elegant, and almost impossible to have prevented with any standard set of controls.

Hudson Rock's analysis traced the root cause to a Context.ai employee who in February 2026 downloaded Roblox "auto-farm" scripts from the internet.2 Those scripts carried Lumma Stealer, a commodity infostealer that harvested everything on the machine: credentials, API keys, session tokens, and critically the support@context.ai account. With support account access, an attacker can impersonate the service itself to its own customers.

// Attack chain: Roblox script to Vercel internals
Context.ai employee downloads Roblox exploits Feb 2026 โ€” Lumma Stealer infects machine, harvests all credentials including support@context.ai
Attacker accesses Context.ai's AWS environment March 2026 โ€” OAuth tokens for consumer users compromised
A Vercel employee had installed the Context.ai browser extension Extension granted "Allow All" read access to corporate files. One OAuth token. One very wide door.
Attacker pivots from compromised OAuth token into Vercel systems The browser extension had been quietly removed from the Chrome Web Store on March 27. Too late.
Vercel internals accessed. Customer env vars read. 580 employee records exfiltrated. April 12-19, 2026 โ€” non-sensitive env vars, claimed access to npm and GitHub tokens

None of those steps required breaking Vercel's own perimeter directly. No cracked passwords on Vercel accounts. No Vercel zero-days. No failed MFA on their internal systems. The attacker found a chain of trusted relationships and walked along it.3

๐Ÿง€ ELI5 version

You give your cleaning service a spare key to your house. One of their employees leaves their bag on the bus. Someone finds the bag, finds the key, and now has access to your house. Your locks were fine. Your alarm was fine. The vulnerability was the copy of the key you handed to someone who left it somewhere unsafe.

Now scale that to: the cleaning service has keys to ten thousand houses, and one of those houses has keys to a building that supplies software to six million developers every week.

The vibe coding problem

Vibe Coding Is Brilliant. The Architecture Gap It Creates Is Not.

Here is where I want to go somewhere the other post-mortems on this incident are not going.

We are in the middle of a genuinely exciting shift in how software gets built. Tools like Cursor, GitHub Copilot, Claude, and Vercel's own v0 mean that someone with limited technical experience, or a developer six months into their career rather than six years, can ship a working product in a weekend. That is real. That is good. I have used these tools and they have meaningfully changed what I can build on my own.

But vibe coding, the practice of prompting your way through an application without deeply understanding the underlying architecture, creates a specific kind of risk that this incident puts a sharp point on. It is much easier to ship something than it is to understand what you have exposed in shipping it.

The vibe coder scenario

Ship first, understand later

Deploys a Next.js app to Vercel in 20 minutes. Pastes database URL and API keys into environment variables. Does not notice the "sensitive" toggle. Has no idea what an OAuth grant is or that the browser extension they installed can read their entire file system. The app works. The holes are invisible.

The architecture-first scenario

Understand the trust chain

Before deploying, asks: what does this platform have access to? What do I need to mark as sensitive? What am I authorising when I install this extension? What happens to my secrets if the provider is compromised? Most of these questions are not hard to answer. You just have to know to ask them.

The Context.ai browser extension granted read access to a Vercel employee's corporate files. That is not an unusual permission for a productivity tool to request. It is also exactly the kind of thing someone installs in ten seconds without reading the permissions dialogue, because the dialogue is long and the "Allow" button is right there. This is not unique to non-technical people. Experienced developers do it constantly.

Vibe coding amplifies this because when you are prompting your way through a deployment, you are often not pausing to understand the integration graph you are building. You are asking the AI to connect things together and shipping when it works. The problem is that "it works" and "it is secure" are not the same sentence. The app working just means the happy path is fine. It says nothing about what happens when something in your trust chain fails weeks later.

๐Ÿ’ก

The question worth asking before deploying to any hosted platform: If this company's internal systems were fully compromised for two weeks before anyone detected it, what data of mine would an attacker have access to? What would they be able to do with it?

If you cannot answer that, you do not yet understand the architecture of what you have built. The app working is not the finish line.

The serverless trade-off

Serverless Outsources Operations. It Does Not Outsource Risk.

I like serverless. I use it. Azure Functions, Azure Static Web Apps, the whole "let someone else worry about the server" model fits the kind of low-traffic, low-ops work I document here. The pitch is genuinely good: no patching, no capacity planning, pay for what you use.

The part of the pitch that does not get enough airtime is the implicit contract underneath it. When you go serverless, you hand your provider a set of keys. Environment variables containing your database passwords, your API tokens, your signing keys. CI/CD pipelines with write access to production. OAuth integrations into your source code. Those keys live on someone else's infrastructure, managed by someone else's employees, integrated with someone else's third-party tooling stack.

"Your security posture has always included your provider's security posture. The Vercel breach just made that visible."

The specific data exposed here was non-sensitive environment variables. In Vercel's model, you can mark a variable as "sensitive," which encrypts it so even Vercel staff cannot read it from the dashboard. Variables not marked sensitive were readable internally. The attacker, once inside Vercel's systems, could enumerate them.4

// The Vercel env var distinction โ€” before the breach changed the default

DATABASE_URL = "postgres://user:pass@host/db" // NOT marked sensitive โ†’ readable internally

STRIPE_SECRET_KEY = "sk_live_..." // NOT marked sensitive โ†’ readable internally

NEXT_PUBLIC_API_URL = "https://api.example.com" // fine, it's public anyway

// After April 2026: Vercel changed the default to sensitive:on for all new variables.

// Before that, the default was the opposite. Nobody advertised that prominently.

This is not a Vercel-specific issue. Azure SWA app settings are readable by anyone with contributor access to the resource group unless you explicitly route them through Key Vault. AWS Lambda environment variables are visible with the right IAM permissions. The "secure by default" bar across the serverless industry has always been lower than it should be. Vercel just got caught with it publicly.

The supply chain amplifier

Vercel Does Not Just Host Websites. They Own the Rails Everyone Runs On.

This is the part that made the security community genuinely nervous, and the part most developers outside the InfoSec world have not fully thought through. So let me spend some proper time on it, because it is more layered than the breach coverage suggests.

Vercel is not just a hosting company. They are the primary maintainer of Next.js, which in 2025 alone recorded more than 520 million downloads and roughly six million downloads every single week.5 But that number is almost the least interesting part of the concentration story.

The ecosystem they control

Vercel also maintains Turbopack, the Rust-based bundler being positioned as the successor to Webpack across the JavaScript ecosystem. They maintain the Vercel AI SDK, which is rapidly becoming the default integration layer for AI features in web applications. They maintain the Flags SDK, the Chat SDK, and a collection of packages under the @vercel namespace that are embedded in production applications across fintech, SaaS, DeFi, and enterprise tooling worldwide.

Critically, Next.js App Router manages your React packages for you automatically.6 When you use Next.js App Router, Vercel controls which version of React gets bundled into your application. You are not just trusting them as a host. You are trusting them as the curator of your framework, your bundler, your React version, and your deployment pipeline, simultaneously. That is an unusual degree of vertical integration for a single company to hold over a large portion of the web.

Hacker News, April 2026 โ€” comment on the breach thread

"At what point do we start asking questions about the concentration of trust in the web ecosystem? It's funny that at the engineering level we are continuously grilled in interviews about the single responsibility principle, meanwhile the industry's business model is to undermine the entirety of web standards and consolidate the web stack into a CLI."

The attacker who posted on BreachForums understood this precisely. The framing in their listing was not "we stole some API keys." It was: "Vercel owns Next.js, Turbo.js, and the entire @vercel sphere. You send one update with a payload, and it will hit every developer on the planet."7 Whether the tokens were real or not, the description of the blast radius was accurate.

This is not theoretical. It happened to Next.js just months before.

What makes this section more than just speculation is what happened in December 2025, four months before this breach. CVE-2025-55182 (React) and CVE-2025-66478 (Next.js) were disclosed simultaneously: critical unauthenticated remote code execution vulnerabilities affecting roughly 39% of cloud environments running React Server Components.8 A newly generated Next.js application, created with create-next-app, was immediately vulnerable without any developer mistakes required. A single new project, zero configuration, production build, exploitable.

The point is not that Vercel is uniquely bad at security. The point is that when you control a framework with that download footprint and that level of integration into a developer's stack, a single bad update, a single compromised token, a single malicious dependency injection, becomes a systemic risk for the entire ecosystem in a way that a hosting provider alone simply cannot be.

Vercel-maintained package / system Scale If compromised
next (Next.js framework) 520M downloads in 2025 / 6M weekly Catastrophic โ€” ecosystem-wide
Next.js App Router (manages React versions) Bundled with Next.js Catastrophic โ€” downstream React apps
ai (Vercel AI SDK) ~1.5M weekly, growing fast Severe โ€” all AI-enabled apps
@vercel/analytics ~2M weekly Severe โ€” data exfiltration at scale
Turbopack (replacing Webpack) Growing rapidly, build-time only Significant โ€” build artifact tampering
Vercel deployment platform itself Thousands of enterprise deployments Severe โ€” env vars, CI/CD pipelines
โš ๏ธ

Vercel confirmed no npm packages were compromised in this incident. They verified this in collaboration with GitHub, Microsoft, npm, and Socket.9 The table above represents the risk surface that existed. It is worth understanding what was at stake, even when the worst case did not materialise.

Meanwhile in March 2026, the axios npm package (70-100 million weekly downloads) was compromised via maintainer account hijacking, with malicious versions injecting a remote access trojan attributed to North Korean state-sponsored actors. Detection window: two to three hours.10 That one actually happened. The Vercel scenario was the same class of attack, applied to a target with far greater ecosystem reach.

Safe Security summed it up well in their post-incident analysis: "The platform sits inside the software delivery chain for an enormous number of organisations, which means a breach at Vercel creates potential downstream exposure that extends far beyond Vercel's own customer list."11

The honest question

What Can You Actually Do If Your Hoster Gets Hacked?

I want to sit with this question honestly, because the standard industry response ("rotate your keys, enable MFA") is correct but incomplete. It addresses what to do after you find out. It does not address the uncomfortable reality: if your provider's internal systems are compromised, you find out when they tell you. That is it. You have no earlier signal.

Vercel did the right thing. They notified affected customers, brought in Mandiant, engaged law enforcement. But the subset of customers who were affected had no way to detect this themselves. Applications running fine. Logs showing nothing unusual. The breach happened inside Vercel's systems, completely outside any individual customer's visibility surface.

โš ๏ธ

Vercel's CEO noted the attack appeared significantly accelerated by AI, citing the attackers' "surprising speed" and detailed knowledge of internal systems. That is not a threat you outrun with a checklist. It is a class of attacker operating faster than most monitoring was calibrated to detect.

With all that said, here is my take on the lessons this incident surfaced, based on what I have learned so far. I am not a security architect. But you do not need to be one to recognise patterns worth paying attention to, or to make better choices about what you hand keys to.

Lesson 01

Treat "non-sensitive" as a misleading label

"Non-sensitive" does not mean "public." It means "readable by your provider's internal systems if they are compromised." Any value that is a secret in any context should be flagged as sensitive regardless of how benign it feels. After this breach, Vercel changed the default to sensitive for all new variables. The existing ones are worth auditing.

The Azure SWA equivalent is worth understanding too. App settings on a Static Web App are readable by anyone with Contributor access to the resource or the resource group it sits in. That is not a breach scenario, it is just how Azure RBAC works by default. The mitigation is to not store secrets there at all. Route them through Key Vault instead. Give the app a managed identity with only Get permission on the specific secrets it needs. Give human access to the vault separately, scoped to the individual who manages it, not the whole team. Keep the blast radius small. If someone's Contributor role gets compromised, or if a colleague leaves and their access is not revoked quickly enough, they cannot read your database credentials because those credentials were never in the app settings to begin with. They are in a vault that requires its own explicit access grant.

Lesson 02

Know what your team is authorising access to

This breach did not start with a password being cracked. It started with a browser extension that had been granted "Allow All" read access to corporate files. One person on the team clicked Allow, and that single OAuth grant became the door the attacker walked through into Vercel's systems.

The point is not to slow development down or ban every productivity tool. But with every permission comes responsibility (to borrow from Spider-Man). Senior devs make this mistake too. It is not a seniority problem, it is a visibility problem. If nobody on the team knows what third-party tools have been granted access to shared systems like Google Workspace, GitHub orgs, or Azure DevOps, then nobody can assess whether those permissions are too broad or whether a compromised tool becomes everyone's problem.

Have some kind of trust framework, even a lightweight one. An approved list of extensions. A quarterly check of what OAuth grants exist on corporate accounts. Something that gives you confidence your team is not accidentally leaving doors wide open that you do not even know about.

Lesson 03

Pin your package versions and add supply chain monitoring

If Vercel's npm tokens had been used to publish malicious packages, teams using floating version ranges like ^14.0.0 would have pulled them in automatically on the next install. Pinned versions buy detection time. Tools like Socket.dev add continuous monitoring on published packages so you have a signal before you pull a poisoned update.

The trade-off is real though. Pinning means every update is manual. When a vulnerability drops on a package three levels deep in your dependency tree, you need to know about it quickly and act on it quickly, because you no longer have Dependabot or floating ranges doing that work for you automatically. You have to be a hawk. You need to watch advisories, understand which packages in your lock file are affected, and know when "update now" means now rather than next sprint. It makes dependency management more painful day-to-day. But the alternative, letting your package manager silently pull in whatever got published ten minutes ago, is exactly how supply chain attacks land without anyone noticing until it is too late.

Lesson 04

Build credential rotation into the routine, not just the incident response

Short-lived credentials limit the useful window for any stolen key. If your API keys and deployment tokens have been sitting unchanged for 18 months, a breach anywhere in your trust chain has 18 months of value to extract. Regular rotation is boring. That is exactly why nobody does it until something goes wrong.

Lesson 05 (the hard one)

Map your trust chain before you ship, not after you read someone else's breach report

This is for the vibe coders and the new devs and honestly for all of us: before deploying something, actually think about what you have authorised and what you have handed keys to. It does not need to be a formal threat model. It needs to be a deliberate moment of thinking about it. The architecture conversation is not the last step before launch. It should be one of the first.

Azure SWA context

Is Azure SWA Actually Safer? Not Immune. Just Differently Risky.

I use Azure Static Web Apps. Part of the reason is the Azure and Key Vault integration: secrets go in Key Vault, app settings reference them by name, nobody reads raw values from a dashboard. Not because Microsoft is immune to breaches. They are not. Nation-state actors have compromised Microsoft systems before. No cloud provider is breach-proof.

The difference that matters here is concentration risk. Microsoft does not also own the primary framework that six million developers run every week. A breach of Microsoft's internal systems is serious. A breach of the company that maintains Next.js, Turbopack, the AI SDK, the React version bundled into your app, and the deployment pipeline running a meaningful slice of the modern web simultaneously, is a structurally different category of risk. The problem with Vercel is not that they are bad at security. It is that their position in the ecosystem means any compromise has an unusually large potential blast radius.

Risk dimension Vercel Azure SWA Self-hosted
Ops overhead Zero Very low High
Package supply chain exposure Very high โ€” owns Next.js, React versioning etc. Medium Medium
Visibility if provider is breached None โ€” you wait for disclosure None โ€” you wait for disclosure More control, still limited
Secret isolation (native) Sensitive flag โ€” was opt-in before breach Key Vault โ€” explicit routing Your choice entirely
Ecosystem lock-in High โ€” Next.js / @vercel sphere Medium โ€” Azure tooling Low
Price for small projects Free tier, then paid Free tier, genuinely free Pay for the server
๐Ÿ’ก

The Azure SWA trade-off is real: The developer experience is not as polished as Vercel. Getting Key Vault integration right takes more deliberate effort than a "sensitive" toggle. You are trading some convenience for a different trust profile and more explicit secret isolation. Worth understanding as a deliberate choice rather than a default.

The closing argument

Nothing Is 100% Secure. The Goal Is Making Sure the Holes Never Line Up.

The Vercel breach is a textbook illustration of the Swiss Cheese Model, developed by psychologist James Reason to explain how accidents happen in complex systems. The idea: no single layer of defence is perfect. Each one has holes. Security works when you stack enough layers so the holes in each layer never align all the way through. When they do align, you get a catastrophic incident.

In this case the holes lined up perfectly. A Context.ai employee downloaded a Roblox script (hole one). That script installed Lumma Stealer (hole two). The attacker compromised the Context.ai support account (hole three). A Vercel employee had installed the extension and granted broad OAuth permissions without scoping them down (hole four). Those permissions were enough to pivot into Vercel's internal systems (hole five). Customer env vars were not marked sensitive by default (hole six). Any one of those holes being closed might have stopped the chain before it reached Vercel's customers.

"Every program and every privileged user of the system should operate using the least amount of privilege necessary to complete the job." Jerome Saltzer, MIT, 1974. Still the most useful sentence in security, fifty years later.

Microsoft formalises this in their Zero Trust framework, published openly on Microsoft Learn. Three core principles: Verify explicitly, Use least privilege access, and Assume breach.12 That third one is the one organisations consistently skip. "Assume breach" means: design your systems as though the attacker is already inside one layer, because eventually they will be. The question is how far they can move when they are. The Vercel employee's OAuth grant was not scoped to least privilege. It was "Allow All." That one decision in a browser extension installation dialogue was hole four in the chain.

// Microsoft Zero Trust โ€” three principles (learn.microsoft.com/security/zero-trust)

Verify explicitly โ€” Always authenticate based on all available data points.

Use least privilege โ€” Limit access with Just-In-Time, Just-Enough-Access, risk-based policies.

Assume breach โ€” Minimise blast radius. Segment access. Verify end-to-end encryption.

// The Context.ai extension was granted "Allow All." That is the opposite of least privilege.

// "Assume breach" would have meant designing that OAuth grant to limit lateral movement.

// One compromised token should not equal broad access to corporate infrastructure.

The period from March to April 2026 included the LiteLLM PyPI supply chain compromise, the axios npm hijacking attributed to North Korean state-sponsored actors, and this. Three major developer toolchain attacks in six weeks.13 This is not a run of bad luck. Attackers have worked out that developer tooling and CI/CD infrastructure are high-value targets with large blast radii and historically permissive trust models. The vibe coding boom that is bringing more people into software development faster than security culture can keep up with makes that attack surface wider, not narrower.

The Swiss Cheese model does not ask you to make any single layer perfect. It asks you to add enough layers that the holes do not align. Least privilege on every third-party integration. Sensitive flags on everything that is actually a secret. Regular credential rotation. Periodic OAuth audits. Package pinning with supply chain monitoring. And, for anyone building with AI coding tools: actually understanding the architecture of what you are shipping, not just prompting until it works. None of these are individually complicated. The hard part is doing all of them, consistently, even when the "Allow" button is right there and the deadline is tomorrow.

References and further reading

1. Vercel security bulletin, April 19-21, 2026. Updates published on April 19 and 20, including confirmation that npm packages were not compromised and that env var creation now defaults to sensitive. vercel.com/kb/bulletin
2. Hudson Rock analysis cited in Help Net Security, April 21, 2026. The Context.ai employee downloaded Roblox "auto-farm" scripts, a known Lumma Stealer delivery vector. Compromised data included Supabase, Datadog, Authkit credentials, and the support@context.ai account. helpnetsecurity.com
3. OX Security breach timeline and analysis documenting the full attack chain from Context.ai employee infection to Vercel infrastructure access. ox.security
4. Vercel's advisory documents the sensitive vs non-sensitive env var distinction. GitGuardian published a detailed breakdown on the implications for variables that carry real secrets but were never flagged. blog.gitguardian.com
5. Safe Security post-incident analysis: "Next.js, Vercel's flagship framework, recorded more than 520 million downloads in 2025 alone." Weekly download figure of ~6 million cited across Strobes and SecurityOnline.info coverage of the breach. safe.security
6. Next.js documentation on React version handling: "In App Router, Next.js manages your React packages for you." This means Next.js updates control which React version is bundled into downstream applications. See also the CVE-2025-66478 disclosure which required a Next.js update (not just a React update) to patch the underlying React vulnerability. github.com/vercel/next.js
7. Forum post text cited by SecurityOnline.info and BleepingComputer. Attribution to ShinyHunters is contested โ€” the group denied involvement to BleepingComputer. The supply chain risk analysis does not depend on attribution. securityonline.info
8. Upwind Security disclosure on CVE-2025-55182 (React) and CVE-2025-66478 (Next.js), December 2025. Critical unauthenticated RCE affecting approximately 39% of cloud environments running React Server Components. Newly generated create-next-app projects were immediately vulnerable in production without any developer error. upwind.io
9. Vercel bulletin update, April 20, 2026: "In collaboration with GitHub, Microsoft, npm, and Socket, our security team has confirmed that no npm packages published by Vercel have been compromised." vercel.com/kb/bulletin
10. Trend Micro analysis of the March 2026 axios npm compromise, CVE-2026-33634. Malicious versions 1.14.1 and 0.30.4 injected a dependency containing a cross-platform RAT. Attributed to Sapphire Sleet (North Korean state-sponsored). Detection window: 2-3 hours. trendmicro.com
11. Safe Security post-incident TPRM analysis. safe.security
12. Microsoft. "What is Zero Trust?" Microsoft Learn. The three core principles and the NIST definition of least privilege: "The principle that a security architecture should be designed so that each entity is granted the minimum system resources and authorizations that the entity needs to perform its function." learn.microsoft.com/security/zero-trust
13. Trend Micro documented the March-April 2026 cluster of supply chain attacks: LiteLLM PyPI compromise (March 24), axios npm hijacking, and Vercel breach (April 19). Characterised as convergent discovery of structural weaknesses in developer credential storage rather than isolated events. trendmicro.com