TavernKeeper Scan Report

platberlitz/sd-proxy

Commit 8af334f 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 15 low

What this review found

No material or immediate-danger item was identified.

Contextual expected matches (13)

OpenGrep reported tavernkeeper.dynamic-execution.node-shell

Expected behavior · high confidence

This runs a fixed git command to check for updates. No user input reaches the command, and the endpoint requires login. This is normal self-update behavior.

Technical evidence

Scanner reason: OpenGrep matched static-analysis rule tavernkeeper.dynamic-execution.node-shell. The match applies to this repository.

Contextual assessment: The execSync call at line 1620 invokes a static git fetch command with no user-controlled interpolation. The cwd is set to __dirname, a built-in constant. The endpoint is gated behind requireAuth. This is part of a self-update feature consistent with the project purpose.

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
opengrep 1.26.0
Rule
tavernkeeper.dynamic-execution.node-shell
File role
production
Source
server.js:1620

OpenGrep reported tavernkeeper.dynamic-execution.node-shell

Expected behavior · high confidence

This runs a fixed git command to count how many updates are behind. No user input is involved and login is required. This is normal self-update behavior.

Technical evidence

Scanner reason: OpenGrep matched static-analysis rule tavernkeeper.dynamic-execution.node-shell. The match applies to this repository.

Contextual assessment: The execSync call at line 1623 invokes a static git rev-list command with no user-controlled interpolation. The cwd is __dirname and the endpoint is auth-protected. No injection surface exists.

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
opengrep 1.26.0
Rule
tavernkeeper.dynamic-execution.node-shell
File role
production
Source
server.js:1623

OpenGrep reported tavernkeeper.dynamic-execution.node-shell

Expected behavior · high confidence

This runs a fixed git command to apply updates and then restarts the server. No user input is involved and login is required. This is normal self-update behavior.

Technical evidence

Scanner reason: OpenGrep matched static-analysis rule tavernkeeper.dynamic-execution.node-shell. The match applies to this repository.

Contextual assessment: The execSync call at line 1638 invokes a static git pull command with no user-controlled interpolation. The cwd is __dirname and the endpoint is auth-protected. The subsequent process.exit restarts the server after update, consistent with a self-update feature. No injection surface exists.

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
opengrep 1.26.0
Rule
tavernkeeper.dynamic-execution.node-shell
File role
production
Source
server.js:1638

JavaScript analysis reported javascript.xray.shady-link

Expected behavior · high confidence

The tool has built-in addresses for well-known image generation services. This is exactly what a multi-backend proxy is supposed to have.

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 signal corresponds to hardcoded default API endpoint URLs for image generation backends (OpenAI, Pollinations, NovelAI, Gemini, A1111, ComfyUI). These are well-known public service endpoints that directly match the project's stated purpose as a multi-backend image generation proxy. No obfuscated, dynamically constructed, or unexpected destinations are present in the supplied evidence.

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.js:16

Credential access and network transmission in one file

Expected behavior · high confidence

This project is a proxy that sends your image-generation API keys to the official websites of services like CivitAI, PixAI, and others so it can generate images on your behalf. That is exactly what the project is designed to do. The keys go only to the expected service providers and nowhere else.

Technical evidence

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

Contextual assessment: The scanner flagged credential access and outbound network transmission co-located in one file. The supplied source shows each backend handler reads a configured API key and transmits it solely as an Authorization header to that provider's official, well-known API endpoint (civitai.com, naistera.org, api.pixai.art, api.stability.ai, api.replicate.com, etc.). This is the core stated purpose of the project: a multi-backend image generation proxy. The credentials flow only to the legitimate provider APIs that require them, not to any unexpected, third-party, or exfiltration destination. No obfuscation, hidden channels, or off-label destinations are present in the evidence.

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
tavernkeeper 5
Rule
credential-exfiltration
File role
production
Source
server.js:878

OpenGrep reported tavernkeeper.dynamic-execution.node-shell

Expected behavior · high confidence

This runs a fixed git command to read the remote version hash. No user input is involved and login is required. This is normal self-update behavior.

Technical evidence

Scanner reason: OpenGrep matched static-analysis rule tavernkeeper.dynamic-execution.node-shell. The match applies to this repository.

Contextual assessment: The execSync call at line 1622 invokes a static git rev-parse command with no user-controlled interpolation. The cwd is __dirname and the endpoint is auth-protected. No injection surface exists.

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
opengrep 1.26.0
Rule
tavernkeeper.dynamic-execution.node-shell
File role
production
Source
server.js:1622

OpenGrep reported tavernkeeper.dynamic-execution.node-shell

Expected behavior · high confidence

This runs a fixed git command to show a changelog of pending updates. No user input is involved and login is required. This is normal self-update behavior.

Technical evidence

Scanner reason: OpenGrep matched static-analysis rule tavernkeeper.dynamic-execution.node-shell. The match applies to this repository.

Contextual assessment: The execSync call at line 1629 invokes a static git log command with no user-controlled interpolation. The cwd is __dirname and the endpoint is auth-protected. No injection surface exists.

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
opengrep 1.26.0
Rule
tavernkeeper.dynamic-execution.node-shell
File role
production
Source
server.js:1629

JavaScript analysis reported javascript.credential-to-network

Expected behavior · high confidence

The proxy takes your API keys and sends them to the image generation services they're meant for. That's what a proxy does.

Technical evidence

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

Contextual assessment: The code reads API keys from request headers and environment variables and forwards them to the corresponding backend API endpoints via fetch. This is the core data flow of an image generation proxy: user-supplied credentials are sent only to the intended provider endpoints (OpenAI, NovelAI, CivitAI, Gemini, etc.). No evidence shows credentials being copied to unexpected destinations, logged in plaintext, or exfiltrated to a third-party sink. The credential-to-network correlation is the product's primary function.

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.credential-to-network
File role
production
Source
server.js:14-358

JavaScript analysis reported javascript.xray.serialize-environment

Expected behavior · high confidence

The tool reads its settings from environment variables, which is a normal way to configure a server application.

Technical evidence

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

Contextual assessment: The flagged signal corresponds to process.env being read for configuration values such as ADMIN_USER, ADMIN_PASS, SESSION_SECRET, LOGIN_REQUIRED, MODEL_PROXY_ALLOWED_HOSTS, and default URL overrides. These are standard environment-variable configuration reads, not serialization or transmission of the full environment object. No evidence shows the environment being stringified, logged, or sent over the network.

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.serialize-environment
File role
production
Source
server.js:11

JavaScript analysis reported javascript.xray.unsafe-command

Expected behavior · high confidence

The tool can update itself by running git commands. These commands are fixed text with no user input mixed in, and the feature requires login. This is a normal self-update feature, not a security hole.

Technical evidence

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

Contextual assessment: The execSync calls are in two self-update endpoints, both gated by requireAuth middleware. Every command string is a hardcoded literal (git fetch origin, git rev-parse HEAD, git rev-parse origin/main, git rev-list --count, git log --oneline, git pull origin main) with no user-controlled interpolation. The cwd is set to __dirname, the project's own directory. There is no command injection vector because no request body, query parameter, or header value is concatenated into any command. This is a standard git-based self-update mechanism. The only residual concern is that default admin/admin credentials could allow an authenticated party to trigger the update, but that is a configuration issue addressed by the default-credentials observation, not a code-level injection vulnerability.

Impact: low · 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.unsafe-command
File role
production
Source
server.js:1620

Gitleaks reported curl-auth-header

Expected behavior · high confidence

The flagged text is just an example in the documentation showing how to use the API, with a placeholder that says YOUR_API_KEY. There is no real password or key exposed here.

Technical evidence

Scanner reason: Gitleaks matched secret-detection rule curl-auth-header. The match applies to this repository.

Contextual assessment: The gitleaks match is a curl example in the README documentation using the placeholder string YOUR_API_KEY. This is a template showing users how to call the API, not a real credential. No actual secret is present in the matched content.

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
gitleaks 8.30.1
Rule
curl-auth-header
File role
documentation
Source
README.md:327-330

Credential access and network transmission in one file

Expected behavior · high confidence

This is a web dashboard for an image generation proxy. It stores your API keys locally in the browser and sends them to its own proxy server and to the image generation services you selected. This is exactly what the tool is designed to do. There is no sign of keys being secretly sent anywhere unexpected.

Technical evidence

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

Contextual assessment: The flagged line initiates session management by fetching a session ID from the same-origin /api/session endpoint and storing it in localStorage. API keys are loaded from localStorage, entered by the user in the UI, and sent as Bearer tokens to same-origin proxy endpoints via getHeaders(). The proxy's stated purpose is to forward credentials to image generation backends. fetchBackendModels() also sends the API key directly to legitimate model-listing endpoints for the selected backend. All network destinations are the project's own proxy or known model-provider APIs, matching the stated purpose. No evidence of hidden exfiltration, unexpected destinations, obfuscation, or credential access disproportionate to the project's role as a multi-backend image generation proxy.

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
tavernkeeper 5
Rule
credential-exfiltration
File role
production
Source
public/index.html:1983

OpenGrep reported tavernkeeper.dynamic-execution.node-shell

Expected behavior · high confidence

This runs a fixed git command to read the current version hash. No user input is involved and login is required. This is normal for a self-update feature.

Technical evidence

Scanner reason: OpenGrep matched static-analysis rule tavernkeeper.dynamic-execution.node-shell. The match applies to this repository.

Contextual assessment: The execSync call at line 1621 invokes a static git rev-parse command with no user-controlled interpolation. The cwd is __dirname. The endpoint is auth-protected. No injection surface exists.

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
opengrep 1.26.0
Rule
tavernkeeper.dynamic-execution.node-shell
File role
production
Source
server.js:1621

Related contextual observations

API keys stored in localStorage without additional protection

low risk · high confidence

The tool saves your API keys in the browser's local storage so you don't have to re-enter them. This is normal for local tools but means that if someone could inject malicious scripts into the page, they could read your keys. For a personal or local setup this is fine; for a shared remote deployment it's worth keeping in mind.

Technical assessment

Settings including per-backend API keys are persisted in localStorage via JSON.stringify(settings). Any XSS in the single-page application could read these keys. This is a common pattern in browser-based tooling and is proportionate to a local or single-user deployment, but it is worth noting for shared or remote deployments.

Impact: low · Exploitability: plausible

Developer action: Consider documenting the localStorage credential storage behavior for users deploying on shared or public-facing servers, and remind users to set custom credentials and session secrets for remote deployments.

Sources:

Default admin credentials and default session secret shipped

low risk · medium confidence

The tool starts with a default username and password of admin/admin. If you put it on a public network without changing them, anyone could log in. The tool warns you about this on startup.

Technical assessment

The code defaults ADMIN_USER to admin and ADMIN_PASS to admin, and falls back to a hardcoded session secret when SESSION_SECRET is unset. While warnings are printed to the console, these defaults could allow unauthorized access if the proxy is exposed beyond localhost without changing them. The README also documents these defaults. This is a configuration hygiene weakness, not demonstrated malicious behavior.

Impact: low · Exploitability: unlikely

Developer action: Consider requiring explicit ADMIN_PASS and SESSION_SECRET on first run, or generating a random session secret automatically when none is provided.

Sources:

Coverage and limitations

JavaScript coverage

Tools

Limitations

Technical scan identity