Maintenance: Security
July 5, 2026 · View on GitHub
How to handle security alerts, audits, and hardening in the
create-node-appecosystem.Read after the top-level MAINTENANCE_RUNBOOK.md.
1. Sources of alerts
There are three main channels:
- GitHub Dependabot alerts — vulnerabilities in direct and transitive dependencies.
- OSV-Scanner CI — runs in
create-node-appvia.github/workflows/osv-scanner.yml. - CodeQL alerts — code scanning alerts in
create-node-app.
Check all three when doing security work:
# Dependabot alerts
gh api repos/Create-Node-App/create-node-app/dependabot/alerts --jq '.[] | {number, severity, package: .dependency.package.name, title}' | head -n 20
gh api repos/Create-Node-App/cna-templates/dependabot/alerts --jq '.[] | {number, severity, package: .dependency.package.name, title}' | head -n 20
# CodeQL
gh code-scanning alerts list --repo Create-Node-App/create-node-app --state open
gh code-scanning alerts list --repo Create-Node-App/cna-templates --state open
2. Triage
| Severity | Action |
|---|---|
| Critical / High in CLI code path | P0 — fix immediately and release |
| High in transitive dependency of a template | P1 — fix within the sprint |
| Moderate / Low | Batch with other maintenance |
| Informational only | Document and close if not actionable |
Questions to ask:
- Is the vulnerable dependency in the CLI execution path or only in generated projects?
- Can we bump the dependency without breaking the template/extension?
- Is the fix already available upstream?
- Can we mitigate with
overrideswhile waiting for upstream?
3. Fixing in create-node-app
The CLI monorepo uses pnpm. Root-level overrides can pin transitive dependencies across all packages.
{
"pnpm": {
"overrides": {
"esbuild": "^0.28.0",
"picomatch": "^4.0.2"
}
}
}
Then run:
pnpm install
pnpm run build
pnpm run test:all
pnpm run lint
Case study: PR #165 "enforce secure esbuild and picomatch versions via overrides" used this exact pattern.
4. Fixing in cna-templates
Templates/extensions do not have committed lockfiles, so the fix must be in package.json ranges or overrides.
4.1 Direct dependency bump
If the vulnerable package is a direct dependency of an extension, bump it in the extension's package.json.
4.2 Transitive dependency override
If the vulnerable package is transitive, add an overrides field in the relevant extension package.json:
{
"devDependencies": { ... },
"overrides": {
"some-vulnerable-pkg": "^x.y.z"
}
}
4.3 Cannot fix quickly
If no fixed version exists or the bump is breaking, open a tracking issue and document:
- The CVE or advisory ID.
- Why it cannot be fixed yet.
- The planned remediation date.
5. Running audits locally
# In create-node-app
pnpm audit
# In a generated project
npm audit
# OSV scanner (requires osv-scanner CLI)
osv-scanner -r .
6. CodeQL fixes
CodeQL alerts often relate to:
- Unsafe shell command construction from environment variables or user input.
- Injection via template strings in CLI code.
General fix pattern
- Validate and sanitize inputs before passing them to
exec,spawn, or shell templates. - Prefer structured arguments (
execFile,spawnwith array) over string shell commands. - Avoid interpolating user-controlled values directly into commands.
If an alert is a false positive, dismiss it with a comment explaining why.
7. Validation
After any security change:
- Run the relevant audit command until the alert is gone or mitigated.
- Run the normal CI checks (
test:all,lint,build). - For
cna-templates: scaffold the affected template + extensions and validate. - For
create-node-app: runnpm run test:alland the full workflow if possible.
8. Checklist
- Alert has been triaged and prioritized.
- Fix is minimal and scoped.
- Audit no longer reports the vulnerability (or it is documented as unfixable).
- CI passes.
- Generated projects still install, lint, type-check, and build.
- A changeset is added if the fix affects a published package.