← Back to CVE Explorer

CVE-2026-44645

Full vulnerability record from the local CVENow database.

Description

LiquidJS is a Shopify/GitHub Pages compatible template engine written in pure JavaScript. In versions 10.25.7 and below, the renderLimit option can be fully bypassed by a {% for %} (or {% tablerow %}) tag whose body is empty. The renderLimit option is documented in docs/source/tutorials/dos.md as the mechanism that "mitigates this by limiting the time consumed by each render() call." The per-iteration time check is reached only when the body contains at least one template node, so a template such as {%- for i in (1..N) -%}{%- endfor -%} iterates the full collection without ever consulting renderLimit. With a configured renderLimit of 50 ms, a single parseAndRenderSync call has been observed to consume 2.26 seconds (~45× over the limit) and scales linearly with N up to memoryLimit, allowing a low-privileged template author to wedge an event-loop thread for an attacker-chosen duration. Deployments that rely on a finite renderLimit for DoS protection (common in multi-tenant template-authoring environments) can still be forced by a single crafted template to monopolize a Node.js event-loop worker for attacker-controlled time, potentially stalling in-flight requests, with availability impact only. This issue has been fixed in version 10.26.0.

Severity
MEDIUM
CVSS score
6.5 (v3.1)
Vulnerability status
Deferred
Source identifier
Published
2026-06-17 23:17:03.607000
Last modified
2026-10-25 23:10:00.167000
View original CVE JSON
{
  "id": "CVE-2026-44645",
  "sourceIdentifier": "[email protected]",
  "published": "2026-06-17T23:17:03.607",
  "lastModified": "2026-10-25T23:10:00.167",
  "vulnStatus": "Deferred",
  "cveTags": [],
  "descriptions": [
    {
      "lang": "en",
      "value": "LiquidJS is a Shopify/GitHub Pages compatible template engine written in pure JavaScript. In versions 10.25.7 and below, the renderLimit option can be fully bypassed by a {% for %} (or {% tablerow %}) tag whose body is empty. The renderLimit option is documented in docs/source/tutorials/dos.md as the mechanism that \"mitigates this by limiting the time consumed by each render() call.\" The per-iteration time check is reached only when the body contains at least one template node, so a template such as {%- for i in (1..N) -%}{%- endfor -%} iterates the full collection without ever consulting renderLimit. With a configured renderLimit of 50 ms, a single parseAndRenderSync call has been observed to consume 2.26 seconds (~45× over the limit) and scales linearly with N up to memoryLimit, allowing a low-privileged template author to wedge an event-loop thread for an attacker-chosen duration. Deployments that rely on a finite renderLimit for DoS protection (common in multi-tenant template-authoring environments) can still be forced by a single crafted template to monopolize a Node.js event-loop worker for attacker-controlled time, potentially stalling in-flight requests, with availability impact only. This issue has been fixed in version 10.26.0."
    },
    {
      "lang": "es",
      "value": "LiquidJS es un motor de plantillas compatible con Shopify/GitHub Pages escrito en JavaScript puro. En las versiones 10.25.7 e inferiores, la opción renderLimit puede ser completamente eludida por una etiqueta {% for %} (o {% tablerow %}) cuyo cuerpo está vacío. La opción renderLimit está documentada en docs/source/tutorials/dos.md como el mecanismo que ’mitiga esto limitando el tiempo consumido por cada llamada a render()’. La verificación de tiempo por iteración se alcanza solo cuando el cuerpo contiene al menos un nodo de plantilla, por lo que una plantilla como {%- for i in (1..N) -%}{%- endfor -%} itera la colección completa sin consultar nunca renderLimit. Con un renderLimit configurado de 50 ms, se ha observado que una sola llamada a parseAndRenderSync consume 2.26 segundos (~45× por encima del límite) y escala linealmente con N hasta memoryLimit, permitiendo a un autor de plantillas con bajos privilegios encallar un hilo del bucle de eventos por una duración elegida por el atacante. Las implementaciones que dependen de un renderLimit finito para la protección contra DoS (común en entornos de autoría de plantillas multi-inquilino) aún pueden ser forzadas por una única plantilla diseñada para monopolizar un worker del bucle de eventos de Node.js por un tiempo controlado por el atacante, lo que podría estancar las solicitudes en curso, con solo un impacto en la disponibilidad. Este problema ha sido solucionado en la versión 10.26.0."
    }
  ],
  "affected": [
    {
      "source": "[email protected]",
      "affectedData": [
        {
          "vendor": "harttle",
          "product": "liquidjs",
          "versions": [
            {
              "version": "< 10.26.0",
              "status": "affected"
            }
          ]
        }
      ]
    }
  ],
  "metrics": {
    "cvssMetricV31": [
      {
        "source": "[email protected]",
        "type": "Secondary",
        "cvssData": {
          "version": "3.1",
          "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H",
          "baseScore": 6.5,
          "baseSeverity": "MEDIUM",
          "attackVector": "NETWORK",
          "attackComplexity": "LOW",
          "privilegesRequired": "LOW",
          "userInteraction": "NONE",
          "scope": "UNCHANGED",
          "confidentialityImpact": "NONE",
          "integrityImpact": "NONE",
          "availabilityImpact": "HIGH"
        },
        "exploitabilityScore": 2.8,
        "impactScore": 3.6
      }
    ],
    "ssvcV203": [
      {
        "source": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
        "ssvcData": {
          "timestamp": "2026-06-18T19:05:03.703365Z",
          "id": "CVE-2026-44645",
          "options": [
            {
              "exploitation": "poc"
            },
            {
              "automatable": "no"
            },
            {
              "technicalImpact": "partial"
            }
          ],
          "role": "CISA Coordinator",
          "version": "2.0.3"
        }
      }
    ]
  },
  "weaknesses": [
    {
      "source": "[email protected]",
      "type": "Secondary",
      "description": [
        {
          "lang": "en",
          "value": "CWE-400"
        }
      ]
    }
  ],
  "references": [
    {
      "url": "https://github.com/harttle/liquidjs/commit/5b9c3469085e01c79e2d0af28e2a13f730e1793d",
      "source": "[email protected]"
    },
    {
      "url": "https://github.com/harttle/liquidjs/releases/tag/v10.26.0",
      "source": "[email protected]"
    },
    {
      "url": "https://github.com/harttle/liquidjs/security/advisories/GHSA-8xx9-69p8-7jp3",
      "source": "[email protected]"
    },
    {
      "url": "https://github.com/harttle/liquidjs/security/advisories/GHSA-8xx9-69p8-7jp3",
      "source": "134c704f-9b21-4f2e-91b3-4a467353bcc0"
    }
  ]
}