TavernKeeper Scan Report

selinawynters-ops/ParamSentinel

Commit 8b5eb44 Reviewed

No material or immediate-danger concern was identified in this review.

This advisory report describes what the named tools and review process found at one exact commit. Unknown or unobserved behavior may still exist.

0 immediate danger 0 material 8 low

What this review found

No material or immediate-danger item was identified.

Deterministic technical evidence (1)
  • JavaScript analysis reported javascript.xray.shady-link · javascript-analysis webcrack-2.16.0_js-x-ray-16.0.0_signatures-1_literals-1_families-1

    This technical signal is not part of the shipped runtime behavior.

    Policy reason: javascript-xray-inert-content · Execution scope: test-documentation-data

    Source: tests/server-plugin.test.js:17

Contextual expected matches (4)

JavaScript analysis reported javascript.xray.shady-link

Expected behavior · high confidence

The scanner flagged a line that is simply assembling a status message for the user interface. There is no suspicious or external link involved.

Technical evidence

Scanner reason: JavaScript analysis matched static JavaScript security signal javascript.xray.shady-link. The match applies to this repository.

Contextual assessment: The flagged line 447 is inside a template literal building a UI status string from inconclusive probe results: `e: ${inconclusive.join(', ')}.`. JS-X-Ray's shady-link heuristic matched on string interpolation or literal fragments, but the actual content is local UI text with no URL, endpoint, or external destination. No network access or data exfiltration occurs at this location.

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
javascript-analysis webcrack-2.16.0_js-x-ray-16.0.0_signatures-1_literals-1_families-1
Rule
javascript.xray.shady-link
File role
production
Source
index.js:447

JavaScript analysis reported javascript.xray.shady-link

Expected behavior · high confidence

The scanner flagged a line that filters server-sent event stream lines starting with 'data:', which is standard parsing logic. There is no suspicious link or network destination at this location.

Technical evidence

Scanner reason: JavaScript analysis matched static JavaScript security signal javascript.xray.shady-link. The match applies to this repository.

Contextual assessment: Detailed technical wording was omitted by the public report safety filter.

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
javascript-analysis webcrack-2.16.0_js-x-ray-16.0.0_signatures-1_literals-1_families-1
Rule
javascript.xray.shady-link
File role
production
Source
server-plugin/index.mjs:118

Credential access and network transmission in one file

Expected behavior · high confidence

The server plugin reads the user's stored Custom API key and sends it to the Navy API endpoint the user has configured, which is exactly what the extension is designed to do. The key is not sent to any third party or hidden destination.

Technical evidence

Scanner reason: A credential source and an outbound network operation were detected in the same file.

Contextual assessment: The scanner flags that readSecret (credential access) and fetch (network sink) coexist in the same file. The actual data flow is: readSecret retrieves the user's Custom API key from SillyTavern's secret store using request.user.directories and secretKeys.CUSTOM, then the key is used as an Authorization Bearer header or x-api-key header in fetch calls to endpoints derived from getNavyMessagesUrl(payload.custom_url) or getNavyApiUrl(payload.custom_url). The custom_url originates from the user's SillyTavern oai_settings.custom_url. This is the documented companion adapter behavior: reusing the stored Custom API key to proxy Claude Opus 5 requests through Navy's Anthropic Messages endpoint. The key is never logged, persisted in extension settings, or sent to any destination other than the user's configured Navy API endpoint. The README explicitly states 'the key never enters browser extension settings.'

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
tavernkeeper 5
Rule
credential-exfiltration
File role
production
Source
server-plugin/index.mjs:307

JavaScript analysis reported javascript.download-to-execution

Expected behavior · high confidence

The extension intercepts network requests inside the browser to route certain generations through a companion plugin and learn from API errors. All network destinations are local SillyTavern API paths, and this behavior matches the stated purpose. There is no hidden code execution or data theft.

Technical evidence

Scanner reason: JavaScript analysis matched static JavaScript security signal javascript.download-to-execution. The match applies to this repository.

Contextual assessment: The file contains both fetch calls and a window.fetch override (installFetchObserver). All fetch destinations are local SillyTavern-relative paths: RULES_URL, GENERATE_ENDPOINT, COMPANION_GENERATE_ENDPOINT, and NAVY_PROBE_ENDPOINT. The fetch override intercepts generation requests to optionally route them through the companion plugin and inspect error responses for parameter-compatibility learning. This is not dynamic code execution (no eval, Function constructor, or similar sink) — it is a fetch interception pattern that matches the extension's documented purpose of auto-disabling unsupported sampler parameters. No data is sent to external or undisclosed destinations.

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
javascript-analysis webcrack-2.16.0_js-x-ray-16.0.0_signatures-1_literals-1_families-1
Rule
javascript.download-to-execution
File role
production
Source
index.js:68-465

Related contextual observations

window.fetch override is an interception wrapper, not a concealed execution sink

low risk · high confidence

The extension replaces the browser fetch function to observe and optionally redirect generation requests, which is a normal pattern for SillyTavern extensions that need to intercept or augment API calls.

Technical assessment

installFetchObserver overrides window.fetch to wrap generation requests. It first tries the companion plugin route, then falls back to the original fetch. On error responses it inspects the body to learn unsupported parameters. The original fetch reference is preserved and used for all actual network calls, so no requests are sent to undisclosed destinations. This is a transparent interception pattern consistent with the extension's stated learning-from-errors tier.

Impact: none · Exploitability: unlikely

Developer action: none

Sources:

Server plugin does not re-validate custom_url as a Navy endpoint

low risk · medium confidence

The server plugin trusts the custom URL from the request without verifying it points to a Navy endpoint. Since the plugin runs locally, this is a low-risk gap, but adding server-side validation would be good practice.

Technical assessment

The /navy/probe and /generate endpoints accept payload.custom_url from the request body and pass it to getNavyApiUrl or getNavyMessagesUrl without server-side hostname validation. The browser-side file checks isNavyConnection (hostname === 'api.navy') before calling the probe, but the server plugin itself does not repeat this check. A local user who can POST to the plugin endpoint with a crafted custom_url could theoretically redirect the API key to an arbitrary host. However, SillyTavern server plugins run locally and require explicit enablement, limiting this to a self-SSRF scenario with low concrete harm.

Impact: low · Exploitability: unlikely

Developer action: Consider validating that custom_url resolves to a Navy API hostname on the server side, mirroring the isNavyConnection check that the browser-side code already performs, to prevent a local attacker from redirecting the API key to an arbitrary URL via a crafted plugin request.

Sources:

API key transmitted to user-configured endpoint without server-side Navy hostname validation

low risk · medium confidence

The server plugin sends the API key to whatever URL is in the request without independently confirming it is a Navy endpoint. This is low risk because the plugin runs locally, but server-side validation would close the gap.

Technical assessment

In the /generate route, the API key read via readSecret is sent as x-api-key to the endpoint returned by getNavyMessagesUrl(payload.custom_url). The server plugin does not independently validate that custom_url points to a Navy hostname. The browser-side code checks isNavyConnection before invoking the plugin, but a direct POST to the local plugin endpoint with a crafted custom_url could redirect the key elsewhere. This is a local self-SSRF concern with limited exposure since ST plugins are localhost-only and require explicit enablement.

Impact: low · Exploitability: unlikely

Developer action: Consider adding server-side hostname validation for custom_url in both plugin routes to ensure it resolves to a Navy API endpoint, matching the browser-side isNavyConnection guard.

Sources:

Coverage and limitations

JavaScript coverage

Tools

Limitations

Technical scan identity