GHSA-VFFH-C9PQ-4CRH
Vulnerability from github – Published: 2025-10-20 20:03 – Updated: 2025-10-20 20:03Summary
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:
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():
// 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
- Open Uptime Kuma → Notifications → Add or Edit an existing Webhook notification.
- Set notification type to Webhook and set Request Body to Custom Body.
- Paste the following JSON into the custom request body:
{
"Title": {% render '/etc/passwd' %}
}
- Click test.
- 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.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "uptime-kuma"
},
"versions": [
"2.0.0-dev.0"
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-1336",
"CWE-36"
],
"github_reviewed": true,
"github_reviewed_at": "2025-10-20T20:03:15Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "### Summary\n\nIn 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.\n\n\n\n### Details\n\nThe 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:\n\n```js\nasync renderTemplate(template, msg, monitorJSON, heartbeatJSON) {\n const engine = new Liquid();\n const parsedTpl = engine.parse(template);\n\n // ...\n}\n```\n\nIn some Notification flows, the `send()` implementation passes user-editable fields directly into `renderTemplate()`:\n```js\n// webhook.js\nif (notification.webhookContentType === \"form-data\") {\n const formData = new FormData();\n formData.append(\"data\", JSON.stringify(data));\n config.headers = formData.getHeaders();\n data = formData;\n} else if (notification.webhookContentType === \"custom\") {\n data = await this.renderTemplate(notification.webhookCustomBody, msg, monitorJSON, heartbeatJSON); //\u003c- this line cause SSTI\n}\n```\n\nBecause `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\u2019s 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.\n\n\n\n### PoC\n\n1. Open Uptime Kuma \u2192 **Notifications** \u2192 **Add** or **Edit** an existing Webhook notification.\n2. Set notification type to **Webhook** and set **Request Body** to **Custom Body**.\n3. Paste the following JSON into the custom request body:\n\n```json\n{\n \"Title\": {% render \u0027/etc/passwd\u0027 %}\n}\n```\n\n4. Click test.\n5. Your webhook will receive the file content\n\n\n\n### Impact\n\nThis is a post-authentication Server-side Template Injection (SSTI) vulnerability that allows an authenticated user to perform arbitrary file read on the server.",
"id": "GHSA-vffh-c9pq-4crh",
"modified": "2025-10-20T20:03:15Z",
"published": "2025-10-20T20:03:15Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/louislam/uptime-kuma/security/advisories/GHSA-vffh-c9pq-4crh"
},
{
"type": "PACKAGE",
"url": "https://github.com/louislam/uptime-kuma"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
],
"summary": "Uptime Kuma Server-side Template Injection (SSTI) in Notification Templates Allows Arbitrary File Read"
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.