Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Commonmark Laravel Package

league/commonmark

Highly extensible PHP Markdown parser supporting full CommonMark and GitHub-Flavored Markdown. Convert Markdown to HTML with simple converters, customize rendering via extensions, and run safely with options like stripping HTML and blocking unsafe links.

View on GitHub
Deep Wiki
Context7

layout: default title: Security description: How to configure league/commonmark against possible security issues when handling untrusted user input redirect_from:

  • /security/
  • /2.0/security/
  • /2.1/security/
  • /2.2/security/
  • /2.3/security/
  • /2.4/security/
  • /2.5/security/
  • /2.6/security/
  • /2.7/security/

Security

In order to be fully compliant with the CommonMark spec, certain security settings are disabled by default. You will want to configure these settings if untrusted users will be providing the Markdown content:

  • html_input: How to handle raw HTML
  • allow_unsafe_links: Whether unsafe links are permitted
  • max_nesting_level: Protect against long render times or segfaults
  • max_delimiters_per_line: Protect against long parse times or rendering segfaults

Further information about each option can be found below.

HTML Input

All HTML input is unescaped by default. This behavior ensures that league/commonmark is 100% compliant with the CommonMark spec.

If you're developing an application which renders user-provided Markdown from potentially untrusted users, you are strongly encouraged to set the html_input option in your configuration to either escape or strip:

Example - Escape all raw HTML input

use League\CommonMark\CommonMarkConverter;

$converter = new CommonMarkConverter(['html_input' => 'escape']);
echo $converter->convert('<script>alert("Hello XSS!");</script>');

// &lt;script&gt;alert("Hello XSS!");&lt;/script&gt;

Example - Strip all HTML from the input

use League\CommonMark\CommonMarkConverter;

$converter = new CommonMarkConverter(['html_input' => 'strip']);
echo $converter->convert('<script>alert("Hello XSS!");</script>');

// (empty output)

Failing to set this option could make your site vulnerable to cross-site scripting (XSS) attacks!

See the configuration section for more information.

Unsafe Links

Unsafe links are also allowed by default due to CommonMark spec compliance. An unsafe link is one that uses any of these protocols:

  • javascript:
  • vbscript:
  • file:
  • data: (except for data:image in png, gif, jpeg, or webp format)

To prevent these from being parsed and rendered, you should set the allow_unsafe_links option to false.

Nesting Level

No maximum nesting level is enforced by default. Markdown content which is too deeply-nested (like 10,000 nested blockquotes: '> > > > > ...') could result in long render times or segfaults.

If you need to parse untrusted input, consider setting a reasonable max_nesting_level (perhaps 10-50) depending on your needs. Once this nesting level is hit, any subsequent Markdown will be rendered as plain text.

Example - Prevent deep nesting

use League\CommonMark\CommonMarkConverter;

$markdown = str_repeat('> ', 10000) . ' Foo';

$converter = new CommonMarkConverter(['max_nesting_level' => 5]);
echo $converter->convert($markdown);

// <blockquote>
//   <blockquote>
//     <blockquote>
//       <blockquote>
//         <blockquote>
//           <p>&gt; &gt; &gt; &gt; &gt; &gt; &gt; ... Foo</p></blockquote>
//       </blockquote>
//     </blockquote>
//   </blockquote>
// </blockquote>

See the configuration section for more information.

Max Delimiters Per Line

Similarly to the maximum nesting level, no maximum number of delimiters per line is enforced by default. Delimiters can be nested (like *a **b** c*) or un-nested (like *a* *b* *c*) - in either case, having too many in a single line can result in long parse times. We therefore have a separate option to limit the number of delimiters per line.

If you need to parse untrusted input, consider setting a reasonable max_delimiters_per_line (perhaps 100-1000) depending on your needs. Once this level is hit, any subsequent delimiters on that line will be rendered as plain text.

Example - Prevent too many delimiters

use League\CommonMark\CommonMarkConverter;

$markdown = '*a* **b *c **d** c* b**'; // 8 delimiters (* and **)

$converter = new CommonMarkConverter(['max_delimiters_per_line' => 6]);
echo $converter->convert($markdown);

// <p><em>a</em> **b *c <strong>d</strong> c* b**</p>

Additional Filtering

Although this library does offer these security features out-of-the-box, some users may opt to also run the HTML output through additional filtering layers (like HTMLPurifier). If you do this, make sure you thoroughly test your additional post-processing steps and configure them to work properly with the types of HTML elements and attributes that converted Markdown might produce, otherwise, you may end up with weird behavior like missing images, broken links, mismatched HTML tags, etc.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport