-
Notifications
You must be signed in to change notification settings - Fork 288
Security audit: CI shell injection, potential API key exposure, and XSS patterns #741
Description
Summary
A static security scan via repowatch.io identified 18 findings across the repository. The most actionable items are grouped below by priority.
Overall score: 59/100 — strong code quality (95) and test confidence (90), but security hygiene was pulled to 0 by the findings below.
Full scan report: docs/repowatch-scan-2026-04-01.md
🔴 Critical: potential API key in test file
Location: tests/vite-hmr-websocket.test.ts:32
Gitleaks flagged a value matching the generic-api-key pattern. If this is a live credential, it should be rotated immediately and moved to environment-based secrets. If it's a test fixture/dummy value, no action is needed.
🟠 High: GitHub Actions shell injection (4 locations)
All four use ${{ github.event.* }} context data directly inside run: steps. An attacker can craft a PR title or branch name to inject arbitrary shell commands, exfiltrating secrets or writing to the repo.
Locations:
.github/workflows/publish.yml:47.github/workflows/nextjs-tracker.yml:42.github/workflows/nextjs-tracker.yml:73.github/workflows/nextjs-tracker.yml:137
Fix pattern: Use an intermediate environment variable instead of inline interpolation:
# Before (vulnerable)
run: echo "${{ github.event.pull_request.title }}"
# After (safe)
env:
PR_TITLE: ${{ github.event.pull_request.title }}
run: echo "$PR_TITLE"🟠 High: innerHTML in script shim
Location: packages/vinext/src/shims/script.tsx:159
innerHTML is used with potentially dynamic content. If the input is always developer-controlled (script config), this is acceptable by design. If user-supplied data can reach this path, it's an XSS vector.
🟡 Medium: non-literal RegExp (6 locations)
new RegExp(variable) patterns — potential ReDoS if the variable is user-controlled. In this codebase these appear to be internal config values (pageExtensions, fileNames, etc.), so likely low risk. Worth confirming no user input flows to these.
Locations:
packages/vinext/src/shims/head.ts:276packages/vinext/src/shims/image-config.ts:58packages/vinext/src/config/config-matchers.ts:341packages/vinext/src/config/config-matchers.ts:974packages/vinext/src/routing/file-matcher.ts:51packages/vinext/src/routing/file-matcher.ts:54
🟡 Medium: dangerouslySetInnerHTML in example
Location: examples/hackernews/components/comment.jsx:29
Renders API-sourced HTML without sanitization. Consider using DOMPurify if the HN API response is not fully trusted.
🔵 Low: unsafe format strings (2 locations)
Server-side debug logs using string concatenation in console.log. Minimal risk.
packages/vinext/src/server/isr-cache.ts:93packages/vinext/src/shims/fetch-cache.ts:679
Report generated by Repo Watch — static risk audit for repositories. Findings are directional signals, not proof of exploitability.