Skip to content

Build input safety: slug validation, HTML escaping, secret denylist - #6

Merged
miguelrisero merged 2 commits into
mainfrom
fix/build-safety
Oct 14, 2026
Merged

miguelrisero merged 2 commits into
mainfrom
fix/build-safety

Conversation

@miguelrisero

Copy link
Copy Markdown
Contributor

Stack 2 of 5 (base: chore/governance-and-ci). Council P0 — treat repo content as untrusted now that the repo is public.

  • Slug-validate project folder names (^[a-z0-9][a-z0-9-]*$) at discovery; invalid names are skipped with a warning. This closes the command-injection path where name was interpolated into spawn("sh", ["-c", …]) (e.g. npx vite build --base /${name}/).
  • HTML-escape project name/title/type and section titles in the generated landing index; allowlist link schemes (internal paths + http(s) only) so externals.json can't inject javascript:/markup → fixes the stored-XSS sink.
  • Secret denylist on static copy: also exclude .env*, .npmrc, *.pem/*.key, id_rsa/id_ed25519, .DS_Store so a static template can't accidentally publish credentials.

npm run build stays green; both example cards still render. (build-node-functions.mjs already validates template.config.json paths against traversal/symlink escape.)

⚠️ Stacked — don't merge before #5 (PR1). Merge order: 1→5.

@vercel

vercel Bot commented Jun 3, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
runflow-templates Ready Ready Preview Oct 14, 2026 7:23pm UTC
templates Ready Ready Preview Oct 14, 2026 7:23pm UTC

Request Review

@miguelrisero
miguelrisero changed the base branch from chore/governance-and-ci to main October 14, 2026 15:49
Validate project folder names against a strict slug (^[a-z0-9][a-z0-9-]*$) at
discovery and skip the rest — closes the command-injection vector where a folder
name was interpolated into `sh -c` (`npx vite build --base /<name>/`). Extend the
static-copy filter to drop secret-looking files (.env*, .npmrc, *.pem/*.key, ssh
keys) so a template can't publish credentials. HTML-escape project name/title/type
and section titles in the generated landing index, and allowlist link schemes
(internal paths + http(s) only) so externals.json can't inject script/markup.
The type-check step ran a bare tsc against projects/dtc-image-package
without its node_modules, so every react/vite import failed to resolve
and the job was red on main. Install the project's locked dependencies
and use its own pinned tsc.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

This branch was successfully deployed

3 active (1 outdated) deployments
Preview – templates — 2eadefdd Deployed Oct 14, 2026 by vercel[bot]
Preview – runflow-templates — 2eadefdd Deployed Oct 14, 2026 by vercel[bot]
Preview — e9d76095 Deployed Jun 3, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant