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
CVE-2026-66421-OpenClaw-Dashboard-Stored-XSS-via-lastMessage-Session-Field — Aviso de seguridad: Cross-Site Scripting Almacenado a través de mensajes de agente que conduce al robo de tokens de sesión (openclaw-dashboard) | Kitploit
Herramientas/GitHubGitHub/theopaid/cve-2026-66421-openclaw-dashboard-stored-xss-via-lastmessage-session-field
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebSeguridad WebSeguridad de APIsSeguridad de IA
GitHubtheopaid/cve-2026-66421-openclaw-dashboard-stored-xss-via-lastmessage-session-field

CVE-2026-66421-OpenClaw-Dashboard-Stored-XSS-via-lastMessage-Session-Field

Aviso de seguridad: Cross-Site Scripting Almacenado a través de mensajes de agente que conduce al robo de tokens de sesión (openclaw-dashboard)

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
Ver Repositorio
hace 17 díasAún no revisado

Aviso de Seguridad: Cross-Site Scripting Almacenado a Través de Mensajes de Agente Que Conduce al Robo de Tokens de Sesión (openclaw-dashboard)

Título: OpenClaw Dashboard XSS Almacenado a través del campo lastMessage de la sesión ID de CVE: CVE-2026-66421

https://github.com/tugcantopaloglu/openclaw-dashboard

Resumen

La tabla de sesiones en la página de inicio del panel muestra el último mensaje de cada sesión de agente. Ese texto se toma de la transcripción de conversación del agente y se escribe en la página con innerHTML y sin escape. OpenClaw es una puerta de enlace de agentes multicanal, por lo que el texto del mensaje puede provenir de cualquier persona que pueda hablar con el agente, como un grupo de chat o un webhook. Un mensaje que contenga un payload HTML se ejecuta como script en el navegador del administrador tan pronto como este abre el panel.

  • CWE-79: Neutralización incorrecta de la entrada durante la generación de páginas web (Cross-site Scripting)
  • CVSS 4.0: 8.8 (Alta). Vector: CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:H/VI:H/VA:N/SC:H/SI:H/SA:N

Versiones afectadas

Presente desde la primera versión pública. El renderizado vulnerable existe en la etiqueta más antigua (v1.1.0) y en cada commit posterior hasta e incluyendo el main actual (d6198d0). No corregido en el momento de redactar este aviso.

Modelo de amenaza

El atacante es una parte que puede enviar un mensaje que termina en la transcripción de sesión del agente. No necesita una cuenta en el panel. En una implementación típica de OpenClaw, esto incluye miembros de canales de chat conectados y cualquier fuente que llegue al agente a través de un webhook, por lo que el atacante suele estar fuera del límite de confianza del operador.

El payload se almacena en la transcripción y se renderiza cada vez que el administrador ve la página de sesiones. Esa página es la vista de inicio predeterminada y se actualiza con un temporizador, por lo que la única interacción requerida es que el administrador cargue el panel que normalmente usa. AT:P refleja la única condición de la que depende el atacante: que la implementación enrute sus mensajes hacia una sesión que el panel muestre.

Causa raíz

Paso 1. El texto del mensaje se extrae de la transcripción. El servidor lee el mensaje más reciente y devuelve su texto, recortado a 80 caracteres, sin saneamiento:

root@kitploit:~
// server.js:474-481
if (typeof msg.content === 'string') {
  text = msg.content;
} else if (Array.isArray(msg.content)) {
  for (const b of msg.content) {
    if (b.type === 'text' && b.text) { text = b.text; break; }
  }
}
if (text) return text.replace(/\n/g, ' ').substring(0, 80);

Paso 2. Se expone a través de la API de sesiones. getSessionsJson coloca el texto en el campo lastMessage de cada sesión:

root@kitploit:~
// server.js:538
lastMessage: getLastMessage(s.sessionId || key),

GET /api/sessions devuelve este array al navegador.

Paso 3. Se escribe en el DOM sin escape. La tabla de sesiones construye cada fila mediante concatenación de cadenas y la asigna con innerHTML:

root@kitploit:~
// index.html:3758
const lastMsg = s.lastMessage ? s.lastMessage.substring(0, 60) + (s.lastMessage.length > 60 ? '…' : '') : '';
root@kitploit:~
// index.html:3773
<div class="table-cell" style="..." onclick="toggleSessionExpand('${escapedKey}', event)">${lastMsg}</div>

lastMsg se coloca directamente en la cadena HTML. No hay ningún paso de codificación en ningún punto de esta ruta.

La misma tabla interpola s.label (index.html:3770) y s.key (index.html:3767) en el marcado de la fila de la misma manera. Esos campos no tienen límite de 60 caracteres, por lo que dan a un atacante que pueda influir en ellos más espacio para un payload.

La Política de Seguridad de Contenido en server.js:298 permite manejadores de eventos en línea (script-src 'self' 'unsafe-inline'), por lo que un manejador onerror se ejecuta.

Prueba de concepto

  1. Como parte que puede enviar mensajes al agente, envíe un mensaje cuyo texto sea un payload corto que quepa en el presupuesto de 60 caracteres, por ejemplo:

    root@kitploit:~

    Esto son 56 caracteres y llega a la transcripción de sesión del agente como cualquier mensaje normal.

  2. Confirme que el servidor devuelve el payload sin escapar:

    root@kitploit:~
    curl -H "Authorization: Bearer ADMIN_TOKEN" http://TARGET:7000/api/sessions
    

    El campo lastMessage de la sesión afectada contiene la cadena `` cruda.

  3. El administrador abre el panel. La página de sesiones es la vista predeterminada, por lo que no se necesita navegación adicional. La fila se renderiza, el navegador analiza la etiqueta ``, el manejador onerror se ejecuta y el token de sesión del administrador es leído por el payload.

Reemplazar el cuerpo de console.log con un fetch a un endpoint autenticado de mismo origen permite que el payload actúe con los privilegios del usuario conectado.

Impacto

Ejecución de scripts en el origen del panel como el usuario conectado, alcanzable por alguien que solo necesita enviar un mensaje al agente. El payload puede leer el token de sesión y llamar a endpoints autenticados, incluidos aquellos que editan los archivos de instrucciones del propio agente y la configuración de OpenClaw. Debido a que se activa en la página predeterminada, el administrador no tiene que realizar ninguna acción inusual.

Remediación

  • Codifique en HTML lastMessage, label y key antes de insertarlos en el marcado de la fila, o construya las celdas con textContent en lugar de una cadena HTML.
  • Aplique la misma codificación a los otros campos de sesión renderizados a través de innerHTML.
  • Elimine 'unsafe-inline' de script-src para que el marcado inyectado no pueda ejecutarse incluso si se omite un paso de codificación.
Descargar herramienta