changedetection.io Authentication Bypass via Flask Decorator Misordering
changedetection.io is vulnerable to authentication bypass due to incorrect decorator ordering in Flask routes, allowing unauthenticated access to backup functionalities and potentially leading to data exfiltration of sensitive information.
changedetection.io versions 0.54.7 and earlier contain an authentication bypass vulnerability affecting 13 routes across 5 blueprint files. The vulnerability stems from the @login_optionally_required decorator being incorrectly placed before the @blueprint.route() decorator in Flask route definitions. This misconfiguration prevents the authentication wrapper from being applied to the affected routes, effectively disabling authentication checks. This allows unauthenticated users to access sensitive functionalities, like backups, which would normally require authentication. This issue is due to an inconsistency in the application of decorators, as other routes correctly implement the proper decorator order. Successful exploitation allows attackers to extract sensitive data such as watched URLs, notification webhook URLs including API tokens, and configuration data.
Attack Chain
- An unauthenticated attacker sends a request to
/backups/request-backupto trigger a backup creation. - The server, without proper authentication, creates a new backup and redirects the user to
/backups/. - The attacker then accesses
/backups/to list all available backups. This route is also exposed. - The attacker parses the HTML response from
/backups/to identify the filenames of the created backups, specifically looking for entries matchingchangedetection-backup. - The attacker sends a request to
/backups/download/<filename>with the identified backup filename to download the backup. Again, no authentication is required. - The server delivers the requested ZIP archive containing sensitive application data.
- The attacker extracts the downloaded backup and obtains sensitive information, including
url-watches.json,secret.txt(Flask secret key), and other configuration files. - As a final step, the attacker can trigger the
/backups/remove-backupsendpoint which deletes all the backup files on the server.
Impact
Successful exploitation of this vulnerability allows for complete data exfiltration of sensitive information stored within application backups. This includes monitored URLs, notification webhook URLs, API tokens (for services like Slack and Discord), and the Flask secret key. An attacker could use the exfiltrated Flask secret key to craft malicious sessions. The ability to download backups also allows for configuration injection, potentially leading to remote code execution. The application may also be susceptible to SSRF attacks via the proxy check endpoint if authentication is bypassed. This flaw can also lead to browser session hijacking by manipulating Playwright sessions.
Recommendation
- Apply the provided remediation by swapping the order of the decorators on the 13 affected routes, ensuring that
@blueprint.route()is the outermost decorator (see Remediation section in the source). - Monitor web server logs for requests to the affected
/backups/routes without valid authentication credentials (e.g., missing session cookies or tokens). Use category "webserver" and product "linux" or "windows" with appropriate filters to detect unauthenticated requests to/backups/*. - Deploy the provided Sigma rule to detect successful downloads from the affected route
/backups/download/<filename>.
Detection coverage 2
Detect changedetection.io Backup Download Without Authentication
highDetects attempted or successful download of a changedetection.io backup file without authentication based on HTTP status code 200 on affected route.
Detect changedetection.io Backup Request Without Authentication
mediumDetects attempted backup creation without authentication based on HTTP status code 302 on affected route.
Detection queries are available on the platform. Get full rules →
Indicators of compromise
1
domain
| Type | Value |
|---|---|
| domain | changedetection.io |