See how thephpleague compares to other vendors in security performance
The league/commonmark (thephpleague/commonmark) library in versions >= 1.5.0 and < 2.9.1 contains quadratic parsing complexity in its SmartPunctExtension and AttributesExtension. When either extension is explicitly registered on the Environment (they are not enabled by default and are excluded from the standard CommonMark and GitHub-Flavored Markdown converters), an unauthenticated attacker can submit small, specially crafted Markdown documents — such as text alternating with unpaired quotes, contiguous runs of block-level attribute blocks, or repeated class attributes — to trigger disproportionate CPU consumption and cause a denial of service. Fixed in 2.9.1.
league/commonmark versions before 2.9.1 contain multiple denial of service vulnerabilities in fenced code block detection, reference link label lookup, and emphasis delimiter processing that perform super-linear work on crafted input. Attackers can submit specially crafted Markdown with long backtick runs, nested brackets, or delimiter sequences to consume disproportionate CPU time and prevent legitimate requests from completing.
commonmark versions from 1.5.0 before 2.10.0 contain a denial of service vulnerability in the AttributesExtension when processing distinctly-named attributes. Attackers can submit Markdown with numerous distinct attribute names to cause quadratic-time attribute merging and filtering, consuming disproportionate CPU resources and preventing legitimate requests from completing.
league/commonmark (thephpleague/commonmark) versions >= 2.7.0 and < 2.9.1 contain a cross-site scripting vulnerability in the AttributesExtension. Prefixing an attribute name with a single U+000C form feed byte (e.g. {\x0Conclick="alert(1)"}) bypasses the AttributesHelper::filterAttributes() 'on' event-handler filter because PHP's trim() does not strip U+000C, causing the attribute to be written verbatim into the output where browsers parse it as a genuine event handler. The same prefix also defeats the allowunsafelinks check, allowing javascript: URIs through href/src attributes even when allowunsafelinks is false. Exploitation requires processing untrusted Markdown with the AttributesExtension enabled; the injected script executes when the rendered HTML is viewed. Fixed in 2.9.1.
Impact Servers that passed their keys to the CryptKey constructor as as string instead of a file path will have had that key included in a LogicException message if they did not provide a valid pass phrase for the key where required.
Patches This issue has been patched so that the provided key is no longer exposed in the exception message in the scenario outlined above. Users should upgrade to version 8.5.3 or 8.4.2 to receive the patch.
Workarounds We recommend upgrading the oauth2-server to one of the patched releases (8.5.3 or 8.4.2). If you are unable to upgrade you can avoid this security issue by passing your key as a file instead of a string.
References Fix for 8.4.x Fix for 8.5.x
Impact
The DomainFilteringAdapter in the Embed extension is vulnerable to an allowlist bypass due to a missing hostname boundary assertion in the domain-matching regex. An attacker-controlled domain like youtube.com.evil passes the allowlist check when youtube.com is an allowed domain.
This enables two attack vectors:
- SSRF: The OscaroteroEmbedAdapter makes server-side HTTP requests to the embed URL via the embed/embed library. A bypassed domain filter causes the server to make outbound requests to an attacker-controlled host, potentially probing internal services or exfiltrating request metadata. - XSS: EmbedRenderer outputs the oEmbed response HTML directly into the page with no sanitization. An attacker controlling the bypassed domain can return arbitrary HTML/JavaScript in their oEmbed response, which is rendered verbatim.
Any application using the Embed extension and relying on alloweddomains to restrict domains when processing untrusted Markdown input is affected.
Patches
This has been patched in version 2.8.2. The fix replaces the regex-based domain check with explicit hostname parsing using parseurl(), ensuring exact domain and subdomain matching only.
Workarounds
- Disable the Embed extension, or restrict its use to trusted users - Provide your own domain-filtering implementation of EmbedAdapterInterface - Enable a Content Security Policy (CSP) and outbound firewall restrictions
Impact
The DisallowedRawHtml extension can be bypassed by inserting a newline, tab, or other ASCII whitespace character between a disallowed HTML tag name and the closing >. For example, <script\n> would pass through unfiltered and be rendered as a valid HTML tag by browsers. This is a cross-site scripting (XSS) vector for any application that relies on this extension to sanitize untrusted user input.
All applications using the DisallowedRawHtml extension to process untrusted markdown are affected. Applications that use a dedicated HTML sanitizer (such as HTML Purifier) on the rendered output are not affected.
Patches
Fixed in 2.8.1. The regex character class [ \/>] was changed to [\s\/>] to match all whitespace characters that browsers accept as valid tag name terminators.
Workarounds
- Set the htmlinput configuration option to 'escape' or 'strip' to disable all raw HTML, though this is a broader restriction than the DisallowedRawHtml extension provides. - Pass the rendered HTML through a dedicated HTML sanitizer before serving it to users (always recommended)
Resources
- CommonMark DisallowedRawHtml documentation - CWE-79: Improper Neutralization of Input During Web Page Generation - CWE-80: Improper Neutralization of Script-Related HTML Tags in a Web Page (Basic XSS)
Cross-site scripting (XSS) vulnerability in the PHP League CommonMark library versions 0.15.6 through 0.18.x before 0.18.1 allows remote attackers to insert unsafe URLs into HTML (even if allowunsafelinks is false) via a newline character (e.g., writing javascript as javascri%0apt).
CVE-2019-10010
Impact
In league/commonmark 0.18.2 and below, malicious users can insert double-encoded HTML entities into their Markdown like this:
md XSS
This library would (correctly) unescape the & entity to & during the parsing step. However, the renderer step would fail to properly re-escape the resulting : string, thus producing the following malicious HTML output:
html <p><a href="javascript:alert('XSS')">XSS</a></p>
Browsers would interpret : as a : character and allow the JS to be executed when the link is clicked.
This vulnerability was present in the upstream library this project was forked from and therefore exists in all prior versions of league/commonmark.
Solution
The new 0.18.3 release mirrors the fix made upstream - we no longer attempt to preserve entities when rendering HTML attributes like href, src, title, etc.
The $preserveEntities parameter of Xml::escape() is therefore no longer used internally, so it has been deprecated and marked for removal in the next major release (0.19.0).
Credits
- Mohit Fawaz for identifying the issue - Sebastiaan Knijnenburg and Ross Tuck for responsibly disclosing/relaying the issue - John MacFarlane for investigating it and implementing the upstream fix we mirrored here
References
- https://nvd.nist.gov/vuln/detail/CVE-2019-10010 - https://github.com/thephpleague/commonmark/releases/tag/0.18.3 - https://github.com/thephpleague/commonmark/issues/353 - https://github.com/FriendsOfPHP/security-advisories/blob/master/league/commonmark/CVE-2019-10010.yaml
Impact
The whitespace normalisation using in 1.x and 2.x removes any unicode whitespace. Under certain specific conditions this could potentially allow a malicious user to execute code remotely.
The conditions:
- A user is allowed to supply the path or filename of an uploaded file. - The supplied path or filename is not checked against unicode chars. - The supplied pathname checked against an extension deny-list, not an allow-list. - The supplied path or filename contains a unicode whitespace char in the extension. - The uploaded file is stored in a directory that allows PHP code to be executed.
Given these conditions are met a user can upload and execute arbitrary code on the system under attack.
Patches
The unicode whitespace removal has been replaced with a rejection (exception).
The library has been patched in: - 1.x: https://github.com/thephpleague/flysystem/commit/f3ad69181b8afed2c9edf7be5a2918144ff4ea32 - 2.x: https://github.com/thephpleague/flysystem/commit/a3c694de9f7e844b76f9d1b61296ebf6e8d89d74
Workarounds
For 1.x users, upgrade to 1.1.4. For 2.x users, upgrade to 2.1.1.