Skip to content

CVE-2026-8445 — justhtml versions <= 1.11.0 (fixed in 1.12.0) do not sufficiently escape HTML-significant…

Key facts

CVE-2026-8445 is a Critical (9.8) vulnerability: justhtml versions <= 1.11.0 (fixed in 1.12.0) do not sufficiently escape HTML-significant…. This entry ships a detection-only PoC and a Docker test lab.

CVE CVE-2026-8445
Severity Critical (9.8)
Detection / prevention —
PoC poc.py
Source 2026/CVE-2026-8445/

Details

English | 한국어

Description

justhtml versions <= 1.11.0 (fixed in 1.12.0) do not sufficiently escape HTML-significant characters (angle brackets) in text nodes when converting a parsed document to Markdown via to_markdown(). While a small set of Markdown metacharacters are escaped, characters such as < and > are preserved, so untrusted input that is safe in to_html() — including entity-decoded text (e.g. <script>) or text from RCDATA/RAWTEXT-parsed elements like , <textarea>, <noscript>, and <plaintext> — can be emitted as raw HTML in the Markdown output, enabling a sanitizer bypass and potential cross-site scripting when that output is rendered.</p> <h2 id="vulnerability-details">Vulnerability Details<a class="headerlink" href="#vulnerability-details" title="Permanent link">¶</a></h2> <table> <thead> <tr> <th>Property</th> <th>Value</th> </tr> </thead> <tbody> <tr> <td><strong>CVE ID</strong></td> <td>CVE-2026-8445</td> </tr> <tr> <td><strong>Type</strong></td> <td>XSS</td> </tr> <tr> <td><strong>CVSS Score</strong></td> <td>9.8</td> </tr> </tbody> </table> <h2 id="proof-of-concept">Proof of Concept<a class="headerlink" href="#proof-of-concept" title="Permanent link">¶</a></h2> <h3 id="download">Download<a class="headerlink" href="#download" title="Permanent link">¶</a></h3> <div class="highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="c1"># Download PoC script</span> <a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a>curl<span class="w"> </span>-O<span class="w"> </span>https://raw.githubusercontent.com/fankh/vulnerability-poc/main/2026/CVE-2026-8445/poc.py </code></pre></div> <h3 id="usage">Usage<a class="headerlink" href="#usage" title="Permanent link">¶</a></h3> <div class="highlight"><pre><span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a><span class="c1"># Run PoC against target</span> <a id="__codelineno-1-2" name="__codelineno-1-2" href="#__codelineno-1-2"></a>python3<span class="w"> </span>poc.py<span class="w"> </span>--target<span class="w"> </span><TARGET_URL> <a id="__codelineno-1-3" name="__codelineno-1-3" href="#__codelineno-1-3"></a> <a id="__codelineno-1-4" name="__codelineno-1-4" href="#__codelineno-1-4"></a><span class="c1"># With authentication</span> <a id="__codelineno-1-5" name="__codelineno-1-5" href="#__codelineno-1-5"></a>python3<span class="w"> </span>poc.py<span class="w"> </span>--target<span class="w"> </span><TARGET_URL><span class="w"> </span>--username<span class="w"> </span><USER><span class="w"> </span>--password<span class="w"> </span><PASS> </code></pre></div> <p>⚠️ <strong>Warning</strong>: This PoC is for authorized security testing only. It uses detection-only techniques and does not exploit or damage target systems.</p> <h2 id="test-lab">Test Lab<a class="headerlink" href="#test-lab" title="Permanent link">¶</a></h2> <p>This repository includes a Docker-based test environment with both vulnerable and patched applications.</p> <h3 id="quick-start">Quick Start<a class="headerlink" href="#quick-start" title="Permanent link">¶</a></h3> <div class="highlight"><pre><span></span><code><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a><span class="c1"># Clone and navigate to CVE directory</span> <a id="__codelineno-2-2" name="__codelineno-2-2" href="#__codelineno-2-2"></a><span class="nb">cd</span><span class="w"> </span>CVE-2026-8445 <a id="__codelineno-2-3" name="__codelineno-2-3" href="#__codelineno-2-3"></a> <a id="__codelineno-2-4" name="__codelineno-2-4" href="#__codelineno-2-4"></a><span class="c1"># Start both applications</span> <a id="__codelineno-2-5" name="__codelineno-2-5" href="#__codelineno-2-5"></a>docker-compose<span class="w"> </span>up<span class="w"> </span>-d <a id="__codelineno-2-6" name="__codelineno-2-6" href="#__codelineno-2-6"></a> <a id="__codelineno-2-7" name="__codelineno-2-7" href="#__codelineno-2-7"></a><span class="c1"># Run tests</span> <a id="__codelineno-2-8" name="__codelineno-2-8" href="#__codelineno-2-8"></a>./run-tests.sh<span class="w"> </span><span class="c1"># Linux/Mac</span> <a id="__codelineno-2-9" name="__codelineno-2-9" href="#__codelineno-2-9"></a>./run-tests.ps1<span class="w"> </span><span class="c1"># Windows PowerShell</span> </code></pre></div> <h3 id="application-endpoints">Application Endpoints<a class="headerlink" href="#application-endpoints" title="Permanent link">¶</a></h3> <table> <thead> <tr> <th>Application</th> <th>URL</th> <th>Status</th> </tr> </thead> <tbody> <tr> <td><strong>Vulnerable App</strong></td> <td>http://localhost:8080</td> <td>Shows vulnerability</td> </tr> <tr> <td><strong>Patched App</strong></td> <td>http://localhost:8081</td> <td>Demonstrates fix</td> </tr> </tbody> </table> <h3 id="directory-structure">Directory Structure<a class="headerlink" href="#directory-structure" title="Permanent link">¶</a></h3> <div class="highlight"><pre><span></span><code><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a>├── README.md # English documentation <a id="__codelineno-3-2" name="__codelineno-3-2" href="#__codelineno-3-2"></a>├── README_KO.md # Korean documentation <a id="__codelineno-3-3" name="__codelineno-3-3" href="#__codelineno-3-3"></a>├── poc.py # PoC detection script <a id="__codelineno-3-4" name="__codelineno-3-4" href="#__codelineno-3-4"></a>├── docker-compose.yml # Container orchestration <a id="__codelineno-3-5" name="__codelineno-3-5" href="#__codelineno-3-5"></a>├── run-tests.sh # Linux/Mac test runner <a id="__codelineno-3-6" name="__codelineno-3-6" href="#__codelineno-3-6"></a>├── run-tests.ps1 # Windows test runner <a id="__codelineno-3-7" name="__codelineno-3-7" href="#__codelineno-3-7"></a>├── vulnerable-app/ # Vulnerable version <a id="__codelineno-3-8" name="__codelineno-3-8" href="#__codelineno-3-8"></a>│ ├── app.py <a id="__codelineno-3-9" name="__codelineno-3-9" href="#__codelineno-3-9"></a>│ ├── Dockerfile <a id="__codelineno-3-10" name="__codelineno-3-10" href="#__codelineno-3-10"></a>│ └── requirements.txt <a id="__codelineno-3-11" name="__codelineno-3-11" href="#__codelineno-3-11"></a>└── patched-app/ # Fixed version <a id="__codelineno-3-12" name="__codelineno-3-12" href="#__codelineno-3-12"></a> ├── app.py <a id="__codelineno-3-13" name="__codelineno-3-13" href="#__codelineno-3-13"></a> ├── Dockerfile <a id="__codelineno-3-14" name="__codelineno-3-14" href="#__codelineno-3-14"></a> └── requirements.txt </code></pre></div> <h2 id="references">References<a class="headerlink" href="#references" title="Permanent link">¶</a></h2> <ul> <li>https://github.com/EmilStenstrom/justhtml/security/advisories/GHSA-3rcm-vjrc-p45j</li> <li>https://www.vulncheck.com/advisories/justhtml-before-sanitizer-bypass-via-markdown</li> </ul> <hr /> <p><em>Generated by PoC Generator on 2026-08-23T23:38:03.25979717</em></p> <h2 id="frequently-asked-questions">Frequently asked questions<a class="headerlink" href="#frequently-asked-questions" title="Permanent link">¶</a></h2> <h3 id="what-is-cve-2026-8445">What is CVE-2026-8445?<a class="headerlink" href="#what-is-cve-2026-8445" title="Permanent link">¶</a></h3> <p>CVE-2026-8445 is a Critical (9.8) vulnerability: justhtml versions <= 1.11.0 (fixed in 1.12.0) do not sufficiently escape HTML-significant…. This entry ships a detection-only PoC and a Docker test lab.</p> <h3 id="how-do-i-detect-cve-2026-8445">How do I detect CVE-2026-8445?<a class="headerlink" href="#how-do-i-detect-cve-2026-8445" title="Permanent link">¶</a></h3> <p>Run the detection-only PoC included with this entry against your Docker test lab to confirm whether a target is affected; pair it with your own IDS logging.</p> <h3 id="how-do-i-block-or-mitigate-cve-2026-8445">How do I block or mitigate CVE-2026-8445?<a class="headerlink" href="#how-do-i-block-or-mitigate-cve-2026-8445" title="Permanent link">¶</a></h3> <p>Upgrade to a fixed version per the vendor advisory; the NVD record lists the affected versions. Use the included PoC to verify your remediation.</p> <hr /> <p><em>For authorized security testing and research only. See the <a href="https://github.com/fankh/vulnerability-poc/blob/main/2026/CVE-2026-8445">full source</a> and <a href="https://nvd.nist.gov/vuln/detail/CVE-2026-8445">NVD record</a>.</em></p> <script type="application/ld+json">{"@context": "https://schema.org", "@graph": [{"@type": "TechArticle", "headline": "CVE-2026-8445 — justhtml versions <= 1.11.0 (fixed in 1.12.0) do not sufficiently escape HTML-significant…", "about": {"@type": "Thing", "name": "CVE-2026-8445", "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-8445"}, "author": {"@type": "Organization", "name": "SeekersLab", "url": "https://seekerslab.com"}, "publisher": {"@type": "Organization", "name": "SeekersLab"}, "url": "https://fankh.github.io/vulnerability-poc/2026/CVE-2026-8445/", "mainEntityOfPage": "https://fankh.github.io/vulnerability-poc/2026/CVE-2026-8445/", "dateModified": "2026-10-22", "keywords": "CVE-2026-8445, CVE-2026-8445 detection, CVE-2026-8445 poc, justhtml versions <= 1.11.0 (fixed in 1.12.0) do not sufficiently escape HTML-significant…"}, {"@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "What is CVE-2026-8445?", "acceptedAnswer": {"@type": "Answer", "text": "CVE-2026-8445 is a Critical (9.8) vulnerability: justhtml versions <= 1.11.0 (fixed in 1.12.0) do not sufficiently escape HTML-significant…. This entry ships a detection-only PoC and a Docker test lab."}}, {"@type": "Question", "name": "How do I detect CVE-2026-8445?", "acceptedAnswer": {"@type": "Answer", "text": "Run the detection-only PoC included with this entry against your Docker test lab to confirm whether a target is affected; pair it with your own IDS logging."}}, {"@type": "Question", "name": "How do I block or mitigate CVE-2026-8445?", "acceptedAnswer": {"@type": "Answer", "text": "Upgrade to a fixed version per the vendor advisory; the NVD record lists the affected versions. Use the included PoC to verify your remediation."}}]}, {"@type": "BreadcrumbList", "itemListElement": [{"@type": "ListItem", "position": 1, "name": "Home", "item": "https://fankh.github.io/vulnerability-poc/"}, {"@type": "ListItem", "position": 2, "name": "2026", "item": "https://fankh.github.io/vulnerability-poc/2026/"}, {"@type": "ListItem", "position": 3, "name": "CVE-2026-8445", "item": "https://fankh.github.io/vulnerability-poc/2026/CVE-2026-8445/"}]}]}</script> </article> </div> <script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var labels=set.querySelector(".tabbed-labels");for(var tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script> <script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script> </div> <button type="button" class="md-top md-icon" data-md-component="top" hidden> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg> Back to top </button> </main> <footer class="md-footer"> <div class="md-footer-meta md-typeset"> <div class="md-footer-meta__inner md-grid"> <div class="md-copyright"> <div class="md-copyright__highlight"> Apache-2.0 · Maintained by SeekersLab · For authorized security testing and research only </div> Made with <a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener"> Material for MkDocs </a> </div> <div class="md-social"> <a href="https://github.com/fankh/vulnerability-poc" target="_blank" rel="noopener" title="github.com" class="md-social__link"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8M97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg> </a> <a href="https://seekerslab.com" target="_blank" rel="noopener" title="seekerslab.com" class="md-social__link"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M16.36 14c.08-.66.14-1.32.14-2s-.06-1.34-.14-2h3.38c.16.64.26 1.31.26 2s-.1 1.36-.26 2m-5.15 5.56c.6-1.11 1.06-2.31 1.38-3.56h2.95a8.03 8.03 0 0 1-4.33 3.56M14.34 14H9.66c-.1-.66-.16-1.32-.16-2s.06-1.35.16-2h4.68c.09.65.16 1.32.16 2s-.07 1.34-.16 2M12 19.96c-.83-1.2-1.5-2.53-1.91-3.96h3.82c-.41 1.43-1.08 2.76-1.91 3.96M8 8H5.08A7.92 7.92 0 0 1 9.4 4.44C8.8 5.55 8.35 6.75 8 8m-2.92 8H8c.35 1.25.8 2.45 1.4 3.56A8 8 0 0 1 5.08 16m-.82-2C4.1 13.36 4 12.69 4 12s.1-1.36.26-2h3.38c-.08.66-.14 1.32-.14 2s.06 1.34.14 2M12 4.03c.83 1.2 1.5 2.54 1.91 3.97h-3.82c.41-1.43 1.08-2.77 1.91-3.97M18.92 8h-2.95a15.7 15.7 0 0 0-1.38-3.56c1.84.63 3.37 1.9 4.33 3.56M12 2C6.47 2 2 6.5 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2"/></svg> </a> </div> </div> </div> </footer> </div> <div class="md-dialog" data-md-component="dialog"> <div class="md-dialog__inner md-typeset"></div> </div> <script id="__config" type="application/json">{"base": "../..", "features": ["navigation.instant", "navigation.tracking", "navigation.top", "navigation.indexes", "search.suggest", "search.highlight", "content.code.copy", "content.tabs.link"], "search": "../../assets/javascripts/workers/search.6ce7567c.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}}</script> <script src="../../assets/javascripts/bundle.525ec568.min.js"></script> </body> </html>