[Maintenance] Fix: replace showdown with markdown-it to remediate CVE-2024-1899#759
[Maintenance] Fix: replace showdown with markdown-it to remediate CVE-2024-1899#759sumukhswamy wants to merge 1 commit into
Conversation
Signed-off-by: sumukhswamy <sumukhhs@amazon.com>
|
@joshuali925-osdbot 1. does the original CVE have meaningful impact to OSD? 2. is there any difference in how showdown and markdown-it handles parsing differently, that switching over would break user experience? |
1. Does CVE-2024-1899 have meaningful impact to OSD?Low practical impact, but still worth fixing. The CVE is a ReDoS (Regular Expression Denial of Service) in showdown's anchors subparser — CVSS 3.1 score 5.3 Medium (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L). It requires crafted markdown input containing malicious link/anchor patterns that trigger catastrophic backtracking. In dashboards-reporting, showdown is used in 4 places:
The markdown input comes from authenticated OSD users (report creators/editors), not from unauthenticated external sources. An attacker would need valid OSD credentials to supply malicious markdown. The impact would be client-side browser tab freeze (for the preview) or server-side report generation hang (for PDF generation via headless Chromium). It would not crash the OSD server process itself. Bottom line: Exploitability is limited to authenticated users, and the blast radius is a single browser tab or report generation job. It's a low-risk DoS vector in practice, but showdown has no upstream fix and the library appears unmaintained, so replacing it is the right long-term move regardless. 2. Parsing differences between showdown and markdown-it that could affect UXBoth libraries support the features used here (tables, autolinks, strikethrough), but there are some behavioral differences:
Potential UX differences:
Overall risk: Low. The typical use case is simple markdown in report headers/footers. The task list removal is the only clearly visible behavioral change, and it's a rarely-used feature in this context. |
|
@joshuali925-osdbot can you start the OSD before and after this PR, test the markdown rendering in reporting plugin with commonly used and potentially breaking syntax, and post the comparison screenshots? |
Markdown Rendering Comparison: Showdown (before) vs markdown-it (after)Tested with the following markdown in the report header preview: # Heading 1
## Heading 2
### Heading 3
**Bold text** and *italic text* and ~~strikethrough~~
A paragraph with a [link](https://example.com) and an auto-link: https://opensearch.org
> This is a blockquote
> with multiple lines
- Unordered item 1
- Unordered item 2
- Nested item
1. Ordered item 1
2. Ordered item 2
- [x] Task completed
- [ ] Task pending
| Column 1 | Column 2 | Column 3 |
|-----------|----------|----------|
| Cell 1 | Cell 2 | Cell 3 |
| Cell 4 | Cell 5 | Cell 6 |
Inline `code` and a code block:
function hello() { Before (showdown on main branch)After (markdown-it on PR branch)Differences Found
SummaryThe rendering is functionally equivalent for all commonly used markdown syntax. Two behavioral differences:
Overall the PR is safe to merge for typical report header/footer usage. |
|
@joshuali925-osdbot compare with OUI/EUI, create a PR to use |
|
Investigated EuiMarkdownFormat Analysis
Feature Comparison
Architectural Issues with EuiMarkdownFormat
Verdictmarkdown-it is the better choice for this use case:
|
ps48
left a comment
There was a problem hiding this comment.
Added some minor comments to change few things.
| html: false, | ||
| linkify: true, |
There was a problem hiding this comment.
The converter is defined identically in public/components/report_definitions/utils/index.ts and public/components/visual_report/constants.ts. Consider consolidating into a single shared module (e.g., common/utils/markdown.ts) to avoid drift. Not blocking for a security fix.
| tasklists: true, | ||
| noHeaderId: true, | ||
| const md = new MarkdownIt({ | ||
| html: false, |
There was a problem hiding this comment.
Suggestion: Change html: false to html: true
Showdown rendered inline HTML by default, so html: false is a user-facing regression anyone using <b>, <br>, <span style="..."> etc. in report headers/footers will see raw tags displayed as text. This is safe because:
- All DOM-rendering paths already wrap output in
DOMPurify.sanitize() (generate_report.ts:126,129 and report_settings.tsx:363,386) - The delivery path sends HTML to a notification channel, not rendered in-browser
- The CVE is in showdown's regex parser, not in HTML pass-through
html: truedoesn't reintroduce the vulnerability
|
Thanks for the review @ps48! Both suggestions make sense — I've pushed a fix: Changes (PR to author's branch):
@sumukhswamy please merge sumukhswamy#1 into your branch to pick up these changes. |


Description
Showdown <= 2.1.0 is vulnerable to a ReDoS in the anchors subparser
(CVE-2024-1899) and has no upstream patch. Replace it with markdown-it,
which provides equivalent feature support for report header/footer
markdown rendering: tables, autolink (linkify), and strikethrough.
The legacy
tasklistsshowdown option is dropped to avoid an extraplugin dependency; checkboxes in report header/footer text now render
as plain list items. Output continues to be sanitized via DOMPurify
at every call site, and the converter API surface (
converter.makeHtml)is preserved so all four call sites remain unchanged.
Signed-off-by: Sumukh Swamy sumukhhs@amazon.com
Issues Resolved
[List any issues this PR will resolve]
Check List
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.