惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Proofpoint News Feed
U
Unit 42
V
Visual Studio Blog
D
DataBreaches.Net
F
Fortinet All Blogs
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
The GitHub Blog
The GitHub Blog
Y
Y Combinator Blog
月光博客
月光博客
大猫的无限游戏
大猫的无限游戏
T
The Blog of Author Tim Ferriss
GbyAI
GbyAI
博客园 - 叶小钗
Blog — PlanetScale
Blog — PlanetScale
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
MongoDB | Blog
MongoDB | Blog
The Cloudflare Blog
云风的 BLOG
云风的 BLOG
D
Docker
G
Google Developers Blog
罗磊的独立博客
博客园 - 三生石上(FineUI控件)
小众软件
小众软件
S
SegmentFault 最新的问题

Aikido Security's Blog

Axios CVE-2026-40175: a critical bug that’s… not exploitable GlassWorm goes native: New Zig dropper infects every IDE on your machine Aikido Attack finds multiple 0-days in Hoppscotch The cybersecurity doomerism around Mythos doesn't match what we see on the ground axios compromised on npm: maintainer account hijacked, RAT deployed Popular telnyx package compromised on PyPI by TeamPCP Aikido × Lovable: Vibe, Fix, Ship CanisterWorm Gets Teeth: TeamPCP's Kubernetes Wiper Targets Iran TeamPCP deploys CanisterWorm on NPM following Trivy compromise Security testing is validating software that no longer exists Aikido Recognized by Frost & Sullivan with the 2026 Customer Value Leadership Award in ASPM GlassWorm Hides a RAT Inside a Malicious Chrome Extension fast-draft Open VSX Extension Compromised by BlokTrooper Glassworm Strikes Popular React Native Phone Number Packages Glassworm Is Back: A New Wave of Invisible Unicode Attacks Hits Hundreds of Repositories How Security Teams Fight Back Against AI-Powered Hackers Introducing Betterleaks, an open source secrets scanner by the author of Gitleaks Trump’s 2026 cybersecurity strategy: From compliance to consequence How does AI pentesting work with compliance? What continuous pentesting actually requires Rare Not Random: Using Token Efficiency for Secrets Scanning Persistent XSS/RCE using WebSockets in Storybook’s dev server Why Determinism Is Still a Necessity in Security WAF vs. RASP vs. ADR Introducing Aikido Infinite: A new model of self-securing software How Aikido secures AI pentesting agents by design Astro Full-Read SSRF via Host Header Injection How to Get Your Board to Care About Security (Before a Breach Forces the Issue) What is Slopsquatting? The AI Package Hallucination Attack Already Happening Top 6 Wiz Code Alternatives
SvelteSpill: A Cache Deception Bug in SvelteKit + Vercel
Jorian Woltjer · 2026-02-19 · via Aikido Security's Blog

SvelteKit is a popular full-stack JavaScript framework, and Vercel is its most common deployment platform. What if we told you that all apps built using this combination were vulnerable to attackers reading responses from any route of other signed-in users?

Well, it’s true. This attack vector, called cache deception, is exactly what one of the AI agents found and reported to us while we were testing Aikido Attack. And while initially skeptical, we retraced its steps and found we could reproduce the vulnerability perfectly. We quickly notified Vercel, and the vulnerability has now been automatically fixed for all users.

Note: The issue can be viewed in Aikido's Intel database and has the reserved CVE number of: CVE-2026-27118. We also found a separate issue that allows for Denial of Service in an experimental feature on SvelteKit. This has also been disclosed and fixed.

Quick Summary

The __pathname query parameter in SvelteKit's Vercel adapter can override the path from anywhere. On Vercel, every file under /_app/immutable/ has different Cache-Control: headers so it can be cached. By prefixing this with a fake path and rewriting it to contain sensitive content, the response will be forcefully cached, allowing an attacker to retrieve it by visiting the same URL without cookies.

Proof of Concept URL:

https://example.vercel.app/_app/immutable/x?__pathname=/api/session

Discovery

We will tell this story from the perspective of the AI pentest agent that found the vulnerability, starting from the initial gadget to full exploitation, and we’ll talk about some interesting ideas along the way. Embrace your inner robot and let’s get researching!

If you read the SvelteKit source code, you’ll come across some “adapters”, which are the middleware between a hosting platform like Vercel and the framework SvelteKit. This makes it possible to apply some special rules to the request & response required for the platform’s internals. Vercel has implemented the following in serverless.js:

const DATA_SUFFIX = '/__data.json';

fetch(request) {
    // If this is an ISR request, the requested pathname is encoded
    // as a search parameter, so we need to extract it
    const url = new URL(request.url);
    let pathname = url.searchParams.get('__pathname');

    if (pathname) {
        // Optional routes' pathname replacements look like `/foo/$1/bar` which means we could end up with an url like /foo//bar
        pathname = pathname.replace(/\/+/g, '/');

        url.pathname = pathname + (url.pathname.endsWith(DATA_SUFFIX) ? DATA_SUFFIX : '');
        url.searchParams.delete('__pathname');

        request = new Request(url, request);
    }

    return server.respond(request, {
        getClientAddress() {
            return /** @type {string} */ (request.headers.get('x-forwarded-for'));
        }
    });
}

We can read “If this is an ISR request, the requested pathname is encoded as a search parameter.” The code takes this pathname variable (from the ?__pathname= query parameter) and rewrites the url.pathname with it. The request ignores the original url and just uses this __pathname instead.

But there don’t seem to be any checks regarding these Incremental Static Regeneration (ISR) requests, so do all requests support this parameter?

The answer is yes, and that’s exactly where the vulnerability lies! Any path can be overridden to any other path with just a query parameter. A simple test like /?__pathname=/404 would indeed show a 404 error instead of the homepage.

This may just sound like a strange feature. Why would it be dangerous? Well, it’s not, until caching gets involved.

Cache Poisoning?

If we can rewrite any path to point to any other resource, what happens if that poisoned resource gets cached? This was our first idea as well. If we check the source code of any SvelteKit app, you’ll see something like:


import("./_app/immutable/entry/start.CLO1Dlt2.js"),	
import("./_app/immutable/entry/app.kQF6jJr8.js")

The path /_app/immutable/entry/start.CLO1Dlt2.js returns some JavaScript to execute, and looking at the response, Cache-Control: headers tell us it is indeed cached. This is expected for static resources:

Age: 618
Cache-Control: public, immutable, max-age=31536000
X-Vercel-Cache: HIT

If we could use our ?__pathname= parameter to rewrite the request to point to some attacker-controlled path like a file upload, and it would still be cached under the same plain /_app/immutable/entry/start.CLO1Dlt2.js path that every user loads, we’d have XSS on every user. Let’s see what happens when we add this query parameter to our request:

GET /_app/immutable/start.CLO1Dlt2.js?__pathname=/ HTTP/2
Host: example.vercel.app

In the response, we receive good and bad news from the headers:

Age: 935
Cache-Control: public, immutable, max-age=31536000
X-Vercel-Cache: HIT

The Age: has increased by however long it took to write the above paragraph, and the HIT signifies that with our query parameter added, the same cache entry is hit as the one everybody loads. But at the same time, that means the old JavaScript content is also returned, not the content on our rewritten path. If that’s the case, might we be able to flush the cache and then be the first to request it so our payload can be cached instead?

Unfortunately not. The Vercel platform is more complicated because of its serverless architecture, and it doesn’t actually even hit the adapter code for such a static resource. This is because static assets are cached and returned on a higher layer, so we will never be able to poison them.

In this case, Vercel itself is the only vulnerable platform, so we can’t find other exploitable scenarios. We hit a dead end.

On to the next problem with web caching: cache deception. In this lesser-known technique, an attacker redirects a victim to some sensitive page that they can retrieve with their cookies. If the cache stores this page without considering which user requested it, the attacker can later visit the same URL and see the victim's private data from the cache.  The issue is that cache saves responses based only on the URL, ignoring that different users with different login cookies should see different content.

Applying this idea to our ?__pathname= gadget, we can make our URL look like it points to a static path, but actually points to sensitive content. The caching layer may trigger on that static-looking path and add explicit Cache-Control: headers and override the private response.

While some cache criteria are documented, our investigation showed more rules. One we’re already familiar with: paths starting with /_app/immutable/. It turns out not only are the expected static files cacheable under this prefix, but any 200 OK response. To avoid the already-generated assets, we can initially point to a fake asset. Then rewrite it to any sensitive path, let’s say /api/session:

https://example.vercel.app/_app/immutable/x?__pathname=/api/session

And there we have our final payload. Visiting this link as a logged-in victim will send a request like the following:

GET /_app/immutable/x?__pathname=/api/session HTTP/2
Host: example.vercel.app
Cookie: auth=...

SvelteKit’s Vercel adapter rewrites the pathname to /api/session, and gets handled by the app. The auth= cookie is verified, and their session token is returned:

HTTP/2 200 OK
Age: 0
Cache-Control: public, immutable, max-age=31536000
...
Server: Vercel
X-Vercel-Cache: MISS
Content-Length: 16

{"token":"1337"}

While the Cache-Control: header would normally say max-age=0 for this endpoint, the caching layer of Vercel forcefully enables caching because of the /_app/immutable/ prefix.

Once the attacker knows a victim has been redirected, they can request the same URL themselves, without any cookies:

GET /_app/immutable/x?__pathname=/api/session HTTP/2
Host: example.vercel.app

They receive the same response as a HIT now, and can read the victim’s token.

HTTP/2 200 OK
Age: 22
Cache-Control: public, immutable, max-age=31536000
...
Server: Vercel
X-Vercel-Cache: HIT
Content-Length: 16

{"token":"1337"}

Using cache busters (unique dummy paths) and checking after redirecting, this could have been exploited on a large scale. Since this vulnerability is just part of the base Sveltekit, any SvelteKit website on Vercel that uses cookies for authentication would allow arbitrary responses to be retrieved.

The aftermath

We quickly reported the issue to Vercel, who came up with a fix to forcefully return 404 on any /_app/immutable/ path, and to strip the __pathname parameter. Since they control their whole platform, this resolves the issue automatically for all users, no manual patch required.

One big takeaway from this vulnerability is that caching is always tricky. Simple rules, like a prefix match, can be taken advantage of by unexpected platform features you didn’t even implement.

That’s why pentesting can be so useful. Issues like this would be hard to discover by code alone, but through a real deployment, hidden rules can be found and exploited. Aikido’s AI pentest can detect cache poisoning and cache deception attacks automatically, like it found this issue.

Key Takeaways

  • On January 20, 2026, Aikido’s AI pentest system flagged something interesting in SvelteKit applications deployed on Vercel. 
  • We confirmed it was a cache deception vulnerability affecting default configurations. 
  • No misconfiguration required. Just SvelteKit + Vercel doing what they're supposed to do.
  • Impact: Authenticated responses can be cached and exposed to other users.
  • Any SvelteKit app running on Vercel with protected endpoints may be affected.

How to check if you're affected

Using Aikido:

If you are an Aikido user, check your central feed. You can see the issue in Aikido Intel here. Tip: Aikido rescans your repos nightly, though we recommend triggering a full rescan as well.

If you are not yet an Aikido user, set up an account and connect your repos. Our proprietary malware coverage is included in the free plan (no credit card required).

Aikido's AI pentest and web security scanning detect cache deception flows and unsafe rewrite behavior automatically.

Fix status

We disclosed this to Vercel on January 21, 2026.

Timeline

  • January 20, 2026: Aikido Security identified the vulnerability, built working PoC
  • January 21, 2026: Responsible disclosure to Vercel
  • January 23, 2026: Report triaged
  • February 9, 2026: Vercel confirms the report and starts working on a fix
  • February 19, 2026: Vercel has fixed the vulnerability for all users, and advisory is published (GHSA-9pq4-5hcf-288c). The issue can be viewed in Aikido's Intel database and has the reserved CVE number of: CVE-2026-27118.

We also found a separate issue that allows for Denial of Service in an experimental feature on SvelteKit. This has also been disclosed and fixed.