CVE-2026-27645: changedetection.io Vulnerable to Reflected XSS in RSS Single Watch Error Response

Published Feb 25, 2026
·
Updated

Summary Three security vulnerabilities were identified in changedetection.io through source code review and live validation against a locally deployed Docker instance. All vulnerabilities were confirmed exploitable on the latest version (0.53.6) it was additionally validated at scale against 500 internet-facing instances discovered via FOFA search engine, producing 5K+ confirmed detections using a custom Nuclei template, demonstrating widespread real-world impact. The RSS single-watch endpoint reflects the UUID path parameter directly in the HTTP response body without HTML escaping. Since Flask returns text/html by default for plain string responses, the browser parses and executes injected JavaScript.

Details File: changedetectionio/blueprint/rss/singlewatch.py (lines ~45 and ~50)

The UUID parameter from the URL path is interpolated into the response body using an f-string with no escaping:

Line ~45 watch = datastore.data['watching'].get(uuid) if not watch: return f"Watch with UUID {uuid} not found", 404 # ← No escaping, Content-Type: text/html

Line ~50 if len(dates) < 2: return f"Watch {uuid} does not have enough history snapshots...", 400 # ← Same issue Flask's default Content-Type for plain string responses is text/html; charset=utf-8, so any HTML/JavaScript in {uuid} is rendered by the browser.

Attack Vector The attack requires a valid RSS access token, which is a 32-character hex string exposed in the HTML <link> tag on the homepage without authentication:

<!-- Visible in page source of any unauthenticated instance --> <link rel="alternate" type="application/rss+xml" href="/rss?token=f2bb14e20ff01bad83a743cf21b5df95">

Attacker visits the target's homepage if it unauthenticathed and extracts the RSS token from the <link> tag Crafts a malicious URL:

1. http://target:5000/rss/watch/%3Cimg%20src%3Dx%20onerror%3Dalert(document.cookie)%3E?token=EXTRACTEDTOKEN 2. Sends the link to a victim who has an active session on the changedetection.io instance 3. When the victim clicks the link, the server responds with: 4. Watch with UUID not found

The browser renders the <img> tag, the onerror fires, and JavaScript executes in the victim's session context

PoC Request:

GET /rss/watch/%3Cimg%20src%3Dx%20onerror%3Dalert(document.cookie)%3E?token=223e7edbbfee2268f5abb5344919054e HTTP/1.1 Host: 127.0.0.1:5000

Response:

HTTP/1.1 404 NOT FOUND Content-Type: text/html; charset=utf-8

Watch with UUID not found

<img width="1918" height="1032" alt="image" src="https://github.com/user-attachments/assets/1633b167-e4ec-4705-a110-18fad7826fc9" />

The XSS payload is reflected unescaped in an HTML response. The browser executes alert(document.cookie).

Lots of intances over internet affected to this. <img width="1465" height="721" alt="image" src="https://github.com/user-attachments/assets/f54160d4-abd1-4e8d-b845-f85e53e79325" />

Impact - Session cookie theft via document.cookie exfiltration - Account takeover if session cookies lack HttpOnly flag - Phishing via crafted links that appear to originate from a trusted changedetection.io instance - Token is obtainable without authentication from the homepage <link> tag, lowering the barrier to exploitation

changedetection.io can work with developer teams to validate and address these issues. Please confirm receipt of this report and inform changedetection.io of the preferred timeline for coordinating the fix.

Roberto Nunes

Other sources

changedetection.io is a free open source web page change detection tool. In versions prior to 0.54.1, the RSS single-watch endpoint reflects the UUID path parameter directly in the HTTP response body without HTML escaping. Since Flask returns text/html by default for plain string responses, the browser parses and executes injected JavaScript. Version 0.54.1 contains a fix for the issue.

MITRE

Affected Software

3 affected componentsFixes available
npm/changedetection.io<0.54.1
Webtechnologies Changedetection<0.54.1
pip/changedetection.io<=0.53.6
0.53.7

Event History

Feb 25, 2026
CVE Published
via MITRE·04:06 AM
Data Sourced
via MITRE·04:06 AM
DescriptionSeverityWeakness
Data Sourced
via NVD·05:17 AM
RemedyDescriptionSeverityWeaknessAffected Software
Advisory Published
via GitHub·07:07 PM
Data Sourced
via GitHub·07:07 PM
DescriptionSeverityWeaknessAffected Software
Oct 1, 58139
Event
via FIRST·02:43 PM
Free Weekly Intel

Don't miss critical vulnerabilities

Join thousands of security professionals who receive our weekly digest of trending CVEs, zero-days, and exploited vulnerabilities.

No spam. Unsubscribe anytime.

Frequently Asked Questions

1

What is the severity of CVE-2026-27645?

CVE-2026-27645 has a severity rating of medium due to its potential for exploitation via reflected XSS attacks.

2

How do I fix CVE-2026-27645?

To fix CVE-2026-27645, upgrade to changedetection.io version 0.54.1 or later.

3

What is the impact of CVE-2026-27645?

The impact of CVE-2026-27645 includes the potential for an attacker to execute arbitrary JavaScript in a user's browser.

4

Which versions of changedetection.io are affected by CVE-2026-27645?

CVE-2026-27645 affects all versions of changedetection.io prior to 0.54.1.

5

How does CVE-2026-27645 exploit reflected XSS?

CVE-2026-27645 exploits reflected XSS by reflecting the UUID parameter in the response without proper HTML escaping.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203