CVE-2026-25527 is a medium-severity (CVSS 5.3) Path Traversal vulnerability in changedetection-io. A fix is available for changedetection-io — see the affected versions and patch details below.
changedetection.io vulnerable to unauthenticated static path traversal
Exploitation Status
No confirmed exploitation observed yet
- CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.
- CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.
Exploitation and automatability from CISA’s SSVC triage for CVE-2026-25527.
EPSS Exploitation Probability
Probability of exploitation in the next 30 days, from FIRST.org EPSS.
How urgent is this, really
CVE-2026-25527 by exploitation likelihood (EPSS) against impact (CVSS). Outside the shaded patch-first corner.
Where this sits among everything scored
Of 385,738 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Counts from FIRST.org, log-scaled.
Real-World Exposure
changedetection-ioReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.
Description
Summary
The /static/<group>/<filename> route accepts group="..", which causes send_from_directory("static/..", filename) to execute. This moves the base directory up to /app/changedetectionio, enabling unauthenticated local file read of application source files (e.g., flask_app.py). Severity is low information disclosure (C:L).
Details
The vulnerable code is in changedetectionio/flask_app.py inside static_content():
group = re.sub(r'[^\w.-]+', '', group.lower())
filename = re.sub(r'[^\w.-]+', '', filename.lower())
...
return send_from_directory(f"static/{group}", path=filename)
The group sanitization allows dots, so group=".." passes validation.
This results in send_from_directory("static/..", filename), effectively shifting the base directory to /app/changedetectionio and allowing reads of files in that directory.
The route is unauthenticated, so any user can retrieve source files without logging in.
Limitation: the route only matches
/static/<group>/<filename>and rejects slashes insidefilename, so it cannot traverse further to arbitrary system paths like/etc/passwd. It is limited to files inside the application package directory.
PoC
- Start an instance (example: Docker on port 5050)
docker run -d --name cdio -p 127.0.0.1:5050:5000 -v cdio-data:/datastore cdio-local
- Reproduce
(URL-encoded traversal)
curl -i http://127.0.0.1:5050/static/%2e%2e/flask_app.py
(curl path passthrough)
curl --path-as-is -i http://127.0.0.1:5050/static/../flask_app.py
- Observe that the response body contains Python source code from
flask_app.py.
Impact
- Vulnerability type: Directory Traversal / Local File Read
- Affected users: Anyone with network access (no authentication required)
- Scope: Source files under
/app/changedetectionio - Security impact: Internal logic exposure can aid further exploitation (Confidentiality: Low)
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 🐍PyPI | changedetection-io | all versions | 0.53.2pip install --upgrade 'changedetection-io==0.53.2' |
Affected Products
changedetectionwebtechnologiesDetection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for changedetection-io, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Fix
Update changedetection-io to 0.53.2 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-25527 is resolved across your whole dependency graph.
Workarounds
Resolve every user-supplied path to its canonical form and reject anything that escapes the intended directory, and run the component under an account that has no read or write access outside the directory it legitimately serves.
How to detect CVE-2026-25527
A community-maintained Nuclei template exists for this CVE. You can scan for it directly:
nuclei -id cve-2026-25527 -u https://target- Template
- changedetection.io <= 0.52.9 - Unauthenticated Path Traversal
- Severity
- medium
- Impact
- Unauthenticated attackers can read local application source files, potentially exposing sensitive information.
Template by ProjectDiscovery nuclei-templates (WRG-11), MIT licensed. View the full template. Scan only systems you are authorised to test.
Frequently Asked Questions
Is CVE-2026-25527 in your dependencies?
Find it across PyPI, including transitive dependencies.