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.
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.
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.'
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.
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.
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.
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.