GHSA-97jj-33gv-5xf9: OS Command Injection

Published Sep 30, 2026
·
Updated

Summary

The 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.

Details

DisallowedRawHtmlRenderer escapes tags with this regex:

/<(\/?(?:title|textarea|style|xmp|iframe|noembed|noframes|script|plaintext)[\s\/>])/i

The trailing character class requires one character after the tag name. The block parser does not: RegexHelper::PARTIALHTMLBLOCKOPEN 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.

In the browser the newline is still present, so the tag name terminates there and whatever follows becomes attributes.

This 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.

Reproduction

Render this with GithubFlavoredMarkdownConverter and default settings:

<div> <script

<span src="/evil.js">

Output:

html <div> <script <span src="/evil.js">

A 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.

Control: <script src="/evil.js"></script> is correctly escaped to &lt;script src="/evil.js">&lt;/script>.

Affected versions

1.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.

Preconditions

- htmlinput is allow (the default) - The DisallowedRawHtml extension is active, which the GFM extension enables automatically - Untrusted users can post Markdown

Setting htmlinput to escape or strip fully mitigates this.

Suggested fix

Allow end of string after the tag name:

php $regex = \sprintf('/<(\/?(?:%s))([\s\/>]|$)/i', \implode('|', \arraymap('pregquote', $tags)));

return \pregreplace($regex, '&lt;$1$2', $rendered);

This 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.

Affected Software

1 affected componentFixes available
composer/league/commonmark>=1.3.0<=2.10.1
2.10.2

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade composer/league/commonmark to a version that resolves this vulnerability.

    Fixed in 2.10.2
  2. Upgrade

    Upgrade to a fixed release to a version that resolves this vulnerability.

    Fixed in 2.8.1
  3. Configuration

    Set html_input to escape or strip to mitigate the raw HTML bypass.

    GithubFlavoredMarkdownConverter html_input = escape or strip

Event History

Sep 30, 2026
Advisory Published
via GitHub·03:36 PM
Data Sourced
via GitHub·03:36 PM
DescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

Which deployments are exposed?

Deployments using composer/league/commonmark with GithubFlavoredMarkdownConverter and its shipped default GFM settings are exposed if untrusted users can post Markdown that is later rendered in a browser.

2

What does an attacker need to trigger the issue?

The attacker needs the ability to submit Markdown content. A line ending immediately after a disallowed raw HTML tag name, followed by a subsequent block that supplies attributes, can result in stored XSS when rendered.

3

How can I identify potentially affected content?

Review stored Markdown for lines containing only the opening portion of a disallowed tag such as <script, particularly where the following block could provide attributes. Confirm the rendering path uses GithubFlavoredMarkdownConverter with default settings.

4

What remediation information is available?

The provided references include commit 411afcc2a7402756d96c89af8882c724d12d47ca and the 2.10.2 release. The advisory data does not provide a complete affected-version range.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203