Cross-site Scripting (XSS) - Stored in kevinpapst/kimai2
Description
Kimai 2 before 1.16.3 allows stored cross-site scripting via markdown fields when safe mode is disabled.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Kimai 2 before 1.16.3 allows stored cross-site scripting via markdown fields when safe mode is disabled.
Vulnerability
Kimai 2 versions prior to 1.16.3 contain a stored cross-site scripting (XSS) vulnerability in the markdown rendering functionality. The MarkdownExtension class, used in comment, timesheet, and other content fields, allowed the markdown parser to operate without safe mode when the $safe parameter was set to false [1]. This occurred in methods commentContent, timesheetContent, and markdownToHtml [2]. If an attacker could submit markdown input (e.g., via timesheet descriptions or comments), the application would output unsanitized HTML, enabling XSS payloads.
Exploitation
An attacker with write access to Kimai's markdown-enabled fields (such as timesheet descriptions or comments) can craft a malicious markdown string, for example `XSS) [2]. When this content is rendered for another user, the markdown parser converts it to an anchor tag with a javascript:` URL. Because safe mode was not forced, the browser executes the script, leading to XSS. No special network position is required beyond being an authenticated user who can create or edit content.
Impact
Successful exploitation allows an attacker to execute arbitrary JavaScript in the context of another user's browser session. This can lead to theft of session cookies, impersonation, data exfiltration, or actions performed on behalf of the victim. The impact is limited to the scope of the affected application, but may include disclosure of timesheet data, customer information, or administrative actions if the victim has elevated privileges.
Mitigation
The vulnerability is fixed in Kimai 2 version 1.16.3, released December 1, 2021 [4]. The fix forces safe mode and escapes markup in the toHtml method, deprecating the unsafe parameter [2]. Users should upgrade to 1.16.3 or later. No other workarounds are documented. The CVE is not listed on CISA's Known Exploited Vulnerabilities catalog.
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
kevinpapst/kimai2Packagist | < 1.16.3 | 1.16.3 |
Affected products
2- kevinpapst/kevinpapst/kimai2v5Range: unspecified
Patches
176e09447c85emake sure that markdown uses safe mode (#2961)
4 files changed · +39 −4
src/Twig/Runtime/MarkdownExtension.php+3 −3 modified@@ -61,7 +61,7 @@ public function commentContent(?string $content, bool $fullLength = false): stri } if ($this->isMarkdownEnabled()) { - $content = $this->markdown->toHtml($content, false); + $content = $this->markdown->toHtml($content); } elseif ($fullLength) { $content = '<p>' . nl2br($content) . '</p>'; } @@ -112,7 +112,7 @@ public function timesheetContent(?string $content): string } if ($this->isMarkdownEnabled()) { - return $this->markdown->toHtml($content, false); + return $this->markdown->toHtml($content); } return nl2br($content); @@ -126,6 +126,6 @@ public function timesheetContent(?string $content): string */ public function markdownToHtml(string $content): string { - return $this->markdown->toHtml($content, false); + return $this->markdown->toHtml($content); } }
src/Utils/Markdown.php+6 −1 modified@@ -33,7 +33,12 @@ public function __construct() */ 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); }
tests/Twig/Runtime/MarkdownExtensionTest.php+12 −0 modified@@ -27,6 +27,10 @@ public function testMarkdownToHtml() $sut = new MarkdownExtension(new Markdown(), $config); $this->assertEquals('<p><em>test</em></p>', $sut->markdownToHtml('*test*')); $this->assertEquals('<p># foobar</p>', $sut->markdownToHtml('# foobar')); + $this->assertEquals( + '<p><a href="javascript%3Aalert(`XSS`)">XSS</a></p>', + $sut->markdownToHtml('[XSS](javascript:alert(`XSS`))') + ); } public function testTimesheetContent() @@ -47,6 +51,10 @@ public function testTimesheetContent() "<ul>\n<li>test</li>\n<li>foo</li>\n</ul>\n<p>foo <strong>bar</strong></p>", $sut->timesheetContent("- test\n- foo\n\nfoo __bar__") ); + $this->assertEquals( + '<p><a href="javascript%3Aalert(`XSS`)">XSS</a></p>', + $sut->timesheetContent('[XSS](javascript:alert(`XSS`))') + ); } public function testCommentContent() @@ -76,6 +84,10 @@ public function testCommentContent() "<ul>\n<li>test</li>\n<li>foo</li>\n</ul>\n<p>foo <strong>bar</strong></p>", $sut->commentContent("- test\n- foo\n\nfoo __bar__") ); + $this->assertEquals( + '<p><a href="javascript%3Aalert(`XSS`)">XSS</a></p>', + $sut->commentContent('[XSS](javascript:alert(`XSS`))') + ); } public function testCommentOneLiner()
tests/Utils/MarkdownTest.php+18 −0 modified@@ -81,6 +81,24 @@ public function testDuplicateIds() ## test ### test # test +EOT; + $this->assertEquals($html, $sut->toHtml($markdown)); + } + + public function testLinksAreSanitized() + { + $sut = new Markdown(); + + $html = <<<'EOT' +<p><a href="javascript%3Aalert(`XSS`)">XSS</a><br /> +<a href="javascript%3Aalert("XSS")">XSS</a><br /> +<a href="javascript%3Aalert('XSS')">XSS</a></p> +EOT; + + $markdown = <<<EOT +[XSS](javascript:alert(`XSS`)) +[XSS](javascript:alert("XSS")) +[XSS](javascript:alert('XSS')) EOT; $this->assertEquals($html, $sut->toHtml($markdown)); }
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-x68c-4gmm-5g43ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2021-3985ghsaADVISORY
- github.com/kevinpapst/kimai2/commit/76e09447c85e762882126b49626a4fe4d93fe8b5ghsax_refsource_MISCWEB
- github.com/kevinpapst/kimai2/releases/tag/1.16.3ghsaWEB
- huntr.dev/bounties/89d6c3de-efbd-4354-8cc8-46e999e4c5a4ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.