diff --git a/src/Twig/Runtime/MarkdownExtension.php b/src/Twig/Runtime/MarkdownExtension.php index c73e8eea..3187796f 100644 --- a/src/Twig/Runtime/MarkdownExtension.php +++ b/src/Twig/Runtime/MarkdownExtension.php @@ -61,7 +61,7 @@ final class MarkdownExtension implements RuntimeExtensionInterface } if ($this->isMarkdownEnabled()) { - $content = $this->markdown->toHtml($content, false); + $content = $this->markdown->toHtml($content); } elseif ($fullLength) { $content = '
' . nl2br($content) . '
'; } @@ -112,7 +112,7 @@ final class MarkdownExtension implements RuntimeExtensionInterface } if ($this->isMarkdownEnabled()) { - return $this->markdown->toHtml($content, false); + return $this->markdown->toHtml($content); } return nl2br($content); @@ -126,6 +126,6 @@ final class MarkdownExtension implements RuntimeExtensionInterface */ public function markdownToHtml(string $content): string { - return $this->markdown->toHtml($content, false); + return $this->markdown->toHtml($content); } } diff --git a/src/Utils/Markdown.php b/src/Utils/Markdown.php index 0988e7c9..5f21a100 100644 --- a/src/Utils/Markdown.php +++ b/src/Utils/Markdown.php @@ -33,7 +33,12 @@ final class Markdown */ public function toHtml(string $text, bool $safe = true): string { - $this->parser->setSafeMode($safe); + if ($safe !== true) { + @trigger_error('Only safe mode is supported in Markdown since 1.16.3 to prevent XSS attacks. Parameter $safe will be removed with 2.0', E_USER_DEPRECATED); + } + + $this->parser->setSafeMode(true); + $this->parser->setMarkupEscaped(true); return $this->parser->text($text); } diff --git a/tests/Twig/Runtime/MarkdownExtensionTest.php b/tests/Twig/Runtime/MarkdownExtensionTest.php index 56fbaf82..4418f3e9 100644 --- a/tests/Twig/Runtime/MarkdownExtensionTest.php +++ b/tests/Twig/Runtime/MarkdownExtensionTest.php @@ -27,6 +27,10 @@ class MarkdownExtensionTest extends TestCase $sut = new MarkdownExtension(new Markdown(), $config); $this->assertEquals('test
', $sut->markdownToHtml('*test*')); $this->assertEquals('# foobar
', $sut->markdownToHtml('# foobar')); + $this->assertEquals( + '', + $sut->markdownToHtml('[XSS](javascript:alert(`XSS`))') + ); } public function testTimesheetContent() @@ -47,6 +51,10 @@ class MarkdownExtensionTest extends TestCase "foo bar
", $sut->timesheetContent("- test\n- foo\n\nfoo __bar__") ); + $this->assertEquals( + '', + $sut->timesheetContent('[XSS](javascript:alert(`XSS`))') + ); } public function testCommentContent() @@ -76,6 +84,10 @@ class MarkdownExtensionTest extends TestCase "foo bar
", $sut->commentContent("- test\n- foo\n\nfoo __bar__") ); + $this->assertEquals( + '', + $sut->commentContent('[XSS](javascript:alert(`XSS`))') + ); } public function testCommentOneLiner() diff --git a/tests/Utils/MarkdownTest.php b/tests/Utils/MarkdownTest.php index 5871a5b9..b021bf8b 100644 --- a/tests/Utils/MarkdownTest.php +++ b/tests/Utils/MarkdownTest.php @@ -81,6 +81,24 @@ EOT; ## test ### test # test +EOT; + $this->assertEquals($html, $sut->toHtml($markdown)); + } + + public function testLinksAreSanitized() + { + $sut = new Markdown(); + + $html = <<<'EOT' + +EOT; + + $markdown = <<