Decorator ordering disables auth on changedetection.io backup routes
TL;DR — A Flask decorator-ordering bug in changedetection.io can register routes without the intended auth wrapper, enabling unauthenticated access to sensitive endpoints like backup listing/download.
What happened
changedetection.io is a self-hosted, open-source web application that monitors web pages for changes and sends notifications. CVE-2026-35490 describes a Critical authentication bypass caused by incorrect Flask decorator ordering: the @login_optionally_required decorator is placed outside @blueprint.route() on certain handlers.
In Flask, @route() must be the outermost decorator because it registers the function it receives. With the order reversed, Flask registers the original (undecorated) handler, and the authentication wrapper is never invoked — effectively silently disabling authentication on the affected routes.
The linked advisory describes this affecting 13 routes across 5 blueprint files, with a working proof-of-concept showing unauthenticated access to backup-related functionality (e.g., triggering backup creation, listing backups, downloading backups, and removing backups) without any session cookie.
| Item | Source value |
|---|---|
| Affected product | changedetection.io |
| Affected versions | < 0.54.8 |
| Severity | CVSS v3.1 9.8 (Critical) |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| Fix status | "This vulnerability is fixed in 0.54.8." |
Auth bypasses caused by framework integration mistakes are especially dangerous because they look like “normal” routes in code review and often ship without obvious functional regressions — until an attacker finds the one handler where the guardrail isn’t actually in the call chain.
Who is impacted
- Deployments running
changedetection.ioversions< 0.54.8. - Instances where operators enabled authentication expecting routes to be protected, especially if the service is reachable from untrusted networks (internet-exposed, shared internal networks, or multi-tenant/self-service environments).
- Environments that store sensitive data in
changedetection.io(watched URL lists, notification/webhook configuration, backups, and other application configuration) where unauthenticated backup access can become a direct data exfiltration path. - Teams relying on
changedetection.ioas an “internal-only” utility: this class of bug is a reminder that a single route-level guard failure can invalidate the security assumptions of the whole UI/API surface.
What to do now
- Follow vendor remediation guidance and apply the latest patched release available at the time of writing.
"This vulnerability is fixed in 0.54.8."
- If you must run an affected version while assessing impact, reduce exposure:
- restrict network access to the service (VPN, allowlists, private ingress)
- consider temporarily disabling or tightly controlling backup-related routes/features if you have an operational kill switch at your ingress layer
- Treat this as potential unauthorized-access exposure and triage accordingly:
- review access logs for unauthenticated requests hitting backup-related paths (listing/download/remove) and other affected endpoints
- if backups may have been accessed, rotate secrets that could plausibly be present in backups/config (e.g., notification webhook URLs/tokens and any credentials stored by the app)
- If you maintain Flask apps internally, add a code review check for decorator ordering on route handlers (security decorators must be in the call chain of the registered view), since this failure mode is easy to introduce during refactors.
Content is AI-assisted and reviewed by our team, but issues may be missed and best practices evolve rapidly, send corrections to [email protected]. Always consult official documentation and validate key implementation decisions before making design or security choices.
