Uptime Kuma Server-side Template Injection (SSTI) in Notification Templates Allows Arbitrary File Read
Key facts
- Attack vector
- —
- Privileges required
- —
- User interaction
- —
- Attack complexity
- —
- Impact type
- Code execution
- Confidentiality · integrity · availability
- —
- Fix status
- No fix listed
No CVSS vector from any source. Fix status from GitHub. Impact type from CWE-1336.
Summary
### Summary In some Notification types (e.g., Webhook, Telegram), the `send()` function allows user-controlled renderTemplate input. This leads to a Server-side Template Injection (SSTI) vulnerability that can be exploited to read arbitrary files from the server. ### Details The root cause is how Uptime Kuma renders user-controlled templates via `renderTemplate()`. The function instantiates a Liquid template engine and parses the `template` argument without sanitization: ```js async renderTemplate(template, msg, monitorJSON, heartbeatJSON) { const engine = new Liquid(); const parsedTpl = engine.parse(template); // ... } ``` In some Notification flows, the `send()` implementation passes user-editable fields directly into `renderTemplate()`: ```js // webhook.js if (notification.webhookContentType === "form-data") { const formData = new FormData(); formData.append("data", JSON.stringify(data)); config.headers = formData.getHeaders(); data = formData; } else if (notification.webhookContentType === "custom") { data = await this.renderTemplate(notification.webhookCustomBody, msg, monitorJSON, heartbeatJSON); //<- this line cause SSTI } ``` Because `notification` can be edited by users and is rendered by the Liquid engine without proper sandboxing or a whitelist of allowed operations, an attacker can supply a crafted template that causes the server to read arbitrary files. In particular, Liquid’s template tags (e.g. `{% render ... %}`) can be abused to include server-side files if the engine is not restricted, resulting in Server-side Template Injection (SSTI) that leaks sensitive file contents. ### PoC 1. Open Uptime Kuma → **Notifications** → **Add** or **Edit** an existing Webhook notification. 2. Set notification type to **Webhook** and set **Request Body** to **Custom Body**. 3. Paste the following JSON into the custom request body: ```json { "Title": {% render '/etc/passwd' %} } ``` 4. Click test. 5. Your webhook will receive the file content ### Impact This is a post-authentication Server-side Template Injection (SSTI) vulnerability that allows an authenticated user to perform arbitrary file read on the server.
Why it matters now
SSVC decision points
Not available: CISA has not published SSVC decision points for this record.
Affected products
| Vendor | Product | Affected versions | Fixed in | Status | Source |
|---|---|---|---|---|---|
| — | uptime-kuma (npm) | — | — | No fix listed | GHSA-vffh-c9pq-4crh |
- uptime-kuma (npm) Vendor— Affected — Fixed in — No fix listed GHSA-vffh-c9pq-4crh
Remediation
No fixed version listed by the sources yet.
Timeline
- 2026-10-03 Threatist record created from GHSA-vffh-c9pq-4crh
References
Sources
This product uses the NVD API but is not endorsed or certified by the NVD. Sources and licences