If you use SillyTavern from your phone or another PC, check three things now: the SillyTavern version, whether your Node.js has the 2026-10-21 security patch, and privateAddressWhitelist in config.yaml. The Node bug, CVE-2026-111497, went onto CISA's list of actively exploited vulnerabilities on 2026-10-27, and the official Docker image latest still ships an unpatched Node as of 2026-10-28.
This is a checklist for people who run SillyTavern, the self-hosted LLM chat frontend, with listen: true and reach it from other devices. On 2026-10-28 I ran 1.17.0 and 1.19.0 on my Mac, and ran the same commands on six Node versions to find a check that tells patched from unpatched builds.
I build backends in Node, and I was unpatched that morning too. My Mac was on v24.21.0, and all three Node versions on my Windows machine were pre-patch.
Without access control, SillyTavern refuses to start with listen: true
On 1.19.0 I turned off both the whitelist and Basic auth and started the server with listen: true. It printed one line and exited with code 1:
Your current SillyTavern configuration is insecure (listening to non-localhost). Enable whitelisting, basic authentication or user accounts.
So if you already use it remotely, you probably have at least one access control switched on. The exception is securityOverride: true. With that value the server only logs a warning and starts anyway.
The line to watch is the warning you get once the whitelist is on. It is a Warning: line saying the private address filter is off. The filter arrived in 1.18.0 and is off by default, so the warning shows up on every start.
The Blocked connection from line at the bottom of the capture is a connection the whitelist rejected. I connected to the same Mac through its LAN address and got a 403. That line comes back later, in the log check.
All 11 SillyTavern CVEs of 2026 are fixed in 1.18.0
SillyTavern had 11 CVEs published in 2026. I counted them on 2026-10-28 by pulling every GitHub Security Advisory with gh api. 1.16.0 fixed one, 1.17.0 fixed four, and 1.18.0 fixed six. Anything older than 1.18.0 is exposed to at least six of them.
| CVE | Fixed in | What it is | GHSA severity | No auth needed |
|---|---|---|---|---|
| CVE-2026-26286 | 1.16.0 | SSRF in asset download | high | no vector listed |
| CVE-2026-34522 | 1.17.0 |
/api/chats/import path traversal (file write) |
high 8.1 | no |
| CVE-2026-34523 | 1.17.0 | Static file existence oracle | medium 5.3 | yes |
| CVE-2026-34524 | 1.17.0 |
/api/chats/export and delete path traversal |
high 8.3 | no |
| CVE-2026-34526 | 1.17.0 |
/api/search/visit SSRF (incomplete validation) |
medium 5.0 | no |
| CVE-2026-44648 | 1.18.0 | Existing sessions survive a password change | high 7.5 | yes (user interaction) |
| CVE-2026-44649 | 1.18.0 | Authentication bypass via SSO headers | critical 9.8 | yes |
| CVE-2026-44650 | 1.18.0 | Path traversal in extension deletion | critical 9.1 | yes |
| CVE-2026-44651 | 1.18.0 | Reflected XSS in the CORS proxy | medium | no vector listed |
| CVE-2026-44652 | 1.18.0 | SSRF in the CORS proxy | medium | no vector listed |
| CVE-2026-46372 | 1.18.0 | SSRF in the SearXNG search proxy | high 8.5 | no |
The "No auth needed" column comes from whether the GHSA's CVSS vector says PR:N. The most urgent one is CVE-2026-44650. It is critical 9.1 and needs no login. CVE-2026-44649 scores 9.8, but it only applies if you turned on SSO header authentication.
The two CORS proxy bugs only matter if you enabled enableCorsProxy. Its default is false. The GHSAs include reproduction steps; I'm not repeating them here.
Four of this year's CVEs are SSRF. The maintainers' answer was to add privateAddressWhitelist in 1.18.0, as written in GHSA-qg89-qwwh-5f3j. They also said future SSRF reports will only be accepted if they bypass that filter. In other words, turning the filter on is now your job.
One more for background. CVE-2025-59159, from 2025-10, is a DNS rebinding bug rated critical 9.6. 1.13.4 added the hostWhitelist setting to block it. That setting is also off by default.
Node2Shell (CVE-2026-111497) reaches SillyTavern through the responses it fetches
Node.js fixed CVE-2026-111497 in its 2026-10-21 security release and rated it High. The advisory title is "Brotli decoder out-of-bounds write permits remote code execution". If an application decompresses Brotli data from someone else with node:zlib, process memory can get corrupted.
| Item | Details (checked 2026-10-28) |
|---|---|
| Patched versions | v22.23.4, v24.22.1, v26.12.1 |
| No patch | 20.x (EOL 2026-04-30), 25.x (EOL 2026-06-01) |
| Scores | nodejs.org High, NVD CVSS 4.0 9.2 |
| Root cause | The Google Brotli decoder bundled in Node |
| KISA (Korea) Node.js advisory, 10-23 | Lists 3 other CVEs, not this one |
| Exploitation | Added to CISA KEV 2026-10-27, remediation due 2026-11-10 |
Node2Shell is a community nickname; it appears on neither nodejs.org nor NVD. Searching by the CVE number gets you the right results. KISA is Korea's national internet security agency, and its Boho-nara site publishes Korean-language security advisories. If you only read the KISA notice, you miss this one.
Read the nodejs.org advisory itself. As of 2026-10-28, it does not mention any exploitation.
CISA added this CVE to its KEV (Known Exploited Vulnerabilities) catalog on 2026-10-27. NVD shows the same date and an SSVC exploitation: active entry. The KEV entry names Google Brotli as the product. Neither source says the exploitation targeted SillyTavern or Node.js.
SillyTavern sends requests to whatever API address you configure. I pointed it at a small server on my Mac that logs request headers, and this is what arrived:
{"method":"GET","url":"/v1/models","headers":{"accept":"*/*","accept-encoding":"gzip, deflate, br","authorization":"Bearer","user-agent":"node-fetch","host":"127.0.0.1:18080","connection":"close"}}
accept-encoding includes br. In 1.19.0, 30 files under src use node-fetch. node-fetch 3.3.2 decodes br responses with zlib.createBrotliDecompress(). The global fetch uses the same decoder.
Incoming request bodies are a different story. body-parser 1.20.4 only inflates deflate and gzip, and answers br with a 415. So the path to this bug is the responses SillyTavern fetches. API endpoints, the search proxy and asset URLs all count.
I did not send a malicious Brotli response; I stopped at headers and source code. If you use an API proxy whose operator you don't know, I'd treat the Node patch as more urgent.
process.versions.brotli can't tell you whether you're patched
Check the patch with node -v. If that leaves you unsure, a single zlib constant settles it. I ran the same commands on six Node versions:
process.versions.brotli reads 1.2.0 on both v24.21.0 and v24.22.1. The 22 line shows 1.1.0 before and after the patch. That's because Node did not upgrade the library; it cherry-picked the one fix.
The BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH constant is what differs. The three patched builds have it and the three unpatched builds don't. So don't use process.versions.brotli for this check.
I ran the same check on my Windows machine. Node there is managed by fnm, which I installed with winget. All three installed versions returned false for the constant. Over a remote shell, node wasn't found at all, because the PowerShell profile is what puts fnm on the PATH.
The official Docker image latest ships Node 24.21.0 as of 2026-10-28
I checked the registry metadata. The official latest and 1.19.0 images were both built on 2026-09-14. The NODE_VERSION in both image configs is 24.21.0.
| Tag | Built | Bundled Node |
|---|---|---|
latest (release) |
2026-09-14 | 24.21.0 |
1.19.0 |
2026-09-14 | 24.21.0 |
staging |
2026-10-28 | 24.22.1 |
Docker Hub node:lts-alpine3.23
|
2026-10-21 | 24.22.1 |
The official docs say "No action required" for Docker. That only holds once the image is rebuilt. Pulling latest again today gets you the same image.
The Dockerfile starts from node:lts-alpine3.23. That base image was rebuilt with 24.22.1 on 10-21. I expect a build from source to pick up the patched Node. staging is the development branch, so feature changes come along with it.
Check two versions, six settings and one log, in that order
1. Check the SillyTavern version
Look for a line like SillyTavern 1.19.0 at the top of the startup log; it should say 1.18.0 or later. The server prints it before it accepts any request, so you see it whatever your auth settings are.
On a local server without access control, pkgVersion in the /version response works too. With Basic auth on, this request gets a 401. Don't trust isLatest in the same response, because it doesn't query the remote. The request:
curl -s http://127.0.0.1:8000/version
2. Check Node
Run these in the same terminal you start SillyTavern from. The Node version: line at the top of the startup log shows the same value:
node -v
node -p "'BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH' in require('zlib').constants"
true means a patched build. For Docker, use docker exec <container-name> node -v.
3. Update Node
The route depends on how you installed it. The commands are from the official Node update docs, except the fnm row, which I added:
| Install method | Commands |
|---|---|
| nvm (macOS, Linux) |
nvm install --lts, then nvm use --lts
|
| nvm-windows |
nvm install lts, then nvm use lts
|
| fnm |
fnm install 24.22.1, then fnm use 24.22.1 and fnm default 24.22.1
|
| Windows winget | winget install --id=OpenJS.NodeJS.LTS -e |
| Homebrew |
brew update, then brew upgrade node
|
| Termux |
pkg update, then pkg upgrade nodejs-lts
|
| Docker | Rebuild from source, or wait for a new image |
After updating, run check 2 again and restart SillyTavern. With fnm, changing only fnm default leaves the current shell on its old Node. In my run, the shell only switched to v24.22.1 after fnm use.
4. Update SillyTavern to 1.19.0
Since 1.17.0, engines requires >= 20, so update Node first.
5. Check six config.yaml entries
Defaults are from default/config.yaml in 1.19.0.
| Key | Default | For remote access | Why |
|---|---|---|---|
whitelistMode, whitelist
|
true, ::1 and 127.0.0.1
|
Keep on, add only your phone's or VPN's address | Anything outside the whitelist gets a 403 |
basicAuthMode, basicAuthUser
|
false, user/password
|
Turn on and change the default password | The default credentials are public |
privateAddressWhitelist.enabled |
false |
true |
Covers the 4 SSRFs; the maintainers' recommendation |
hostWhitelist.enabled |
false |
true, list the host names you use |
The setting that addresses CVE-2025-59159 |
enableCorsProxy |
false |
Keep false
|
CVE-2026-44651, CVE-2026-44652 |
securityOverride |
false |
Keep false
|
Disables the startup check |
The official docs recommend a VPN or a tunnel over port forwarding. If you're going to expose it straight to the internet anyway, get every row of this table right first.
6. If an LLM server runs elsewhere on your LAN, add its range to allowedRanges
By default the filter only allows loopback. A request to a backend on another PC gets blocked like this:
[Private Request Filter] Blocked request to private IP address: <LAN-IP>
FetchError: request to http://<LAN-IP>:9/v1/models failed, reason: Blocked request to private IP address: <LAN-IP>
After I added 10.0.0.0/8, the same request passed the filter and failed with ECONNREFUSED instead. Keep the range as narrow as the addresses you actually use.
7. Check the logs
access.log in the data folder records only connections that got through, once per IP. Connections the whitelist blocked appear only as Blocked connection from lines in the console. Basic auth returns 429 for 60 seconds starting from the sixth failure. During that window even the correct password is refused, and the console logs a Basic auth failed: Rate limited from line.
Takeaways
As of 2026-10-28, a SillyTavern you reach from other devices needs 1.18.0 or later for this year's 11 CVEs, a Node build that has the BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH constant (v22.23.4, v24.22.1, v26.12.1), and privateAddressWhitelist.enabled: true. The official Docker latest image still carried Node 24.21.0 that day, so pulling it again doesn't fix the Node side.
Unverified
Node updates on Termux (Android) installs: I have no device to run them on. The commands in the table are copied from the official docs.
The message you get when starting 1.17.0 or later on Node below 20: I didn't check it, because I didn't download a Node 18 binary. I only confirmed from the source that server.js has no version check.
node -v inside a container and the Node version of a self-built image: I couldn't check either, because this Mac has no Docker runtime. I used NODE_VERSION from the image config instead.
hostWhitelist blocking behavior: I didn't run it. I only confirmed the default value from the source.
The real effect of a malicious Brotli response on SillyTavern: I deliberately did not reproduce it. I stopped at the headers and the decoder path.
Brotli decoding paths in extensions and server plugins: I didn't trace them. I only looked at the core src.
Real-world exploitation targeting SillyTavern: I couldn't confirm any. CISA KEV and NVD only say the Brotli decoder was exploited. I couldn't independently confirm claims made in security vendors' posts either.
The CVSS 3.1 9.8 score for CVE-2026-111497: it appears only on some aggregator sites. NVD doesn't list it, so this post uses CVSS 4.0 9.2.
The update path for the winget Node.js LTS package: I didn't run it, because that package wasn't installed on my Windows machine. I didn't run the upgrade either.
Changelog
| Version | Description |
|---|---|
| 1.0 | 2026-10-28 first version (version checks on SillyTavern 1.17.0 and 1.19.0 and on six Node versions, four config startups, Docker image metadata, Windows fnm check, fnm switch, NVD and KEV lookup) |
AI disclosure: translated and edited with AI assistance (Claude) from my Korean original. Measurements were run with Claude Code under my supervision; I reviewed the result.


Top comments (0)