Skip to main content
Vulnerability Database/CVE-2026-95657

CVE-2026-95657: Changedetection.io XSS Vulnerability

CVE-2026-95657 is a cross-site scripting vulnerability in dgtlmoon Changedetection.io affecting versions up to 0.55.8. Attackers can exploit the Visual Selector component remotely to execute malicious scripts. This article covers technical details, affected versions, and upgrade recommendations.

Published:

CVE-2026-95657 Overview

CVE-2026-95657 is a cross-site scripting (XSS) vulnerability [CWE-79] in dgtlmoon Changedetection.io versions up to 0.55.8. The flaw resides in the setCurrentSelectedText function of changedetectionio/static/js/visual-selector.js, part of the Visual Selector component. Manipulation of the s argument causes scraped selector content to render as HTML markup instead of text. An authenticated remote attacker can trigger the issue through crafted content processed by the Visual Selector. The exploit has been publicly disclosed. Upgrading to version 0.60.1, which includes commit aac6fcfa594f17511b8ff73e5eaa4f6c33899de0, remediates the issue.

Critical Impact

Authenticated remote attackers can inject markup that executes in the browser context of a Changedetection.io user viewing the Visual Selector, enabling limited integrity impact through client-side script execution.

Affected Products

  • dgtlmoon Changedetection.io versions up to and including 0.55.8
  • Component: Visual Selector (changedetectionio/static/js/visual-selector.js)
  • Fixed in Changedetection.io release 0.60.1

Discovery Timeline

  • 2026-09-22 - CVE-2026-95657 published to the National Vulnerability Database
  • 2026-09-22 - Last updated in NVD database

Technical Details for CVE-2026-95657

Vulnerability Analysis

The vulnerability is a stored/reflected DOM-based XSS in the Visual Selector component of Changedetection.io. The setCurrentSelectedText(s) function assigns its argument directly to the innerHTML property of the current XPath display element. Because the string s is derived from selectors scraped from a target page, attacker-controlled markup embedded in element IDs or related attributes is parsed as HTML rather than rendered as text.

A secondary root cause exists in the XPath generation logic within xpath_element_scraper.js. The getxpath function previously constructed selectors of the form //*[@id="..."] without validating whether the element ID contained quote or angle-bracket characters. IDs containing <, >, or " produced selectors that carried raw page markup into any downstream consumer that later displayed them.

Root Cause

The defect is improper neutralization of input during web page generation [CWE-79]. The Visual Selector treated scraped, untrusted data as trusted markup by writing it to innerHTML. Any HTML tags contained in the selector string, including <script> or event-handler attributes on other elements, were interpreted by the browser.

Attack Vector

Exploitation requires network access and low privileges on the Changedetection.io instance, plus user interaction. An attacker who controls a monitored page can craft HTML elements with IDs containing markup characters. When a Changedetection.io user opens the Visual Selector against that page, the scraper builds a selector string containing the malicious markup, and setCurrentSelectedText renders it as HTML in the operator's browser session.

javascript
// Security patch in changedetectionio/static/js/visual-selector.js
// Source: https://github.com/dgtlmoon/changedetection.io/commit/aac6fcfa594f17511b8ff73e5eaa4f6c33899de0
function setCurrentSelectedText(s) {
-    $selectorCurrentXpathElem[0].innerHTML = s;
+    // Selectors come from the scraped page, display them as text and never as markup
+    $selectorCurrentXpathElem[0].textContent = s;
}

// Companion fix in changedetectionio/content_fetchers/res/xpath_element_scraper.js
function getxpath(e) {
    var n = e;
-    if (n && n.id) return '//*[@id="' + n.id + '"]';
+    // A double quote cannot be expressed inside a double-quoted xpath literal, and an angle
+    // bracket would carry page markup into whatever displays the selector later.
+    if (n && n.id && !/["<>]/.test(n.id)) return '//*[@id="' + n.id + '"]';
    // ... positional path fallback ...
}

The patch replaces innerHTML assignment with textContent, which forces the browser to render the string as literal text. The scraper change filters IDs containing ", <, or > from the shortcut XPath and falls back to a positional path.

Detection Methods for CVE-2026-95657

Indicators of Compromise

  • HTML tags, <script> blocks, or event handler attributes (onerror, onload) appearing in stored Changedetection.io watch metadata or Visual Selector logs
  • Unexpected outbound requests from operator browsers to attacker-controlled domains shortly after opening the Visual Selector
  • Monitored pages containing DOM elements whose id attribute includes <, >, or " characters

Detection Strategies

  • Review installed Changedetection.io version against the fixed release 0.60.1 and flag any deployment at or below 0.55.8
  • Inspect browser DevTools network activity from users interacting with the Visual Selector for anomalous script loads or fetch calls
  • Search application logs for scraper output containing HTML tag characters within selector strings

Monitoring Recommendations

  • Enable a Content Security Policy on the Changedetection.io web interface and alert on CSP violation reports
  • Log and review all Visual Selector sessions, correlating operator identity with the target URLs being scraped
  • Monitor the Changedetection.io GitHub repository for further advisories referencing the Visual Selector component

How to Mitigate CVE-2026-95657

Immediate Actions Required

  • Upgrade Changedetection.io to release 0.60.1 or later, which contains commit aac6fcfa594f17511b8ff73e5eaa4f6c33899de0
  • Restrict access to the Changedetection.io web interface to trusted operators only, since exploitation requires an authenticated session
  • Audit the list of monitored URLs and remove any watches pointing to untrusted or attacker-controlled sites until patching is complete

Patch Information

The fix is delivered in Changedetection.io release 0.60.1 via GitHub Pull Request #4282 and GitHub Commit aac6fcf. Release artifacts are available at GitHub Release 0.60.1. Additional advisory context is published at VulDB CVE-2026-95657.

Workarounds

  • Avoid using the Visual Selector against untrusted target pages until the upgrade is applied
  • Deploy a strict Content Security Policy that disallows inline script execution on the Changedetection.io UI
  • Place the Changedetection.io instance behind a reverse proxy that enforces authentication and network segmentation
bash
# Upgrade Changedetection.io Docker deployment to the patched release
docker pull dgtlmoon/changedetection.io:0.60.1
docker stop changedetection && docker rm changedetection
docker run -d --name changedetection \
  -p 5000:5000 \
  -v datastore-volume:/datastore \
  dgtlmoon/changedetection.io:0.60.1

# Verify the running version
curl -s http://localhost:5000/ | grep -i version

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.