The app uses system commands to hide its encryption-key file so casual users do not accidentally see or delete it. The file path is hardcoded and not influenced by user input, so this is not exploitable. However, building shell commands by pasting strings together is a sloppy pattern that could become dangerous if reused with untrusted input.
Technical evidence
Scanner reason: OpenGrep matched static-analysis rule tavernkeeper.dynamic-execution.node-shell. The match applies to this repository.
Contextual assessment: Line 61 contains execSync('chflags hidden + filePath') inside the hideFile function. The filePath argument is always SECRET_FILE, which is path.join(__dirname, '.appdata') — a hardcoded local path with no user-controlled component. The command sets the macOS hidden flag on the encryption-key file, consistent with the project's documented AES-256-GCM key-at-rest encryption. The risk is limited to a theoretical command-injection concern from string interpolation into a shell command, but since the input is a fixed filesystem path derived from __dirname, there is no demonstrated attacker-controlled path to exploitation.
Impact: low · Exploitability: unlikely
Developer action: Consider replacing execSync string concatenation with execFileSync using an argument array (e.g., execFileSync('chflags', ['hidden', filePath])) to eliminate any future risk if the function is ever called with less-trusted input.
The app uses a Windows system command to hide its encryption-key file. The file path is hardcoded and not influenced by user input, so this is not exploitable. The string-pasting pattern is a minor code-quality concern only.
Technical evidence
Scanner reason: OpenGrep matched static-analysis rule tavernkeeper.dynamic-execution.node-shell. The match applies to this repository.
Contextual assessment: Line 59 contains execSync('attrib +h + filePath') inside the hideFile function, targeting the Windows platform branch. The filePath argument is always SECRET_FILE (path.join(__dirname, '.appdata')), a hardcoded path with no user-controlled input. The command sets the Windows hidden attribute on the encryption-key file, consistent with the project's documented at-rest encryption of API keys. No attacker-controlled data reaches the command string; the concern is limited to the anti-pattern of string-interpolated shell commands.
Impact: low · Exploitability: unlikely
Developer action: Consider replacing execSync string concatenation with execFileSync using an argument array (e.g., execFileSync('attrib', ['+h', filePath])) to eliminate any future risk if the function is ever called with less-trusted input.
The app uses a Linux system command to restrict permissions on its encryption-key file so only the owner can read it. The file path is hardcoded and not influenced by user input, so this is not exploitable. The string-pasting pattern is a minor code-quality concern only.
Technical evidence
Scanner reason: OpenGrep matched static-analysis rule tavernkeeper.dynamic-execution.node-shell. The match applies to this repository.
Contextual assessment: Line 64 contains execSync('chmod 600 + filePath') inside the hideFile function, targeting the Linux platform branch. The filePath argument is always SECRET_FILE (path.join(__dirname, '.appdata')), a hardcoded path with no user-controlled input. The command restricts file permissions to owner-only on the encryption-key file, consistent with the project's documented at-rest encryption of API keys. No attacker-controlled data reaches the command string; the concern is limited to the anti-pattern of string-interpolated shell commands.
Impact: low · Exploitability: unlikely
Developer action: Consider replacing execSync string concatenation with execFileSync using an argument array (e.g., execFileSync('chmod', ['600', filePath])) to eliminate any future risk if the function is ever called with less-trusted input.
A crafted input might briefly slow or freeze the local client, without showing broader security harm.
Technical evidence
Scanner reason: JavaScript analysis matched static JavaScript security signal javascript.xray.unsafe-regex. The match applies to this repository.
Contextual assessment: The expression may permit a local CPU slowdown, but this evidence shows no credential, persistence, code-execution, or cross-user impact.
Impact: low · Exploitability: plausible
Developer action: Bound the input length or replace the expression when practical.
The tool flagged network URLs in the code, but they are all standard addresses for the AI services and local tools the app is designed to talk to. No suspicious or unknown destinations were found.
Technical evidence
Scanner reason: JavaScript analysis matched static JavaScript security signal javascript.xray.shady-link. The match applies to this repository.
Contextual assessment: The JS-X-Ray shady-link signal fired at line 20, but the visible source shows only standard require() statements and configuration defaults. The URLs present in the code are well-known service endpoints (api.openai.com, api.x.ai, localhost:5001 for KoboldCPP, 127.0.0.1:8188 for ComfyUI, openrouter.ai) that directly match the project's stated purpose of a multi-backend character card generator. No evidence of data being sent to unrecognized, obfuscated, or suspicious destinations. The scanner did not retain matched literal values, and the actual code context shows no exfiltration behavior.
Impact: none · Exploitability: unlikely
Developer action: No change required for this candidate. The flagged network endpoints are standard model-provider and local-service URLs matching the project's documented multi-backend character generation purpose.
The tool flagged what looked like environment-variable access, but the code only reads the standard PORT setting to decide which port the local server listens on. No sensitive data is collected or sent anywhere.
Technical evidence
Scanner reason: JavaScript analysis matched static JavaScript security signal javascript.xray.serialize-environment. The match applies to this repository.
Contextual assessment: Detailed technical wording was omitted by the public report safety filter.