Skip to content

fix(security): resolve all 35 open code-scanning alerts#7

Merged
ikunin merged 1 commit into
mainfrom
fix/code-scanning-alerts
Jul 1, 2026
Merged

fix(security): resolve all 35 open code-scanning alerts#7
ikunin merged 1 commit into
mainfrom
fix/code-scanning-alerts

Conversation

@ikunin

@ikunin ikunin commented Jun 30, 2026

Copy link
Copy Markdown
Owner

Closes all 35 open code-scanning alerts on this repo.

Summary

Count Rule Disposition
1 CVE-2026-53550 (Trivy, medium) Fixed — bump js-yaml ^4.1.0 → ^4.3.0 (DoS via crafted YAML merge keys; fixed in 4.2.0)
14 detect-non-literal-regexp (Semgrep) 2 fixed (escape unescaped interpolation), 12 suppressed (FP)
12 contains-bidirectional-characters (Semgrep) suppressed (FP) — sanitizer regexes that intentionally contain bidi code points to strip/reject them
8 prototype-pollution-loop (Semgrep) suppressed (FP) — read-only traversals, already-guarded writes, null-proto trees

Real hardening fixes

  • stack-snapshot.js / install.js: a story key / config key was interpolated unescaped into new RegExp(...). Now regex-escaped so a metacharacter can't alter the pattern.
  • js-yaml bumped past the DoS CVE; lockfile also self-syncs stale root version/engines that were out of step with package.json.

Suppressions

Semgrep SAST is report-only in security.yml; the workflow explicitly directs FP suppression via inline // nosemgrep. Each suppression carries a specific rationale (escaped input, glob→regex compiler, operator-supplied pattern by design, UNSAFE_KEYS-guarded write, Object.create(null) tree, read-only traversal).

Verification

  • semgrep scan --config p/default --config p/security-audit --config p/secrets0 findings
  • biome check → clean
  • cd tests && npm test2234 passed, 0 failures

The Trivy CVE alert and Semgrep alerts will auto-close on the next FULL security scan after merge.

🤖 Generated with Claude Code

Trivy (1):
- CVE-2026-53550 (medium): bump js-yaml ^4.1.0 -> ^4.3.0 (DoS via crafted
  YAML merge keys; fixed in 4.2.0). Lockfile also self-syncs stale root
  metadata (version/engines) to match package.json.

Semgrep (34) — two real hardening fixes, the rest justified suppressions
per the workflow's sanctioned `// nosemgrep` path (SAST is report-only):

detect-non-literal-regexp (14):
- stack-snapshot.js, install.js: storyKey/key were interpolated UNESCAPED
  into `new RegExp` — now regex-escaped (latent correctness + hardening).
- remainder: input already escaped (escapeRe/escapeRegex/inline), glob->regex
  compilers that escape metachars during translation, or an operator-supplied
  grep pattern by design — suppressed with rationale.

contains-bidirectional-characters (12 -> 3 lines):
- resolve-dag.js / sprint-plan.js sanitizer regexes intentionally contain
  bidi code points in order to strip/reject them. Suppressed.

prototype-pollution-loop (8):
- read-only path traversals (no write sink), already-UNSAFE_KEYS-guarded
  writes (state-shard), and a null-proto tree (config-merger). Suppressed.

Verified: Semgrep (p/default,p/security-audit,p/secrets) reports 0 findings;
biome clean; 2234 tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
// Escape the key so a metacharacter in it can't alter the pattern.
const safeKey = storyKey.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
// nosemgrep: javascript.lang.security.audit.detect-non-literal-regexp.detect-non-literal-regexp -- pattern built from a regex-escaped, trusted story key
const re = new RegExp(`^\\s*${safeKey}:\\s*(\\w+)`, 'm');
Comment thread lib/commands/install.js
// Escape the key so a metacharacter in it can't alter the pattern.
const safeKey = key.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
// nosemgrep: javascript.lang.security.audit.detect-non-literal-regexp.detect-non-literal-regexp -- pattern built from a regex-escaped config key
const replaceRe = new RegExp(`^([ \\t]*)${safeKey}:[ \\t]*(\\S[^#\\n]*?)?([ \\t]*#.*)?$`, 'm');
@ikunin
ikunin merged commit 27b1ceb into main Jul 1, 2026
8 checks passed
@ikunin
ikunin deleted the fix/code-scanning-alerts branch July 1, 2026 17:35
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.

2 participants