Aikido

SvelteSpill: Ein Cache-Deception-Bug in SvelteKit + Vercel

Verfasst von
Jorian Woltjer

SvelteKit ist ein beliebtes Full-Stack-JavaScript-Framework, und Vercel ist die gängigste Bereitstellungsplattform dafür. Was wäre, wenn wir Ihnen sagen würden, dass alle mit dieser Kombination erstellten Apps anfällig dafür sind, dass Angreifer Antworten von beliebigen Routen anderer angemeldeter Benutzer lesen können?

Nun, es ist wahr. Dieser Angriffsvektor, der als „Cache Deception“ bezeichnet wird, ist genau das, was einer der KI-Agenten gefunden und uns gemeldet hat, während wir Aikido getestet haben. Obwohl wir zunächst skeptisch waren, haben wir seine Schritte zurückverfolgt und festgestellt, dass wir die Schwachstelle perfekt reproduzieren konnten. Wir haben Vercel umgehend benachrichtigt, und die Schwachstelle wurde nun für alle Benutzer automatisch behoben.

Hinweis: Die Problem kann in der Intel-DatenbankAikido und hat die reservierte CVE-Nummer: CVE-2026-27118. Wir haben außerdem ein separates Problem, das einen Denial-of-Service in einer experimentellen Funktion von SvelteKit ermöglicht. Auch dieses Problem wurde offengelegt und behoben.

Kurze Zusammenfassung

Der __Pfadname Der Abfrageparameter im Vercel-Adapter von SvelteKit kann den Pfad von überall überschreiben. Auf Vercel kann jede Datei unter /_app/unveränderlich/ hat verschiedene Cache-Kontrolle: Header, damit sie zwischengespeichert werden kann. Indem man ihr einen gefälschten Pfad voranstellt und sie so umschreibt, dass sie sensible Inhalte enthält, wird die Antwort zwangsweise zwischengespeichert, sodass ein Angreifer sie durch Aufrufen derselben URL ohne Cookies abrufen kann.

Proof-of-Concept-URL:

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

Erkennung

Wir werden diese Geschichte aus der Perspektive des KI-Pentest-Agenten erzählen, der die Schwachstelle entdeckt hat, angefangen vom ersten Gadget bis hin zur vollständigen Ausnutzung, und dabei einige interessante Ideen vorstellen. Lassen Sie Ihren inneren Roboter zum Vorschein kommen und lassen Sie uns mit der Forschung beginnen!

Wenn Sie den Quellcode von SvelteKit lesen, werden Sie auf einige „Adapter” stoßen, die als Middleware zwischen einer Hosting-Plattform wie Vercel und dem Framework SvelteKit fungieren. Dadurch ist es möglich, einige spezielle Regeln auf die für die Interna der Plattform erforderlichen Anfragen und Antworten anzuwenden. Vercel hat Folgendes implementiert: serverlos.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'));
        }
    });
}

Wir können lesen: „Wenn es sich um eine ISR-Anfrage handelt, wird der angeforderte Pfadname als Suchparameter codiert.“ Der Code nimmt diese Pfadnamensvariable (aus der ?__Pfadname= Abfrageparameter) und schreibt die url.Pfadname damit. Die Anfrage ignoriert die ursprüngliche URL und verwendet nur diese. __Pfadname stattdessen.

Es scheint jedoch keine Überprüfungen hinsichtlich dieser ISR- Anfragen (Incremental Static Regeneration) zu geben. Unterstützen also alle Anfragen diesen Parameter?

Die Antwort lautet ja, und genau darin liegt die Schwachstelle! Jeder Pfad kann mit nur einem Abfrageparameter zu einem anderen Pfad überschrieben werden. Ein einfacher Test wie /?__pathname=/404 würde tatsächlich einen 404-Fehler anstelle der Startseite anzeigen.

Das mag zunächst wie eine seltsame Funktion klingen. Warum sollte sie gefährlich sein? Nun, das ist sie auch nicht, solange kein Caching im Spiel ist.

Cache-Vergiftung?

Wenn wir jeden Pfad so umschreiben können, dass er auf eine andere Ressource verweist, was passiert dann, wenn diese vergiftete Ressource zwischengespeichert wird? Das war auch unsere erste Idee. Wenn wir den Quellcode einer beliebigen SvelteKit-App überprüfen, sehen wir etwa Folgendes:


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

Der Weg /_app/immutable/entry/start.CLO1Dlt2.js gibt JavaScript zur Ausführung zurück, und wenn man sich die Antwort ansieht, Cache-Kontrolle: Die Header zeigen uns, dass es tatsächlich zwischengespeichert ist. Dies ist bei statischen Ressourcen zu erwarten:

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

Wenn wir unsere ?__Pfadname= Parameter, um die Anfrage so umzuschreiben, dass sie auf einen vom Angreifer kontrollierten Pfad wie einen Datei-Upload verweist, und sie würde weiterhin unter dem gleichen Klartext zwischengespeichert werden. /_app/immutable/entry/start.CLO1Dlt2.js Pfad, den jeder Benutzer lädt, hätten wir XSS bei jedem Benutzer. Schauen wir uns an, was passiert, wenn wir diesen Abfrageparameter zu unserer Anfrage hinzufügen:

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

In der Antwort erhalten wir gute und schlechte Nachrichten aus den Headern:

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

Der Alter: hat sich um die Zeit erhöht, die zum Schreiben des obigen Absatzes benötigt wurde, und die HIT bedeutet, dass mit unserem hinzugefügten Abfrageparameterwird derselbe Cache-Eintrag getroffen wie der, den alle laden. Das bedeutet aber gleichzeitig, dass auch der alte JavaScript-Inhalt zurückgegeben wird und nicht der Inhalt auf unserem umgeschriebenen Pfad. Wenn das der Fall ist, könnten wir dann vielleicht den Cache leeren und dann als Erste eine Anfrage stellen, damit unser Die Nutzlast kann stattdessen zwischengespeichert werden?

Leider nein. Die Vercel-Plattform ist aufgrund ihrer serverlosen Architektur komplizierter und greift bei solchen statischen Ressourcen nicht einmal auf den Adaptercode zu. Das liegt daran, dass statische Assets zwischengespeichert und auf einer höheren Ebene zurückgegeben werden, sodass wir sie niemals manipulieren können.

In diesem Fall ist Vercel selbst die einzige anfällige Plattform, sodass wir keine weiteren ausnutzbaren Szenarien finden können. Wir sind in einer Sackgasse gelandet.

Cache-Täuschung!

Weiter zum nächsten Problem beim Web-Caching: Cache-Täuschung. Bei dieser weniger bekannten Technik leitet ein Angreifer ein Opfer auf eine sensible Seite um, die er mit seinen Cookies abrufen kann. Wenn der Cache diese Seite speichert, ohne zu berücksichtigen, welcher Benutzer sie angefordert hat, kann der Angreifer später dieselbe URL aufrufen und die privaten Daten des Opfers aus dem Cache einsehen. Das Problem besteht darin, dass der Cache Antworten nur anhand der URL speichert und dabei ignoriert, dass verschiedene Benutzer mit unterschiedlichen Login-Cookies unterschiedliche Inhalte sehen sollten.

Anwendung dieser Idee auf unser ?__Pfadname= Gadget, wir können unsere URL erstellen aussehen wie Es verweist auf einen statischen Pfad, führt jedoch tatsächlich zu sensiblen Inhalten. Die Caching-Ebene kann diesen statisch aussehenden Pfad auslösen und explizit hinzufügen. Cache-Kontrolle: Header und überschreiben Sie die private Antwort.

Während einige Cache-Kriterien sind dokumentiert, unsere Untersuchung ergab jedoch weitere Regeln. Eine davon ist uns bereits bekannt: Pfade, die mit /_app/unveränderlich/Es stellt sich heraus, dass nicht nur die erwarteten statischen Dateien unter diesem Präfix zwischengespeichert werden können, sondern auch jegliche 200 OK-Antwort. Um die bereits generierten Assets zu vermeiden, können wir zunächst auf ein gefälschtes Asset verweisen. Dann schreiben wir es in einen beliebigen sensiblen Pfad um, sagen wir /api/session:

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

Und damit haben wir unsere endgültige Nutzlast. Wenn Sie diesen Link als angemeldetes Opfer aufrufen, wird eine Anfrage wie die folgende gesendet:

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

Der Vercel-Adapter von SvelteKit schreibt den Pfadnamen um in /api/sessionund wird von der App verarbeitet. Die auth= Das Cookie wird überprüft und das Sitzungstoken wird zurückgegeben:

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

{"token":"1337"}

Während die Cache-Kontrolle: Die Kopfzeile würde normalerweise lauten max-age=0 Für diesen Endpunkt aktiviert die Caching-Ebene von Vercel zwangsweise das Caching aufgrund der /_app/unveränderlich/ Präfix.

Sobald der Angreifer weiß, dass ein Opfer umgeleitet wurde, kann er selbst dieselbe URL ohne Cookies anfordern:

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

Sie erhalten dieselbe Antwort wie ein HIT jetzt und kann das Token des Opfers lesen.

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

{"token":"1337"}

Durch die Verwendung von Cache-Buster (eindeutige Dummy-Pfade) und die Überprüfung nach der Umleitung hätte dies in großem Umfang ausgenutzt werden können. Da diese Schwachstelle nur ein Teil des Basis-Sveltekit ist, würde jede SvelteKit-Website auf Vercel, die Cookies für die Authentifizierung verwendet, das Abrufen beliebiger Antworten ermöglichen.

Die Nachwirkungen

Wir haben das Problem umgehend an Vercel gemeldet, die daraufhin eine Lösung gefunden haben. eine Lösung zwangsweise 404 für alle /_app/unveränderlich/ Pfad und zum Entfernen der __Pfadname Parameter. Da sie ihre gesamte Plattform kontrollieren, wird das Problem für alle Benutzer automatisch gelöst, ohne dass ein manueller Patch erforderlich ist.

Eine wichtige Erkenntnis aus dieser Sicherheitslücke ist, dass Caching immer heikel ist. Einfache Regeln, wie eine Präfixübereinstimmung, können durch unerwartete Plattformfunktionen ausgenutzt werden, die Sie gar nicht implementiert haben.

Deshalb kann Pentesting so nützlich sein. Probleme wie dieses wären allein anhand des Codes schwer zu entdecken, aber durch eine echte Bereitstellung können versteckte Regeln gefunden und ausgenutzt werden. Der KI-PentestAikido kann Cache-Poisoning- und Cache-Deception-Angriffe automatisch erkennen, so wie er dieses Problem gefunden hat.

Wichtige Erkenntnisse

  • Am 20. Januar 2026 hat das KI-Pentest-System Aikidoetwas Interessantes in SvelteKit-Anwendungen entdeckt, die auf Vercel bereitgestellt wurden. 
  • Wir haben bestätigt, dass es sich um eine Cache-Täuschungsschwachstelle handelt, die sich auf Standardkonfigurationen auswirkt. 
  • Keine Fehlkonfiguration erforderlich. Nur SvelteKit + Vercel, die das tun, was sie tun sollen.
  • Auswirkung: Authentifizierte Antworten können zwischengespeichert und anderen Benutzern zugänglich gemacht werden.
  • Jede SvelteKit-App, die auf Vercel mit geschützten Endpunkten läuft, kann betroffen sein.

So überprüfen Sie, ob Sie betroffen sind

Aikido anwenden:

Wenn Sie Aikido , überprüfen Sie Ihren zentralen Feed. Das Problem wird hier in Aikido angezeigt. Tipp: Aikido Ihre Repositories jede Nacht Aikido , wir empfehlen jedoch, zusätzlich einen vollständigen Rescan durchzuführen.

Wenn Sie noch kein Aikido-Benutzer sind, richten Sie ein Konto ein und verbinden Sie Ihre Repos. Unsere proprietäre Malware-Abdeckung ist im kostenlosen Plan enthalten (keine Kreditkarte erforderlich).

Die KI-Penetrationstests und Web-Sicherheitsscans Aikido erkennen automatisch Cache-Deception-Flows und unsichere Umschreibeverhalten.

Status reparieren

Wir haben dies Vercel am 21. Januar 2026 mitgeteilt.

Zeitplan

  • 20. Januar 2026: Aikido hat die Schwachstelle identifiziert und einen funktionierenden PoC erstellt.
  • 21. Januar 2026: Verantwortungsvolle Offenlegung gegenüber Vercel
  • 23. Januar 2026: Bericht sortiert
  • 9. Februar 2026: Vercel bestätigt den Bericht und beginnt mit der Arbeit an einer Lösung.
  • 19. Februar 2026: Vercel hat die Sicherheitslücke für alle Benutzer behoben und eine Empfehlung veröffentlicht (GHSA-9pq4-5hcf-288c). Das Problem kann in der Aikido Intel-Datenbank und hat die reservierte CVE-Nummer: CVE-2026-27118.

Wir haben auch ein separates Problem, das einen Denial-of-Service in einer experimentellen Funktion von SvelteKit ermöglicht. Auch dieses Problem wurde offengelegt und behoben.

Teilen:

https://www.aikido.dev/blog/sveltespill-cache-deception-sveltekit-vercel

Abonnieren Sie Bedrohungs-News.

Starten Sie noch heute, kostenlos.

Kostenlos starten
Ohne Kreditkarte

Sicherheit jetzt implementieren

Sichern Sie Ihren Code, Ihre Cloud und Ihre Laufzeit in einem zentralen System.
Finden und beheben Sie Schwachstellen schnell und automatisch.

Keine Kreditkarte erforderlich | Scan-Ergebnisse in 32 Sek.