Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
pasteguard-PoC — PoC — abuso de proxy de origen cruzado de claves API de proveedores configuradas en PasteGuard (GHSA-q94x-p9rc-q89f, CVE-2026-86998, CVSS 7.6). | Kitploit
Herramientas/GitHubGitHub/squeeze440/pasteguard-poc
Análisis de VulnerabilidadesExplotaciónSeguridad WebPruebas de PenetraciónPapers e InvestigaciónSeguridad de APIs
GitHubsqueeze440/pasteguard-poc

pasteguard-PoC

PoC — abuso de proxy de origen cruzado de claves API de proveedores configuradas en PasteGuard (GHSA-q94x-p9rc-q89f, CVE-2026-86998, CVSS 7.6).

Ver Repositorio
hace 7 díasAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

PasteGuard: aviso de seguridad

Estado del CVE: solicitado, pendiente de asignación. Este hallazgo se publica como GHSA-q94x-p9rc-q89f. Tras la asignación del CVE, este repositorio se renombra CVE-YYYY-NNNNN-pasteguard-PoC y este banner se reemplaza por el enlace del CVE.

InvestigadorDostxodjayev Abdullox (@squeeze440)
AvisoGHSA-q94x-p9rc-q89f
CVSS 3.17.6 (Alto)
DebilidadCWE-352, CWE-942

Resumen: La falta de protección CORS/CSRF en las rutas del proxy LLM en PasteGuard 0.9.1 permite a un atacante remoto (cualquier sitio web que visite el navegador del operador, o cualquier host en la red local) desencadenar solicitudes autenticadas a la API de OpenAI/Anthropic configurada por el operador usando la clave de API de respaldo del lado del servidor de PasteGuard, y leer la respuesta, mediante un fetch() de origen cruzado a /openai/v1/chat/completions (y su hermana /anthropic/v1/messages).

Producto: PasteGuard (github.com/sgasser/pasteguard)

Versión probada: commit 100718191499c52934f3b2ccca72ca16373fb765 (2026-07-30), versión de package.json 0.9.1

CVSS v3.1 estimado: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:H — 7.6 (Alto)

  • UI:R — el operador debe tener su navegador abriendo una página (cualquier página, en cualquier sitio) mientras PasteGuard está en ejecución; no se necesita ninguna otra interacción.
  • C:L / I:L — el JS del propio atacante solo lee la respuesta a su propio prompt elegido por el atacante (no las conversaciones previas ni los datos del panel del operador, que están correctamente excluidos de CORS), pero esto aún confirma/usa una cuenta activa con fondos y contamina el registro de uso/auditoría de la cuenta bajo la identidad del operador.
  • A:H — el impacto realista e ilimitado: una página del atacante puede repetir esta solicitud indefinidamente, generando uso facturado real contra la cuenta/cuota del proveedor del operador (drenaje financiero, posible agotamiento del límite de velocidad o marcas de abuso del lado del proveedor) sin limitación de velocidad ni verificación de origen que lo impida.
  • S:U — el impacto permanece dentro del mismo límite de confianza (la credencial configurada del propio proxy es la que se usa); no se cruza ninguna autoridad de seguridad separada.

Detalles:

La capa HTTP de PasteGuard aplica una política CORS permisiva con comodín a todas las rutas excepto el panel:

  • src/index.ts:40-45 — const corsMiddleware = cors(); (el cors() de Hono sin opciones usa por defecto Access-Control-Allow-Origin: *) se aplica mediante app.use("*", ...) a todo, con una excepción explícita solo para /dashboard y /dashboard/*. El comentario justo encima (src/index.ts:34-39) muestra que el autor razonó cuidadosamente sobre la exposición CORS del panel pero no extendió el mismo razonamiento a las rutas del proxy que están debajo.
  • src/config.ts:153 — host: z.string().default("0.0.0.0"), confirmado en vivo en config.example.yaml:13. El proxy escucha en todas las interfaces por defecto, no solo en loopback, por lo que también es accesible desde la LAN, no solo desde el navegador del propio operador.
  • src/providers/openai/client.ts:48-53:
    root@kitploit:~
    // Use client's auth header if provided, otherwise fall back to config
    if (authHeader) {
      headers.Authorization = authHeader;
    } else if (config.api_key) {
      headers.Authorization = `Bearer ${config.api_key}`;
    }
    
    Si la solicitud entrante no lleva encabezado Authorization, PasteGuard adjunta silenciosamente su propia providers.openai.api_key retenida en el servidor a la solicitud saliente. config.example.yaml:22-24 documenta esto como una característica de conveniencia intencional ("Respaldo opcional si el cliente no envía encabezado de autenticación") para el caso de uso "Apps & APIs".
  • src/providers/anthropic/client.ts:37-61 implementa el patrón de respaldo idéntico para /anthropic/v1/messages (respaldo de x-api-key/Authorization a config.api_key) — confirmado como una instancia hermana de la misma causa raíz, no reverificado de forma independiente de extremo a extremo (ver el alcance del PoC a continuación).

Debido a que la política CORS con comodín se sitúa delante de rutas que contienen esta credencial de respaldo, cualquier origen puede (1) hacer que el navegador envíe la solicitud sin encabezado Authorization, provocando que el servidor adjunte su propia clave de API real, y (2) leer la respuesta JSON, ya que Access-Control-Allow-Origin: * está presente. Ninguna verificación de Origin/Referer ni token CSRF protege estas rutas.

Prueba de concepto (confirmada dinámicamente, no solo trazada estáticamente):

  1. Se configuró config.yaml con providers.openai.base_url: http://127.0.0.1:9091 (upstream simulado) y providers.openai.api_key: "sk-VICTIM-SECRET-DO-NOT-LEAK-12345", pii_detection.enabled: false (detector simulado solo /health, para evitar necesitar el servicio completo del modelo GLiNER), secrets_detection.enabled: false. Se inició PasteGuard con bun run src/index.ts, se confirmó /health → 200.
  2. Se inició un upstream simulado (mock_upstream.py) en 127.0.0.1:9091 que registra cualquier encabezado Authorization que reciba.
  3. Se sirvió una página de atacante real desde un origen genuinamente distinto, http://127.0.0.2:8001/attack.html (IP de loopback literal diferente, según las reglas de aislamiento de sitios de Chrome — no una prueba de mismo origen en localhost), mediante python3 -m http.server 8001 --bind 127.0.0.2. La única acción de la página al cargar:
    root@kitploit:~
    fetch("http://127.0.0.1:3000/openai/v1/chat/completions", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ model: "gpt-4o-mini", messages: [{ role: "user", content: "cross-origin drive-by call, attacker supplied NO api key" }] })
    }).then(r => r.json()).then(data => { /* render on page */ });
    
  4. Se dirigió una instancia real de Chrome (Chrome DevTools Protocol) a http://127.0.0.2:8001/attack.html. Se confirmó mediante inspección de red de DevTools:
    • Solicitud: origin: http://127.0.0.2:8001, sec-fetch-site: cross-site, sin encabezado Authorization enviado por la página del atacante.
    • Respuesta: access-control-allow-origin: *, HTTP 200, cuerpo JSON totalmente legible por el JS de la página del atacante.
    • Página renderizada: "CROSS-ORIGIN READ SUCCEEDED. Response body visible to attacker JS: ..." — captura de pantalla: ../evidence/cross_origin_csrf_success.png.
    • Registro del upstream simulado para esa solicitud exacta: RECEIVED AUTH HEADER: Bearer sk-VICTIM-SECRET-DO-NOT-LEAK-12345 — lo que demuestra que PasteGuard adjuntó la clave real configurada del operador del lado del servidor, sin que la página del atacante la conociera ni la proporcionara.

Evidencia sin procesar: ~/engagements/pasteguard/evidence/cross_origin_csrf_success.png, ~/engagements/pasteguard/evidence/mock_upstream_log.txt.

Se confirmó estáticamente (archivo:línea arriba) que la ruta /anthropic/v1/messages comparte el patrón idéntico de respaldo + CORS con comodín, pero no se volvió a ejecutar por separado a través del PoC del navegador en vivo, en aras de la guía de profundidad sobre amplitud/regla de 5 minutos de la sesión, una vez que la causa raíz ya estaba confirmada en /openai.

Impacto: Cualquier sitio web que visite el navegador del operador de PasteGuard (anuncio malicioso, sitio comprometido, o un atacante en la misma LAN dado el bind predeterminado 0.0.0.0) puede impulsar silenciosamente solicitudes facturadas ilimitadas a través de la propia cuenta de OpenAI/Anthropic del operador mediante su instancia local de PasteGuard, sin interacción del usuario más allá de tener la pestaña abierta y sin forma de que el operador lo note salvo vigilando el panel de facturación de su proveedor. Este es un vector directo de abuso financiero / agotamiento de cuota, y secundariamente contamina el registro de uso/auditoría de la cuenta del proveedor del operador con contenido elegido por el atacante.

Debilidades:

  • CWE-352: Cross-Site Request Forgery
  • CWE-942: Permissive Cross-domain Policy with Untrusted Domains
  • CWE-798: Use of Hard-coded Credentials (la clave de respaldo del lado del servidor es reutilizable de forma transparente por cualquier llamador que omita su propia autenticación) — listada como factor contribuyente, no como la debilidad principal

Remediación (sugerencias):

  • No aplicar el middleware cors() con comodín a /openai, /anthropic, /codex (y /api/mask si alguna vez se extiende para usar credenciales retenidas en el servidor) cuando se configura una api_key de respaldo. Como mínimo, hacer que los orígenes permitidos para estas rutas sean explícitos/configurables (p. ej., solo el origen conocido de la extensión del navegador), con valor predeterminado de ningún acceso de origen cruzado en lugar de *.
  • Añadir una verificación de Origin/Referer (o un token local compartido ligero que la extensión legítima del navegador adjunte) específicamente en la ruta de código de la clave de respaldo, reflejando el razonamiento ya aplicado a /dashboard en src/index.ts.
  • Cambiar el valor predeterminado de server.host de 0.0.0.0 a 127.0.0.1 en src/config.ts:153 y config.example.yaml:13, requiriendo una adhesión explícita para enlazar en todas las interfaces.

Crédito: Dostxodjayev Abdullox

Canal de reporte: No existe ningún SECURITY.md en el repositorio (confirmado mediante gh api repos/sgasser/pasteguard/contents/SECURITY.md → 404, reverificado en el momento de la auditoría). Tampoco hay avisos de seguridad publicados previamente (gh api repos/sgasser/pasteguard/security-advisories → []), por lo que esto no parece ser un duplicado de un problema divulgado anteriormente. Canal recomendado: el flujo predeterminado de reporte privado de vulnerabilidades de GitHub en https://github.com/sgasser/pasteguard/security/advisories/new.

Descargar herramienta