GHSA-VFFH-C9PQ-4CRH

Vulnerability from github – Published: 2025-10-20 20:03 – Updated: 2025-10-20 20:03
VLAI
Summary
Uptime Kuma Server-side Template Injection (SSTI) in Notification Templates Allows Arbitrary File Read
Details

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:

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

  1. Open Uptime Kuma → NotificationsAdd 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:
{
  "Title": {% render '/etc/passwd' %}
}
  1. Click test.
  2. 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.

Show details on source website

{
  "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"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

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.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…