Dosage Vulnerable to Stored Cross-Site Scripting (XSS) in HTML/RSS Output Handlers
Date: 2026-06
Affected: pip/dosage
Attack vector: xss
Category: vulnerability-disclosure
Severity: Medium
CWE: CWE-79
CVSS: 6.1 (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N)

## Summary The HTML and RSS output handlers in `dosagelib/events.py` write user-controlled content (comic text and page URLs) directly into generated files without proper HTML escaping. When a user scrapes a malicious webcomic and opens the generated HTML/RSS file, attacker-controlled JavaScript can execute in their browser. **CWE**: [CWE-79](https://cwe.mitre.org/data/definitions/79.html) - Improper Neutralization of Input During Web Page Generation (Cross-site Scripting) --- ## Details ### Vulnerable Code Locations The vulnerability exists in `dosagelib/events.py` where untrusted content is written to HTML/RSS output without escaping: **1. RSSEventHandler (lines 116-118)** ```python # events.py:116-118 if comic.text: description += '<br/>%s' % comic.text # ← Unescaped comic.text description += '<br/><a href="%s">View Comic Online</a>' % pageUrl # ← Unescaped URL ``` **2. HtmlEventHandler (lines 232, 238)** ```python # events.py:232 self.html.write(u'<li><a href="%s">%s</a>\n' % (pageUrl, pageUrl)) # ← Unescaped URL # events.py:238 if text: self.html.write(u'<br/>%s\n' % text) # ← Unescaped text ``` ### Root Cause - `BasicScraper.fetchText()` in `scraper.py:422` calls `html.unescape()` on extracted text - The output handlers never call `html.escape()` before writing to files - No sanitization of URLs or text content occurs anywhere in the output pipeline ### Data Flow ``` Malicious webcomic page ↓ textSearch XPath extracts content (e.g., im


Mitigations:

Architectural layers (MAESTRO):