|
| 1 | +--- |
| 2 | +gem: prosemirror_to_html |
| 3 | +ghsa: 4249-gjr8-jpq3 |
| 4 | +url: https://github.com/etaminstudio/prosemirror_to_html/security/advisories/GHSA-52c5-vh7f-26fx |
| 5 | +title: ProsemirrorToHtml has a Cross-Site Scripting (XSS) vulnerability |
| 6 | + through unescaped HTML attribute values |
| 7 | +date: 2025-11-13 |
| 8 | +description: | |
| 9 | + ### Impact |
| 10 | +
|
| 11 | + The prosemirror_to_html gem is vulnerable to Cross-Site Scripting |
| 12 | + (XSS) attacks through malicious HTML attribute values. While tag |
| 13 | + content is properly escaped, attribute values are not, allowing |
| 14 | + attackers to inject arbitrary JavaScript code. |
| 15 | +
|
| 16 | + **Who is impacted:** |
| 17 | +
|
| 18 | + - Any application using prosemirror_to_html to convert ProseMirror |
| 19 | + documents to HTML |
| 20 | + - Applications that process user-generated ProseMirror content are |
| 21 | + at highest risk |
| 22 | + - End users viewing the rendered HTML output could have malicious |
| 23 | + JavaScript executed in their browsers |
| 24 | +
|
| 25 | + **Attack vectors include:** |
| 26 | +
|
| 27 | + - `href` attributes with `javascript:` protocol: |
| 28 | + `<a href="javascript:alert(document.cookie)">` |
| 29 | + - Event handlers: `<div onclick="maliciousCode()">` |
| 30 | + - `onerror` attributes on images: `<img src=x onerror="alert('XSS')">` |
| 31 | + - Other HTML attributes that can execute JavaScript |
| 32 | +
|
| 33 | + ### Patches |
| 34 | +
|
| 35 | + A fix is currently in development. Users should upgrade to version |
| 36 | + **0.2.1** or later once released. The patch escapes all HTML attribute |
| 37 | + values using `CGI.escapeHTML` to prevent injection attacks. |
| 38 | +
|
| 39 | + ### Workarounds |
| 40 | +
|
| 41 | + Until a patched version is available, users can implement one or |
| 42 | + more of these mitigations: |
| 43 | +
|
| 44 | + 1. **Sanitize output**: Pass the HTML output through a sanitization |
| 45 | + library like [Sanitize](https://github.com/rgrove/sanitize) or |
| 46 | + [Loofah](https://github.com/flavorjones/loofah): |
| 47 | +
|
| 48 | + ```ruby |
| 49 | + html = ProsemirrorToHtml.render(document) |
| 50 | + safe_html = Sanitize.fragment(html, Sanitize::Config::RELAXED) |
| 51 | + ``` |
| 52 | +
|
| 53 | + 2. **Implement Content Security Policy (CSP)**: Add strict CSP |
| 54 | + headers to prevent inline JavaScript execution: |
| 55 | + ``` |
| 56 | + Content-Security-Policy: default-src 'self'; script-src 'self' |
| 57 | + ``` |
| 58 | +
|
| 59 | + 3. **Input validation**: If possible, validate and sanitize |
| 60 | + ProseMirror documents before conversion to prevent malicious |
| 61 | + content from entering the system. |
| 62 | +
|
| 63 | + ### References |
| 64 | +
|
| 65 | + - Vulnerable code: https://github.com/etaminstudio/prosemirror_to_html/blob/ea8beb32f6c37f29f042ba4155ccf18504da716e/lib/prosemirror_to_html.rb#L249 |
| 66 | + - [OWASP XSS Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html) |
| 67 | +patched_versions: |
| 68 | + - ">= 0.2.1" |
| 69 | +related: |
| 70 | + url: |
| 71 | + - https://github.com/etaminstudio/prosemirror_to_html/security/advisories/GHSA-52c5-vh7f-26fx |
| 72 | + - https://github.com/etaminstudio/prosemirror_to_html/commit/4d59f94f550bcabeec30d298791bbdd883298ad8 |
| 73 | + - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html |
| 74 | + - https://github.com/etaminstudio/prosemirror_to_html/blob/ea8beb32f6c37f29f042ba4155ccf18504da716e/lib/prosemirror_to_html.rb#L249 |
| 75 | + - https://github.com/rubysec/ruby-advisory-db/blob/master/gems/prosemirror_to_html/GHSA-vfpf-xmwh-8m65.yml |
| 76 | + - https://github.com/advisories/GHSA-4249-gjr8-jpq3 |
0 commit comments