{"schema":"threatline.record/2","record":{"id":"GHSA-97jj-33gv-5xf9","aliases":["CVE-2026-105829","GHSA-97jj-33gv-5xf9"],"summary":"league/commonmark: DisallowedRawHtml bypassed when a disallowed tag name ends the raw-HTML literal","details":"﻿## Summary\n\nThe `DisallowedRawHtml` extension does not escape a disallowed tag when the tag name is the last thing in the raw HTML. A Markdown line containing just `<script` is emitted unchanged, and the next block can supply its attributes. With the shipped GFM defaults this allows stored XSS by anyone who can post Markdown.\n\n## Details\n\n`DisallowedRawHtmlRenderer` escapes tags with this regex:\n\n```\n/<(\\/?(?:title|textarea|style|xmp|iframe|noembed|noframes|script|plaintext)[\\s\\/>])/i\n```\n\nThe trailing character class requires one character after the tag name. The block parser does not: `RegexHelper::PARTIAL_HTMLBLOCKOPEN` accepts end of line after a tag name, so `<script` alone opens an HTML block. Because a rendered `HtmlBlock` has no trailing newline, the regex has nothing to match and the `<` passes through.\n\nIn the browser the newline is still present, so the tag name terminates there and whatever follows becomes attributes.\n\nThis is the same filter that GHSA-4v6x-c7xx-hw9f fixed in 2.8.1. That fix widened the character class but still requires one character, so this case was not covered.\n\n## Reproduction\n\nRender this with `GithubFlavoredMarkdownConverter` and default settings:\n\n```\n<div>\n<script\n\n<span src=\"/evil.js\">\n```\n\nOutput:\n\n```html\n<div>\n<script\n<span src=\"/evil.js\">\n```\n\nA browser parses that as `<script src=\"/evil.js\">` with a junk `<span` attribute, and the script runs. `<iframe` with `<span onload=\"...\">` works the same way and does not need a later `</script>` in the page.\n\nControl: `<script src=\"/evil.js\"></script>` is correctly escaped to `&lt;script src=\"/evil.js\">&lt;/script>`.\n\n## Affected versions\n\n1.3.0 (when the extension was added) through the current release. The `</style` and mid-line forms are only affected as continuation lines inside an already-open HTML block.\n\n## Preconditions\n\n- `html_input` is `allow` (the default)\n- The `DisallowedRawHtml` extension is active, which the GFM extension enables automatically\n- Untrusted users can post Markdown\n\nSetting `html_input` to `escape` or `strip` fully mitigates this.\n\n## Suggested fix\n\nAllow end of string after the tag name:\n\n```php\n$regex = \\sprintf('/<(\\/?(?:%s))([\\s\\/>]|$)/i', \\implode('|', \\array_map('preg_quote', $tags)));\n\nreturn \\preg_replace($regex, '&lt;$1$2', $rendered);\n```\n\nThis escapes every bypass shape above and leaves `<div>`, `<scripts>` and `<span class=\"a\">` untouched. The existing unit test only covers tag names followed by another character, so a case for a bare tag name should be added.","categories":["Libraries & packages"],"product":"league/commonmark","vendor":"","ecosystem":"composer","affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-97jj-33gv-5xf9","source_modified_at":"2026-09-30T15:36:37Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"composer","name":"league/commonmark"},"range":">= 1.3.0, <= 2.10.1"},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-97jj-33gv-5xf9","source_modified_at":"2026-10-09T02:56:07.054426049Z","fetched_at":"2026-10-23T18:45:31.882637Z","package":{"name":"league/commonmark","ecosystem":"Packagist","purl":"pkg:composer/league/commonmark"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.3.0"},{"fixed":"2.10.2"}]}],"versions":["1.3.0","1.3.1","1.3.2","1.3.3","1.3.4","1.4.0","1.4.1","1.4.2","1.4.3","1.5.0","1.5.1","1.5.2","1.5.3","1.5.4","1.5.5","1.5.6","1.5.7","1.5.8","1.6.0","1.6.1","1.6.2","1.6.3","1.6.4","1.6.5","1.6.6","1.6.7","2.0.0","2.0.0-beta1","2.0.0-beta2","2.0.0-beta3","2.0.0-rc1","2.0.0-rc2","2.0.1","2.0.2","2.0.3","2.0.4","2.1.0","2.1.1","2.1.2","2.1.3","2.10.0","2.10.1","2.2.0","2.2.1","2.2.2","2.2.3","2.2.4","2.2.5","2.3.0","2.3.1"]}],"fixed_versions":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-97jj-33gv-5xf9","source_modified_at":"2026-09-30T15:36:37Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"composer","name":"league/commonmark"},"version":"2.10.2"},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-97jj-33gv-5xf9","source_modified_at":"2026-10-09T02:56:07.054426049Z","fetched_at":"2026-10-23T18:45:31.882637Z","package":{"name":"league/commonmark","ecosystem":"Packagist","purl":"pkg:composer/league/commonmark"},"version":"2.10.2"}],"cvss":6.1,"severity":"Medium","kev":{"listed":false},"epss":{"probability":null,"percentile":null,"score_date":null},"published_at":"2026-09-30T15:36:33Z","modified_at":"2026-10-09T02:56:07.054426049Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/advisories/GHSA-97jj-33gv-5xf9","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-09-30T15:36:37Z"},{"source":"OSV","url":"https://osv.dev/vulnerability/GHSA-97jj-33gv-5xf9","fetched_at":"2026-10-23T18:45:31.882637Z","source_modified_at":"2026-10-09T02:56:07.054426049Z"}],"sources":["GitHub Advisory Database","OSV"],"references":[{"url":"https://github.com/thephpleague/commonmark/security/advisories/GHSA-97jj-33gv-5xf9","source":"GitHub Advisory Database"},{"url":"https://github.com/thephpleague/commonmark/commit/411afcc2a7402756d96c89af8882c724d12d47ca","source":"GitHub Advisory Database"},{"url":"https://github.com/thephpleague/commonmark/releases/tag/2.10.2","source":"GitHub Advisory Database"},{"url":"https://github.com/advisories/GHSA-97jj-33gv-5xf9","source":"GitHub Advisory Database"}],"locations":[],"motoko_assessment":{"status":"requires_architecture_review","automatic_remediation":false},"classification":{"method":"product-first software-layer rules","rules_version":"2.1","matched_on":"ecosystem","confidence":"heuristic","reviewed":false},"change_timestamp":"2026-10-09T02:56:07.054426049Z","content_hash":"f8aa1e2c4e0b835c73a2855d81d74a5ecc43306b1bc190551da4629b9f6a16a3"}}
