Skip to main content
CVE Vulnerability Database

CVE-2026-9769: justhtml Library DOS Vulnerability

CVE-2026-9769 is a denial of service vulnerability in the justhtml library caused by uncontrolled recursion during HTML parsing. Attackers can crash applications using deeply nested elements. This article covers technical details, affected versions, impact assessment, and mitigation strategies.

Updated:

CVE-2026-9769 Overview

CVE-2026-9769 is an uncontrolled recursion vulnerability [CWE-674] in the justhtml Python library through version 1.9.1. The flaw resides in the JustHTML() constructor, where TreeBuilder.finish() unconditionally invokes _populate_selectedcontent(). That routine recursively walks the parsed DOM tree through _find_elements() and _find_element() without a depth boundary. An attacker who controls HTML input can submit approximately 1000 nested <div> tags, around 11 KB, to exceed CPython's default recursion limit. The resulting unhandled RecursionError can abort parsing, fail HTTP requests, or terminate a worker process. The issue is fixed in version 1.10.0.

Critical Impact

Remote unauthenticated attackers can trigger denial of service against any application that parses attacker-supplied HTML using justhtml versions through 1.9.1.

Affected Products

  • justhtml versions through 1.9.1
  • Python applications embedding justhtml for HTML parsing
  • Web services accepting user-supplied HTML processed by justhtml

Discovery Timeline

  • 2026-08-23 - CVE-2026-9769 published to NVD
  • 2026-08-26 - Last updated in NVD database

Technical Details for CVE-2026-9769

Vulnerability Analysis

The vulnerability is a denial of service caused by uncontrolled recursion during HTML tree construction. When JustHTML() is instantiated, TreeBuilder.finish() calls _populate_selectedcontent() unconditionally, regardless of tree shape. That helper traverses every DOM node using _find_elements() and _find_element() in a recursive pattern. Because neither function enforces a maximum depth, tree depth maps directly onto Python call stack depth. Approximately 1000 nested elements exhaust CPython's default recursion limit of 1000 frames. The interpreter raises an unhandled RecursionError that propagates out of the parser.

Root Cause

The root cause is missing depth validation in the recursive tree walk. The _populate_selectedcontent() post-processing step runs on every parse, so attackers do not need to reach a specific feature to trigger it. Because Python converts stack overflow into a catchable exception rather than a crash, downstream applications that lack a broad exception handler will bubble the error up and fail the calling operation.

Attack Vector

Exploitation requires only the ability to submit HTML to a parser using justhtml. A crafted payload of roughly 11 KB containing about 1000 nested <div> elements is sufficient. The attack requires no authentication, no user interaction, and can be delivered over any transport that ultimately calls JustHTML() on attacker-controlled markup. Impact depends on the host application's exception handling: individual requests may fail, background workers may terminate, or long-running processes may be forced to restart. See the GitHub Security Advisory and VulnCheck Advisory for additional detail.

Detection Methods for CVE-2026-9769

Indicators of Compromise

  • HTTP request bodies containing deeply nested identical tags, particularly long runs of <div> elements exceeding several hundred levels.
  • Application logs showing RecursionError: maximum recursion depth exceeded originating from justhtml modules.
  • Repeated worker restarts or 500-series responses correlated with HTML upload or webhook endpoints.

Detection Strategies

  • Inspect ingress HTML payloads for tag nesting depth and flag inputs exceeding an application-appropriate threshold, such as 100 levels.
  • Correlate Python exception telemetry with request identifiers to attribute RecursionError events to specific client sources.
  • Baseline normal HTML payload size and structure for endpoints that accept markup, then alert on statistical outliers.

Monitoring Recommendations

  • Emit metrics for parser failures and worker restarts, and route them into your SIEM for correlation with source IP and user session.
  • Enable structured exception logging in web frameworks so RecursionError events include full stack traces and request context.
  • Track dependency inventory for justhtml version 1.9.1 and earlier across all Python services.

How to Mitigate CVE-2026-9769

Immediate Actions Required

  • Upgrade justhtml to version 1.10.0 or later across all environments that parse untrusted HTML.
  • Audit application code paths that call JustHTML() and identify endpoints that accept external markup.
  • Add explicit try/except RecursionError handlers around parser invocations to prevent worker termination until patching completes.

Patch Information

The maintainer has released justhtml version 1.10.0, which fixes the uncontrolled recursion. Refer to the GitHub Security Advisory GHSA-v7cf-c9rm-wm3j for release notes and upgrade guidance.

Workarounds

  • Pre-validate incoming HTML and reject documents whose nesting depth exceeds a conservative bound before invoking justhtml.
  • Enforce request body size limits at the reverse proxy or WAF to reduce the practical payload window for nesting attacks.
  • Isolate HTML parsing in worker processes with automatic restart so a RecursionError does not degrade the wider service.
bash
# Upgrade justhtml to the fixed release
pip install --upgrade 'justhtml>=1.10.0'

# Verify installed version
pip show justhtml | grep -i version

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.