TavernKeeper Scan Report

starlitcode/Lumiverse-Auto-Retry

Commit 71e6170 Reviewed

1 material concern identified.

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

0 immediate danger 1 material 21 low

What this review found

No material or immediate-danger item was identified.

Minor cautions

zizmor reported artipacked

Minor caution · medium confidence

The checkout step leaves a temporary GitHub token in the build machine's git config. Since nothing is uploaded or shared and the token is read-only, the practical risk is negligible.

Technical evidence

Scanner reason: zizmor matched workflow-security rule artipacked in this repository.

Contextual assessment: The artipacked rule fires because actions/checkout is used without persist-credentials: false, so the default GITHUB_TOKEN is stored in .git/config. However, this workflow declares permissions: contents: read, does not upload any artifacts, and does not share job state that would expose the token. The token is scoped and ephemeral, so credential persistence risk is minimal.

Impact: low · Exploitability: unlikely

Developer action: Set persist-credentials: false on checkout steps if you want to eliminate residual token storage, though the current contents: read scope and absence of artifact uploads make this low priority.

Scanner
zizmor 1.28.0
Rule
artipacked
File role
tooling
Source
.github/workflows/checks.yml:60

zizmor reported unpinned-uses

Minor caution · high confidence

The workflow uses a version tag instead of a fixed hash for a standard build action. If the tag were ever moved to malicious code it could affect CI, but this is a well-known official action and the risk is low.

Technical evidence

Scanner reason: zizmor matched workflow-security rule unpinned-uses in this repository.

Contextual assessment: actions/checkout@v4 is pinned to a major version tag rather than a full SHA. While SHA-pinning is best practice for supply-chain integrity, using major version tags for widely used official actions is standard in the ecosystem. This is a CI-only tooling file with no runtime impact on extension users.

Impact: low · Exploitability: unlikely

Developer action: Pin actions to a full commit SHA if you want maximum supply-chain hardening; otherwise current practice is acceptable for this CI tooling file.

Scanner
zizmor 1.28.0
Rule
unpinned-uses
File role
tooling
Source
.github/workflows/checks.yml:60

zizmor reported unpinned-uses

Minor caution · high confidence

The workflow uses a version tag instead of a fixed hash for the Bun setup action. This is a common practice and the risk is low, though pinning to a hash would be more secure.

Technical evidence

Scanner reason: zizmor matched workflow-security rule unpinned-uses in this repository.

Contextual assessment: oven-sh/setup-bun@v2 is pinned to a major version tag rather than a full SHA. This is a CI-only tooling file. While SHA-pinning is the stricter practice, using version tags for maintained actions is conventional and does not affect the extension's runtime behavior.

Impact: low · Exploitability: unlikely

Developer action: Pin actions to a full commit SHA if you want maximum supply-chain hardening; otherwise current practice is acceptable for this CI tooling file.

Scanner
zizmor 1.28.0
Rule
unpinned-uses
File role
tooling
Source
.github/workflows/checks.yml:62

zizmor reported unpinned-uses

Minor caution · high confidence

The workflow uses a version tag instead of a fixed hash for a standard checkout action. This is common practice and the risk is low.

Technical evidence

Scanner reason: zizmor matched workflow-security rule unpinned-uses in this repository.

Contextual assessment: actions/checkout@v4 in the first job is pinned to a major version tag rather than a full SHA. This is a CI-only tooling file with no runtime impact on extension users. SHA-pinning would be stricter but version tags for official actions are standard.

Impact: low · Exploitability: unlikely

Developer action: Pin actions to a full commit SHA if you want maximum supply-chain hardening; otherwise current practice is acceptable for this CI tooling file.

Scanner
zizmor 1.28.0
Rule
unpinned-uses
File role
tooling
Source
.github/workflows/checks.yml:33

zizmor reported unpinned-uses

Minor caution · high confidence

The workflow uses a version tag instead of a fixed hash for the Bun setup action in the first job. This is common practice and the risk is low.

Technical evidence

Scanner reason: zizmor matched workflow-security rule unpinned-uses in this repository.

Contextual assessment: oven-sh/setup-bun@v2 in the first job is pinned to a major version tag rather than a full SHA. This is a CI-only tooling file. SHA-pinning would be stricter but version tags for maintained actions are conventional and do not affect the extension's runtime behavior.

Impact: low · Exploitability: unlikely

Developer action: Pin actions to a full commit SHA if you want maximum supply-chain hardening; otherwise current practice is acceptable for this CI tooling file.

Scanner
zizmor 1.28.0
Rule
unpinned-uses
File role
tooling
Source
.github/workflows/checks.yml:35

zizmor reported artipacked

Minor caution · medium confidence

The checkout step in the first job leaves a temporary read-only GitHub token in the build machine's git config. Since nothing is uploaded or shared, the practical risk is negligible.

Technical evidence

Scanner reason: zizmor matched workflow-security rule artipacked in this repository.

Contextual assessment: The artipacked rule fires because actions/checkout is used without persist-credentials: false, so the default GITHUB_TOKEN is stored in .git/config. This workflow declares permissions: contents: read, does not upload artifacts, and does not share job state. The token is scoped and ephemeral, so credential persistence risk is minimal.

Impact: low · Exploitability: unlikely

Developer action: Set persist-credentials: false on checkout steps if you want to eliminate residual token storage, though the current contents: read scope and absence of artifact uploads make this low priority.

Scanner
zizmor 1.28.0
Rule
artipacked
File role
tooling
Source
.github/workflows/checks.yml:33
Expected scanner matches (15)

OpenGrep reported tavernkeeper.download-and-execute.shell-pipeline

Expected behavior · high confidence

This is a development setup script that installs the Bun programming tool. It first tries installing through the standard package manager, and only as a backup does it use Bun's official installer from the Bun website. This is a normal and transparent way to set up a development environment.

Technical evidence

Scanner reason: OpenGrep matched static-analysis rule tavernkeeper.download-and-execute.shell-pipeline in this repository.

Contextual assessment: The flagged line is a fallback in a development bootstrap script. It first attempts to install bun via npm, and only if that fails does it pipe the official bun.sh installer into bash. The destination is the official Bun runtime installer domain, the URL is visible and unobfuscated, and the script is a dev-environment setup file rather than shipped extension runtime code. The project purpose is a Lumiverse extension that makes no external network calls at runtime; this script exists solely to prepare a developer sandbox. The curl-to-bash pattern is the officially recommended Bun installation method and is gated behind a prior npm attempt with error tolerance.

Impact: low · Exploitability: unlikely

Developer action: none

Scanner
opengrep 1.26.0
Rule
tavernkeeper.download-and-execute.shell-pipeline
File role
production
Source
setup.sh:40

JavaScript analysis reported javascript.xray.serialize-environment

Expected behavior · high confidence

A test script reads a system environment variable to find a browser program for running automated UI checks. This is standard test setup and does not touch any secrets or send data anywhere.

Technical evidence

Scanner reason: JavaScript analysis matched static JavaScript security signal javascript.xray.serialize-environment in this repository.

Contextual assessment: The flagged line reads process.env.CHROMIUM_PATH to optionally supply an executablePath to Playwright's chromium.launch(). This is a test harness in file that launches a headless browser for contrast and UI checks. The environment variable is a local path to a browser binary, not credentials or sensitive state. No serialization, exfiltration, or network transmission of environment data occurs. The value is used solely to configure the browser process and falls back to undefined when unset.

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
javascript-analysis webcrack-2.16.0_js-x-ray-16.0.0_signatures-1_literals-1
Rule
javascript.xray.serialize-environment
File role
test
Source
test/ui.mjs:287

JavaScript analysis reported javascript.xray.unsafe-regex

Expected behavior · high confidence

The flagged pattern is a standard color-parsing helper used to read CSS color values from the browser. It does not accept user input and cannot be used to attack anything.

Technical evidence

Scanner reason: JavaScript analysis matched static JavaScript security signal javascript.xray.unsafe-regex in this repository.

Contextual assessment: The regex at line 1772 matches rgb()/rgba() color strings produced by getComputedStyle. It contains no nested quantifiers or ambiguous alternation that would cause catastrophic backtracking (ReDoS). Each quantified group is linear: [d.]+, character-class [,/s]+, and an optional trailing alpha group. The input is a browser-generated CSS color string, not attacker-controlled data. The function parseColor feeds into WCAG contrast-ratio calculations for UI accessibility checks, which is consistent with the extension's stated purpose of clicking regenerate buttons and rendering a settings panel.

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
javascript-analysis webcrack-2.16.0_js-x-ray-16.0.0_signatures-1_literals-1
Rule
javascript.xray.unsafe-regex
File role
generated
Source
dist/frontend.js:1772

JavaScript analysis reported javascript.xray.unsafe-regex

Expected behavior · high confidence

The flagged pattern is a text-matching rule used to detect when an AI reply is an accidental refusal, so the extension can retry. The scanner warns it might be a slow regex, but the pattern uses bounded repetition limits and runs on short AI-generated text, not attacker-controlled input, so there is no real denial-of-service risk.

Technical evidence

Scanner reason: JavaScript analysis matched static JavaScript security signal javascript.xray.unsafe-regex in this repository.

Contextual assessment: JS-X-Ray flagged this regex as an unsafe-regex signal, typically indicating potential ReDoS. The regex at line 1243 is part of the REFUSAL_STRONG array used to detect accidental AI refusals in generated replies. Analysis of the pattern shows bounded quantifiers (e.g., {0,30}?) and no deeply nested overlapping quantifiers that would cause catastrophic backtracking. The input is AI-generated reply text, not attacker-controlled data, and reply length is naturally bounded. The regex serves the project's stated purpose of detecting refusals to trigger retries. No ReDoS vulnerability is present in practice.

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
javascript-analysis webcrack-2.16.0_js-x-ray-16.0.0_signatures-1_literals-1
Rule
javascript.xray.unsafe-regex
File role
generated
Source
dist/frontend.js:1243

OpenGrep reported tavernkeeper.dynamic-execution.javascript-eval

Expected behavior · high confidence

This is a test file that loads the project's own built code and runs it inside a fake environment to check its behavior. The dynamic execution is a normal way to test the backend in isolation and does not run untrusted or remote input.

Technical evidence

Scanner reason: OpenGrep matched static-analysis rule tavernkeeper.dynamic-execution.javascript-eval in this repository.

Contextual assessment: The match is `new Function('spindle', BACKEND)(spindle)` inside a test harness. BACKEND is read from the project's own dist/backend.js build output via readFileSync, not from user input, network, or chat content. The test injects a mock spindle object to exercise the backend module in isolation. This is a standard pattern for testing bundled backend code without a real host environment. No untrusted data reaches the executed code, and the file role is test-only, not shipped runtime.

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
opengrep 1.26.0
Rule
tavernkeeper.dynamic-execution.javascript-eval
File role
test
Source
test/prompt-viewer.test.ts:40

JavaScript analysis reported javascript.xray.unsafe-regex

Expected behavior · high confidence

This is a simple pattern used in a test to read a countdown timer like 'in 5s' or 'in 1m 30s'. It only matches digits and optional time-unit labels, poses no security risk, and is not reachable by any attacker input.

Technical evidence

Scanner reason: JavaScript analysis matched static JavaScript security signal javascript.xray.unsafe-regex in this repository.

Contextual assessment: The flagged regex at line 1424 is `/in (?:(?:(?:(?:d+)h )?(?:(?:d+)m )?(?:d+)s/` used inside a test helper `num()` to parse countdown strings produced by the extension's own UI (e.g., 'Retrying in 1m 30s'). The pattern consists of optional non-capturing groups matching digits followed by single-character time units. There is no nested quantifier structure that would cause catastrophic backtracking (ReDoS). The input is a textContent string from a DOM element the extension itself created, not attacker-controlled data. This is a test file exercising UI countdown behavior, and the regex is a straightforward parser with no security relevance.

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
javascript-analysis webcrack-2.16.0_js-x-ray-16.0.0_signatures-1_literals-1
Rule
javascript.xray.unsafe-regex
File role
test
Source
test/ui.mjs:1424

JavaScript analysis reported javascript.xray.shady-link

Expected behavior · high confidence

The flagged URL is a fake test-only address used so the automated browser test has a working web origin. No real internet request is made to it; the test tool intercepts and serves local content instead.

Technical evidence

Scanner reason: JavaScript analysis matched static JavaScript security signal javascript.xray.shady-link in this repository.

Contextual assessment: The flagged line defines const ORIGIN as a .test TLD URL used solely as a synthetic origin for Playwright page navigation in the test file. The .test TLD is reserved by RFC 2606 for testing and never resolves to a real host. The stage() function installs a page.route('**/*') handler that intercepts all requests and fulfills them with local test HTML, so page.goto(ORIGIN) never makes a real network call. The comment explains this is needed because about:blank blocks localStorage. This is standard test infrastructure with no external network access.

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
javascript-analysis webcrack-2.16.0_js-x-ray-16.0.0_signatures-1_literals-1
Rule
javascript.xray.shady-link
File role
test
Source
test/ui.mjs:234

OpenGrep reported tavernkeeper.dynamic-execution.javascript-eval

Expected behavior · high confidence

This is a test file that loads the extension's own compiled backend code to run it against a fake environment. The dynamic execution is just the test harness booting the backend for testing, not running anything unexpected or from outside.

Technical evidence

Scanner reason: OpenGrep matched static-analysis rule tavernkeeper.dynamic-execution.javascript-eval in this repository.

Contextual assessment: The flagged `new Function` on line 43 is inside a test harness (`file`). It reads the project's own compiled backend (`dist/backend.js`) from disk via `readFileSync` and executes it with a mock `spindle` object. This is a standard test pattern for loading a built module without module resolution, and the executed code is the project's own output, not user-supplied or remotely fetched content. No untrusted data reaches the `new Function` call; the only argument is the locally built backend source. The mock spindle provides stubbed storage, chat, and interceptor hooks, confirming this is a controlled test environment.

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
opengrep 1.26.0
Rule
tavernkeeper.dynamic-execution.javascript-eval
File role
test
Source
test/refusal-note.test.ts:43

JavaScript analysis reported javascript.xray.unsafe-regex

Expected behavior · high confidence

This is a text-matching pattern used to detect when an AI reply contains a soft refusal phrase like 'I'd be happy to help with X instead.' The pattern is part of the extension's core feature: detecting accidental refusals so it can retry. The regex uses bounded quantifiers (max 40 characters) so it cannot cause runaway processing, and it only runs on model-generated reply text, not on attacker-controlled input.

Technical evidence

Scanner reason: JavaScript analysis matched static JavaScript security signal javascript.xray.unsafe-regex in this repository.

Contextual assessment: The JS-X-Ray unsafe-regex signal flags line 1417, which is the regex /i'?d be happy to help (?:you )?(?:with [^.?!]{0,40}? )?instead/i. This regex is part of the REFUSAL_SOFT array used for accidental-refusal detection, matching the project's stated purpose. The potentially concerning subpattern is (?:with [^.?!]{0,40}? )? which combines an optional group with a lazy bounded quantifier. Because the quantifier is bounded to {0,40}, worst-case backtracking is O(n*40) which is linear and not exponential. The input is model-generated reply text processed locally in the browser, not attacker-controlled network input. No ReDoS vulnerability is present.

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
javascript-analysis webcrack-2.16.0_js-x-ray-16.0.0_signatures-1_literals-1
Rule
javascript.xray.unsafe-regex
File role
generated
Source
dist/frontend.js:1417

JavaScript analysis reported javascript.xray.unsafe-regex

Expected behavior · high confidence

A pattern-matching rule used to detect unclosed custom tags in AI replies was flagged by an automated scanner. The pattern does not have the nested repetition that causes dangerous slowdowns, the text it checks is AI output rather than attacker input, and the loop that uses it is capped at 5000 passes. No real risk is present.

Technical evidence

Scanner reason: JavaScript analysis matched static JavaScript security signal javascript.xray.unsafe-regex in this repository.

Contextual assessment: The flagged regex matches lines containing only an opening or closing custom tag name. It uses simple character classes with single quantifiers and no nested or overlapping repetition that would cause catastrophic backtracking. The input is model-generated reply text, not attacker-controlled data. The consuming loop is guarded by a 5000-iteration cap. The scanner signal is a heuristic flag and does not correspond to an exploitable ReDoS condition in this context.

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
javascript-analysis webcrack-2.16.0_js-x-ray-16.0.0_signatures-1_literals-1
Rule
javascript.xray.unsafe-regex
File role
generated
Source
dist/frontend.js:764

JavaScript analysis reported javascript.download-to-execution

Expected behavior · high confidence

This is a test file that loads the extension's own built code from disk and runs it inside a test browser to check the UI works. Reading a local file and running it in a browser is exactly what a UI test is supposed to do. There is no network download or hidden code execution.

Technical evidence

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

Contextual assessment: The candidate flags a correlation between file reading (readFileSync/existsSync imports) and code execution sinks (page.evaluate, page.addScriptTag). In context, this is a Puppeteer-based UI test file that reads the extension's own compiled source from the local filesystem and injects it into a headless browser page for testing. The SOURCE variable is local build output, not a network download. page.evaluate and page.addScriptTag are standard Puppeteer test primitives used to run assertions in the browser context. No remote retrieval, no dynamic eval of untrusted input, no credential access. This is expected test infrastructure behavior.

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
javascript-analysis webcrack-2.16.0_js-x-ray-16.0.0_signatures-1_literals-1
Rule
javascript.download-to-execution
File role
test
Source
test/ui.mjs:1811-2332

JavaScript analysis reported javascript.xray.unsafe-regex

Expected behavior · high confidence

A test file uses regular expressions to check that the UI displays the right text. The scanner flagged the regex pattern, but it is just a normal test assertion checking for expected output. No security risk.

Technical evidence

Scanner reason: JavaScript analysis matched static JavaScript security signal javascript.xray.unsafe-regex in this repository.

Contextual assessment: The unsafe-regex signal at line 1827 is in a test file. The surrounding code shows test fixture data (notes, dropped, messages array) and regex-based assertions like /3 messages,.*characters,.*tokens/i.test(p). These are static regex literals used to validate UI output in a Puppeteer test. They operate on locally generated test strings, not on attacker-controlled input, so there is no ReDoS or injection risk. This is expected test behavior.

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
javascript-analysis webcrack-2.16.0_js-x-ray-16.0.0_signatures-1_literals-1
Rule
javascript.xray.unsafe-regex
File role
test
Source
test/ui.mjs:1827

JavaScript analysis reported javascript.xray.unsafe-regex

Expected behavior · high confidence

A test file uses a regular expression to verify that the UI shows the correct role and origin labels. The scanner flagged the regex, but it is a simple test assertion with no security impact.

Technical evidence

Scanner reason: JavaScript analysis matched static JavaScript security signal javascript.xray.unsafe-regex in this repository.

Contextual assessment: The unsafe-regex signal at line 1866 corresponds to test assertions such as /1 system (chat)/.test(p) and /3 user (chat)/.test(p). These are static regex literals in a UI test file that validate rendered output strings. They match against locally produced test data, not attacker-controlled input, so there is no ReDoS or injection concern. This is expected test behavior.

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
javascript-analysis webcrack-2.16.0_js-x-ray-16.0.0_signatures-1_literals-1
Rule
javascript.xray.unsafe-regex
File role
test
Source
test/ui.mjs:1866

OpenGrep reported tavernkeeper.dynamic-execution.javascript-eval

Expected behavior · high confidence

This is a test file that loads the project's own backend code to exercise it in a controlled harness. Using dynamic execution here is a normal way to run code under test and does not pose a security risk.

Technical evidence

Scanner reason: OpenGrep matched static-analysis rule tavernkeeper.dynamic-execution.javascript-eval in this repository.

Contextual assessment: The match is on `new Function('spindle', BACKEND)(spindle)` inside a test harness. The file role is test, and the harness constructs a mock spindle object with stubbed storage, chat, event, and logging APIs. BACKEND is the project's own backend module source loaded for execution under test. This is a standard pattern for invoking the code-under-test in isolation without importing its real dependencies. No untrusted external input reaches the Function constructor; the executed code is the project's own backend. There is no exfiltration, persistence, or obfuscation.

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
opengrep 1.26.0
Rule
tavernkeeper.dynamic-execution.javascript-eval
File role
test
Source
test/word-swaps.test.ts:72

JavaScript analysis reported javascript.xray.unsafe-regex

Expected behavior · high confidence

A test uses a simple pattern to check that a button has no CSS animation when reduced motion is requested. The pattern is straightforward and only runs in the test suite, so it poses no security risk.

Technical evidence

Scanner reason: JavaScript analysis matched static JavaScript security signal javascript.xray.unsafe-regex in this repository.

Contextual assessment: The flagged regex at line 1163 is `/^0s(,s*0s)*$//`, used inside a UI test to assert that computed CSS transitionDuration values are all zero (no animation) under reduced-motion preferences. The pattern contains no nested quantifiers or overlapping alternations that could cause catastrophic backtracking, so it is not a ReDoS vector. It operates on a short, locally-produced string from getComputedStyle, not on attacker-controlled input. The file role is test-only and the regex is part of a normal assertion, matching the project's stated purpose of UI behavior testing.

Impact: none · Exploitability: unlikely

Developer action: none

Scanner
javascript-analysis webcrack-2.16.0_js-x-ray-16.0.0_signatures-1_literals-1
Rule
javascript.xray.unsafe-regex
File role
test
Source
test/ui.mjs:1163

Coverage and limitations

JavaScript coverage

Unresolved JavaScript stages

Tools

Limitations

Technical scan identity