The scanner flagged a line that emits an internal event for tag-category assignment. This is normal UI event handling with no network calls or suspicious behavior.
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.
The code in this file is normal, readable JavaScript with clear comments and naming. There is no hidden or obfuscated code. The scanner flag is a false positive.
Technical evidence
Scanner reason: JavaScript analysis matched static JavaScript security signal javascript.xray.obfuscated-code. The match applies to this repository.
Contextual assessment: The scanner reports a low-confidence obfuscated-code signal at line 1. The supplied source is plainly readable, well-structured JavaScript with standard ES module imports, JSDoc comments, clear variable names, and no minification, packing, string encoding, or control-flow flattening. No obfuscation techniques are present in the reviewed code.
The extension sends character creation data to the local SillyTavern server and receives back an avatar identifier. Nothing downloaded from the network is executed as code. This is exactly what a character creation feature should do.
Technical evidence
Scanner reason: JavaScript analysis matched static JavaScript security signal javascript.download-to-execution. The match applies to this repository.
Contextual assessment: The flagged range contains a fetch call to /api/characters/create, which is a same-origin POST that submits FormData (character fields and an avatar file) to the SillyTavern server. The response is used only as text representing the new avatar identifier. No response data reaches eval, Function, innerHTML, or any dynamic execution sink. The getBase64Async call reads a user-selected local file for avatar preview. There is no network-retrieved code being executed.
The extension checks whether an optional avatar-editing plugin is installed by pinging a local SillyTavern API endpoint. The response is only used as a yes/no check. No downloaded code is ever executed. This is normal, expected behavior for a character management extension.
Technical evidence
Scanner reason: JavaScript analysis matched static JavaScript security signal javascript.download-to-execution. The match applies to this repository.
Contextual assessment: The scanner correlates a network retrieval primitive with a code execution sink in the same file. The only fetch call in the flagged range is a POST to a same-origin relative endpoint (/api/plugins/avataredit/probe) that checks whether an optional plugin is available by testing for HTTP 204. No response body from this fetch is passed to eval, Function, innerHTML, or any other execution sink. The .html() calls elsewhere in the file use locally stored character metadata, not fetched remote content. There is no download-to-execution data flow.
The scanner flagged a standard 1x1 transparent placeholder image used to cancel in-flight image loads during scrolling. This is a well-known performance technique with no security implications.
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 defines a static data URI containing a 1x1 transparent GIF (a well-known base64 placeholder). This is used to cancel in-flight image loads when virtualized list items scroll out of view. The entire file implements a virtual scrolling container with DOM recycling, scroll calculations, and spacer elements. No network access, external URLs, dynamic code execution, or credential handling is present. The scanner likely matched the base64 data URI as a link-like string.
The scanner flagged a line that registers an internal event listener for tag-category operations. This is normal user-interface logic with no network calls or suspicious behavior.
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 registers a local event listener (this.eventManager.on) for the internal event tag:addTagToCat. The surrounding code manages preset and category CRUD operations via jQuery DOM handlers and local settings persistence. No network access, external URLs, dynamic code execution, or credential handling is present. The scanner signal is a false positive on an internal event name.
DOM insertion of user-controlled category and preset names uses escapeHtml
low risk · high confidence
The code builds HTML strings using template literals and inserts them into the DOM via jQuery. User-supplied names are passed through escapeHtml before insertion, which is the correct pattern for preventing injection.
Technical assessment
Preset and category names from popups are inserted into HTML via jQuery .html() and template literals, but the values are passed through escapeHtml() before rendering (e.g., escapeHtml(preset.name), escapeHtml(cat.name)). This mitigates XSS from user-controlled strings. The code is consistent with expected extension UI behavior.
Tag display uses escapeHtml for tag names but interpolates tag colors into inline styles without sanitization
low risk · high confidence
Tag names are escaped before being inserted into HTML, which is the correct approach to prevent injection. However, tag color values are inserted directly into inline styles, which is a minor weakness if an attacker can control tag colors.
Technical assessment
In displayTag, tag.name is passed through escapeHtml before insertion into the HTML template, which mitigates XSS from tag names. However, tag.color and tag.color2 are interpolated directly into inline style attributes without sanitization. These values originate from SillyTavern's tagList, which is managed through the host application's tag editor. An attacker who could inject arbitrary color values could potentially break out of the style attribute context, but this requires control of the host tag store and is not exposed via this extension's own untrusted input paths.