Introducción
Hoppscotch es un ecosistema de desarrollo de API de código abierto, similar a Postman, con más de 100 000 usuarios mensuales. Hace dos semanas, configuramos una instancia autohospedada y ejecutamos nuestros agentes de pruebas de penetración de IA en ella. Detectaron dos vulnerabilidades de gravedad alta y una de gravedad media, todas presentes en versiones hasta la 2026.2.1 inclusive, y todas corregidas en la versión 2026.3.0:
- Apropiación de cuentas mediante redireccionamiento abierto, lo que permite que los tokens de autenticación se transfieran a un dominio malicioso, lo que permite al atacante autenticarse como la víctima.
- XSS almacenado a través del servidor simulado, en el que el código JavaScript inyectado a través de un encabezado de respuesta se ejecuta en el contexto de la aplicación Hoppscotch, lo que permite al atacante acceder en lectura y escritura a todo lo que la víctima puede ver.
- control de acceso roto el flujo de solicitudes, que permite a un usuario de un equipo insertar una solicitud en la pila de un equipo diferente. Si un miembro del equipo de destino la ejecuta, se pueden sustraer credenciales y claves de API.
Las tres vulnerabilidades se comunicaron de forma responsable y ya se han solucionado.
Nota: Accidentalmente agrupamos el problema de XSS y el de control de acceso en un solo informe. Aunque el texto del aviso se refiere al XSS, las capturas de pantalla muestran en realidad el fallo de control de acceso, lo que da lugar a dos avisos que abarcan tres problemas distintos.
Remediación
Actualiza las instancias autohospedadas de Hoppscotch a la versión 2026.3.0 o superior.
Las vulnerabilidades detectadas se han añadido a la base de datos de Aikido Intel:
- https://intel.aikido.dev/cve/AIKIDO-2026-10462
- https://intel.aikido.dev/cve/AIKIDO-2026-10463
- https://intel.aikido.dev/cve/AIKIDO-2026-10461
Redireccionamiento abierto que da lugar a la apropiación de cuentas
Aviso: GHSA-7fg7-wx5q-6m3v
CVSS: 8,5 (Alto)
Affected versions: Hoppscotch <= 2026.2.1
Versiones actualizadas: 2026.3.0
Hoppscotch cuenta tanto con una interfaz web como con una aplicación de escritorio. Para autenticarse en la aplicación de escritorio, se abre la siguiente URL en el navegador:
http://<hoppscotch-instance>/device-login/?redirect_uri=http%3A%2F%2Flocalhost%2Fdevice-token
La instancia de Hoppscotch utiliza el parámetro de consulta «redirect_uri» para enviar los tokens de sesión. Ahí es donde reside la vulnerabilidad. El back-end presentaba el siguiente error de validación en la URI:
if (!redirectUri || !redirectUri.startsWith('http://localhost')) {
throwHTTPErr({
…
})
}
El código comprueba si la URI comienza por http://localhost, pero no tiene en cuenta que los dominios maliciosos como http://localhost.evil.com también supera esta comprobación. Por lo tanto, si una víctima navega hasta:http://<hoppscotch-instance>/device-login/?redirect_uri=http%3A%2F%2Flocalhost.evil.com%2Fdevice-token
Hoppscotch enviaría sus tokens de sesión a http://localhost.evil.com. Desde localhost es un subdominio del atacante evil.com dominio, en lugar de dirigirse a localhost, la solicitud se envía al servidor del atacante. A continuación, este podría utilizar esos tokens para autenticarse como la víctima.
Nuestros agentes detectaron el problema en el código fuente y lo verificaron configurando un listener en una IP pública y creando una carga útil utilizando sslip.io. Mediante el uso del URI http://localhost.<attacker-ip>.sslip.io/, la carga útil logró eludir la comprobación «startsWith» al tiempo que obligaba al navegador a resolver la dirección en el servidor del atacante. Una vez que la víctima se autenticó, los tokens de sesión confidenciales se filtraron directamente a nuestro listener, lo que confirmó que era posible una apropiación total de la cuenta.
La siguiente solicitud de incorporación de cambios resolvió la vulnerabilidad mediante el uso de un analizador de URL adecuado: https://github.com/hoppscotch/hoppscotch/pull/6012
XSS almacenado a través de un servidor simulado
Advisory: GHSA-wj4r-hr4h-g98v
CVSS: 8.5 (High)
Affected versions: Hoppscotch <= 2026.2.1
Patched versions: 2026.3.0
Hoppscotch incluye una función de servidor simulado que ofrece respuestas definidas por el usuario a partir de direcciones URL bajo /mock/<subdomain>/. El backend envía estas respuestas desde el mismo origen que la aplicación Hoppscotch, lo que significa que se puede utilizar cross-site scripting el MockServer para extraer y modificar datos de los usuarios.
Para inyectar una carga útil XSS, los agentes de pruebas de penetración de Aikido eludieron las restricciones de la interfaz de usuario enviando una solicitud a la API GraphQL que establece el Tipo de contenido encabezado de respuesta a text/html. Esto no era posible a través de la interfaz de usuario.
Ejemplo de cuerpo de la solicitud:
{
"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\":[]}}}}"
}
}El XSS se activa en cuanto el usuario visita el punto final de la API simulada. Por ejemplo:
http://<hoppscotch-instance>/mock/-v9juLVaiMnJa/v2/pet/findByStatus

Para comprobarlo, los agentes de IA insertaron una carga útil «console.log» en el cuerpo de la respuesta a través de la API de GraphQL, eludiendo así las restricciones de tipo de contenido de la interfaz de usuario. Al acceder al punto final simulado específico, el navegador ejecutó el script y los agentes capturaron con éxito la salida registrada en la consola.
La siguiente solicitud de incorporación de cambios (PR) solucionó la vulnerabilidad mediante la incorporación de medidas de saneamiento y el uso de un entorno aislado (sandbox) con una Política de Seguridad de Contenidos:
https://github.com/hoppscotch/hoppscotch/pull/6006
Control de acceso: transferir solicitudes a otro equipo
Aviso: GHSA-wj4r-hr4h-g98v
CVSS: 6,0 (medio)
Affected versions: Hoppscotch <= 2026.2.1
Versiones actualizadas: 2026.3.0
Hoppscotch permite a los usuarios mover o reordenar solicitudes entre colecciones utilizando el solicitud de traslado Mutación de GraphQL. Los agentes descubrieron que el backend no validaba correctamente los permisos de la colección de destino, lo que permitía a un atacante «inyectar» sus propias solicitudes en una colección perteneciente a otro equipo.
La vulnerabilidad se encuentra en la lógica de validación del backend: aunque verifica la solicitud de origen, omite la comprobación del equipo de destino si el nextRequestID está configurado en null. Al proporcionar el destCollID del equipo de la víctima y dejando el nextRequestID Si está vacío, un atacante puede hacer llegar una solicitud más allá de los límites del inquilino:
{
"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
}
}
Esto puede afectar a la confidencialidad si un miembro del equipo afectado ejecuta, sin saberlo, la solicitud inyectada o la colección principal. Si lo hace, en el caso de solicitudes que hereden encabezados de autorización o que contengan marcadores de posición variables —por ejemplo, claves API—, los datos confidenciales podrían filtrarse al servidor del atacante.
A continuación se muestran los registros de los agentes que identificaron la vulnerabilidad:
Análisis de las relaciones entre teamID - Me pregunto si las solicitudes pueden pertenecer a colecciones de diferentes equipos sin cambiar el teamID. Esto podría infringir la restricción de clave externa si la colección está vinculada a otro equipo. Probablemente, el modelo TeamRequest conecta las colecciones por ID sin exigir estrictamente que teamID coincida con collection.teamID. En createTeamRequest, sí comprueban que el ID del equipo coincida. Sin embargo, si al mover una solicitud solo se actualiza collectionID sin alterar teamID, necesito consultar el esquema de Prisma para aclarar cómo están estructuradas estas relaciones. Busquemos el esquema en el directorio correspondiente.
Identificación de problemas de control de acceso - Me doy cuenta de que el guard solo comprueba si un usuario es miembro del equipo asociado al requestID e ignora los permisos del equipo de la colección de destino. La función moveRequest está protegida por GqlRequestTeamMemberGuard para roles como Editor o Propietario, pero no incluye comprobaciones de GqlCollectionTeamMemberGuard en destCollID. Esto significa que un editor del Equipo A podría mover una solicitud a la colección del Equipo B sin ser miembro, lo que crea una grave vulnerabilidad en el control de acceso.
Revisión del manejo de solicitudes - Necesito confirmar mi comprensión de findRequestAndNextRequest y reorderRequests. En findRequestAndNextRequest, se comprueba que la solicitud exista en srcCollID. Si se proporciona nextRequestID, se garantiza que nextRequest pertenezca a la misma colección y equipo. Sin embargo, si nextRequestID es nulo, se omite la comprobación de la propiedad del equipo de destCollID.
En reorderRequests, se bloquea por request.teamID para las colecciones src y dest. Pero si destCollID pertenece a otro equipo, sigue adelante con las actualizaciones sin garantizar las comprobaciones de equipo adecuadas, lo que podría dar lugar a problemas.
La siguiente solicitud de incorporación de cambios (PR) solucionó la vulnerabilidad añadiendo una comprobación de autorización:
https://github.com/hoppscotch/hoppscotch/pull/6006
El mérito es de TristanInSec, quien también había identificado por su cuenta la vulnerabilidad XSS.
Más información sobre nuestra investigación sobre pruebas de penetración con IA:
- SvelteSpill: un fallo de engaño de caché en SvelteKit + Vercel
- PromptPwnd: vulnerabilidades de inyección de comandos en GitHub Actions mediante agentes de IA
Descubre más sobre cómo funcionan nuestros agentes de pruebas de penetración basados en IA:
- Cómo garantizamos la seguridad de nuestros agentes de IA desde el diseño:
- pentesting autónomo entre pentesting autónomo y las manuales

