fix(security): update transitive nanoid for CVE-2026-67213 - #76
Conversation
📝 WalkthroughWalkthrough
Changesnanoid CVE remediation
Estimated code review effort: 1 (Trivial) | ~5 minutes Possibly related issues
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Exact-head triage for Validated intended change:
Unrelated regeneration churn still requiring correction or source-level justification:
The repository does not pin a package-manager version in |
7c333e4 to
59b4bb5
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/doctoring/nanoid-cve-2026-67213.md`:
- Around line 13-17: Update the CI/toolchain configuration around the Node 24
and npm ci setup to pin the npm CLI version and install flags using
packageManager/Corepack or an equivalent fixed execution image. Record the exact
Node/npm versions and flags used in the exact-head evidence document
nanoid-cve-2026-67213.md, ensuring future lockfile reproductions use the same
toolchain.
- Around line 21-24: Strengthen the final remediation head’s repository-write
requirements to use an atomic expected-head check, not only a pre-write refetch:
existing refs must reject writes unless the expected old SHA still matches, and
new refs must atomically verify expected absence. Define trusted local checkout
as requiring a clean worktree, exact base and head, verified remote identity,
and isolated credentials.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 08ac04e7-001d-4e15-a80b-994889c01428
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (2)
CHANGELOG.mddocs/doctoring/nanoid-cve-2026-67213.md
|
@coderabbitai review Please perform a substantive review of the current exact head |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
HEAD_SHA="e0106ce16b7b8b493f46bf075ec5baf58762bd95"
REPO="ContextualWisdomLab/noema"
echo '== Repository HEAD and target commit =='
git rev-parse HEAD
git cat-file -t "$HEAD_SHA"
git show -s --format='commit=%H%nparents=%P%nsubject=%s%ncommitter=%cn <%ce> %cI' "$HEAD_SHA"
echo '== PR metadata =='
gh pr view 76 --repo "$REPO" --json number,state,isDraft,headRefOid,baseRefOid,mergeCommit,url,title
BASE_SHA="$(gh pr view 76 --repo "$REPO" --json baseRefOid --jq '.baseRefOid')"
echo "base=$BASE_SHA"
echo "head=$HEAD_SHA"
echo '== Exact changed files and stat =='
git diff --stat "$BASE_SHA" "$HEAD_SHA"
git diff --name-status "$BASE_SHA" "$HEAD_SHA"
echo '== Exact lockfile/package/documentation diff =='
for f in package.json package-lock.json CHANGELOG.md docs/doctoring/nanoid-cve-2026-67213.md; do
if git cat-file -e "$HEAD_SHA:$f" 2>/dev/null || git cat-file -e "$BASE_SHA:$f" 2>/dev/null; then
echo "--- $f ---"
git diff --no-ext-diff --unified=80 "$BASE_SHA" "$HEAD_SHA" -- "$f"
fi
done
echo '== Package manager and install-script policy configuration =='
for f in package.json .npmrc; do
if git cat-file -e "$HEAD_SHA:$f" 2>/dev/null; then
echo "--- $f at exact head ---"
git show "$HEAD_SHA:$f"
fi
done
echo '== Workflow inventory and relevant workflow content =='
fd -t f -a .github 2>/dev/null | sort || true
for f in $(fd -t f -a .github/workflows 2>/dev/null | sort); do
echo "--- $f ---"
sed -n '1,280p' "$f"
done
echo '== Write-capable repository automation references =='
rg -n -i -C 3 \
'(permissions:|contents:\s*write|pull-requests:\s*write|issues:\s*write|actions/github-script|gh\s+(pr|issue|api)|git\s+(push|commit)|workflow_dispatch|repository_dispatch|npm\s+(install|ci).*(ignore-scripts)|ignore-scripts|npm_config_ignore_scripts)' \
.github package.json .npmrc CHANGELOG.md docs 2>/dev/null || true
echo '== Exact-head check runs and statuses =='
gh api "repos/$REPO/commits/$HEAD_SHA/check-runs?per_page=100" \
--jq '.check_runs[] | [.name,.status,.conclusion,.head_sha,.details_url,.app.slug] | `@tsv`' || true
gh api "repos/$REPO/commits/$HEAD_SHA/status" \
--jq '.statuses[] | [.context,.state,.target_url,.creator.login] | `@tsv`' || true
echo '== Recent PR workflow runs and their associated SHA =='
gh run list --repo "$REPO" --branch "$(gh pr view 76 --repo "$REPO" --json headRefName --jq '.headRefName')" \
--limit 30 --json databaseId,name,event,status,conclusion,headSha,headBranch,workflowName,urlLength of output: 115255 🏁 Script executed: #!/bin/bash
set -euo pipefail
HEAD_SHA="e0106ce16b7b8b493f46bf075ec5baf58762bd95"
REPO="ContextualWisdomLab/noema"
echo '== Changed workflow and contract-test source at exact head =='
for f in \
.github/workflows/ci.yml \
.github/workflows/reviewer-ci.yml \
test/ci-exact-head-contract.test.ts \
test/workflow-readiness.test.ts \
.github/workflows/hourly-product-development.yml; do
echo "--- $f ---"
git show "$HEAD_SHA:$f" | nl -ba | sed -n '1,980p'
done
echo '== Exact CI run jobs =='
for run in 31252585269 31252585267 31252585268; do
echo "--- run $run ---"
gh run view "$run" --repo "$REPO" --json databaseId,event,headSha,headBranch,conclusion,jobs,url
done
echo '== Exact CI and reviewer CI log evidence for checkout, versions, install, audit, tests =='
for run in 31252585269 31252585267; do
echo "--- run $run selected log lines ---"
gh run view "$run" --repo "$REPO" --log 2>&1 | \
rg -n -i -C 2 \
'(NOEMA_EXPECTED_HEAD_SHA|git rev-parse HEAD|v24\.19\.0|11\.17\.0|npm ci|legacy-peer-deps|install-links|ignore-scripts|npm audit|audit-level|test files|tests passed|coverage)' \
|| true
done
echo '== Exact Security Scan run jobs and event payload binding =='
gh run view 31252585268 --repo "$REPO" --json databaseId,event,headSha,headBranch,conclusion,jobs,url
gh api "repos/$REPO/actions/runs/31252585268" \
--jq '{id,event,head_sha,head_branch,path,workflow_id,conclusion,created_at,updated_at,pull_requests}'
echo '== PR reviews and merge protection metadata =='
gh pr view 76 --repo "$REPO" --json reviewDecision,reviews,mergeStateStatus,statusCheckRollup,isDraft
echo '--- branch protection/rulesets ---'
gh api "repos/$REPO/branches/main/protection" 2>&1 || true
gh api "repos/$REPO/rules/branches/main" 2>&1 || true
gh api "repos/$REPO/rulesets?includes_parents=true" 2>&1 || true
echo '== `#80` state =='
gh issue view 80 --repo "$REPO" --json number,state,title,url,body,commentsLength of output: 2384 🏁 Script executed: #!/bin/bash
set -euo pipefail
HEAD_SHA="e0106ce16b7b8b493f46bf075ec5baf58762bd95"
REPO="ContextualWisdomLab/noema"
show_numbered() {
git show "$HEAD_SHA:$1" | awk '{printf "%6d\t%s\n", NR, $0}'
}
echo '== Changed CI workflow =='
show_numbered .github/workflows/ci.yml
echo '== Changed reviewer CI workflow =='
show_numbered .github/workflows/reviewer-ci.yml
echo '== Exact-head contract test =='
show_numbered test/ci-exact-head-contract.test.ts
echo '== Workflow readiness test =='
show_numbered test/workflow-readiness.test.ts
echo '== Publisher write-boundary section =='
git show "$HEAD_SHA:.github/workflows/hourly-product-development.yml" | \
awk 'NR >= 760 && NR <= 910 {printf "%6d\t%s\n", NR, $0}'
echo '== Exact CI run jobs =='
for run in 31252585269 31252585267 31252585268; do
echo "--- run $run ---"
gh run view "$run" --repo "$REPO" --json databaseId,event,headSha,headBranch,conclusion,jobs,url
done
echo '== Exact CI and reviewer CI log evidence =='
for run in 31252585269 31252585267; do
echo "--- run $run selected log lines ---"
gh run view "$run" --repo "$REPO" --log 2>&1 | \
rg -n -i -C 2 \
'(NOEMA_EXPECTED_HEAD_SHA|git rev-parse HEAD|v24\.19\.0|11\.17\.0|npm ci|legacy-peer-deps|install-links|ignore-scripts|npm audit|audit-level|test files|tests passed|coverage)' \
|| true
done
echo '== Exact Security Scan binding =='
gh api "repos/$REPO/actions/runs/31252585268" \
--jq '{id,event,head_sha,head_branch,path,workflow_id,conclusion,created_at,updated_at,pull_requests}'
echo '== PR reviews and merge protection metadata =='
gh pr view 76 --repo "$REPO" --json reviewDecision,reviews,mergeStateStatus,statusCheckRollup,isDraft
echo '--- branch protection ---'
gh api "repos/$REPO/branches/main/protection" 2>&1 || true
echo '--- branch rules ---'
gh api "repos/$REPO/rules/branches/main" 2>&1 || true
echo '--- repository rulesets ---'
gh api "repos/$REPO/rulesets?includes_parents=true" 2>&1 || true
echo '== `#80` state =='
gh issue view 80 --repo "$REPO" --json number,state,title,url,body,commentsLength of output: 32529 🏁 Script executed: #!/bin/bash
set -u
HEAD_SHA="e0106ce16b7b8b493f46bf075ec5baf58762bd95"
REPO="ContextualWisdomLab/noema"
echo '== CI exact-run log evidence =='
gh run view 31252585269 --repo "$REPO" --log 2>&1 | \
rg -n -i -C 2 \
'(NOEMA_EXPECTED_HEAD_SHA|git rev-parse HEAD|v24\.19\.0|11\.17\.0|npm ci|legacy-peer-deps|install-links|npm audit|audit-level|test files|tests passed|coverage)' \
|| true
echo '== Reviewer CI exact-run log evidence =='
gh run view 31252585267 --repo "$REPO" --log 2>&1 | \
rg -n -i -C 2 \
'(NOEMA_EXPECTED_HEAD_SHA|git rev-parse HEAD|npm ci|ignore-scripts|pytest|coverage|interrogate)' \
|| true
echo '== Security Scan exact-run API metadata and jobs =='
gh api "repos/$REPO/actions/runs/31252585268" \
--jq '{id,event,head_sha,head_branch,path,workflow_id,conclusion,created_at,updated_at,pull_requests}' \
|| true
gh api "repos/$REPO/actions/runs/31252585268/jobs?per_page=100" \
--jq '.jobs[] | {name,conclusion,started_at,completed_at,steps}' \
|| true
echo '== Security Scan workflow source at exact head =='
for f in .github/workflows/security-scan.yml .github/workflows/security.yml; do
if git cat-file -e "$HEAD_SHA:$f" 2>/dev/null; then
echo "--- $f ---"
git show "$HEAD_SHA:$f" | awk '{printf "%6d\t%s\n", NR, $0}'
fi
done
echo '== PR review and merge state =='
gh pr view 76 --repo "$REPO" \
--json reviewDecision,reviews,mergeStateStatus,statusCheckRollup,isDraft,mergeable \
|| true
echo '== Main branch protections and rulesets =='
gh api "repos/$REPO/branches/main/protection" || true
gh api "repos/$REPO/rules/branches/main" || true
gh api "repos/$REPO/rulesets?includes_parents=true" || true
echo '== Issue `#80` =='
gh issue view 80 --repo "$REPO" --json number,state,title,url,body,comments || true
echo '== Active PR workflow source changed-file scope =='
git diff --no-ext-diff --unified=3 \
9adb784902cae19a150146a8fadd6a0491f67814 "$HEAD_SHA" \
-- .github/workflows/ci.yml .github/workflows/reviewer-ci.yml test/ci-exact-head-contract.test.ts test/workflow-readiness.test.ts \
|| trueLength of output: 57728
Blocking conditionThe repository-write boundary is not fail-closed at this head. In
A concurrent actor can create or replace the branch after the The new doctoring file correctly identifies this gap and states that Verified
Merge evidence not established
I do not approve or authorize a merge. You are interacting with an AI system. |
Summary
Remediates the repository-wide
nanoiddependency-security blocker tracked in #75 without weakeningnpm audit, changing severity thresholds, adding an ignore/waiver, or introducing write-capable repair automation. The branch also carries the minimum test-first CI hardening required to make this remediation's own acceptance evidence bind to the immutable pull-request head and a fixed Node/npm execution identity.Source boundary
mainat9adb784902cae19a150146a8fadd6a0491f67814.e0106ce16b7b8b493f46bf075ec5baf58762bd95.fix/nanoid-cve-2026-67213..github/workflows/ci.yml,.github/workflows/reviewer-ci.yml,CHANGELOG.md,docs/doctoring/nanoid-cve-2026-67213.md,package-lock.json,test/ci-exact-head-contract.test.ts, andtest/workflow-readiness.test.ts.node_modules/nanoidlockfile change is3.3.16 -> 3.3.17, withresolvedset tohttps://registry.npmjs.org/nanoid/-/nanoid-3.3.17.tgzand SRIsha512-xQLf0A3HOMlgHq0n247/LRuAOYmB7dXJ/DvAxGvsSBij45XtBSmQycu+F8ODbHwns/XyFZagyL1+J0Offw1E0g==. PostCSS's declared^3.3.16range remains unchanged.Test-first corrections
test/ci-exact-head-contract.test.tsbefore changing application CI. It requires checkout ofgithub.event.pull_request.head.sha, an explicit expected-head environment binding, andgit rev-parse HEADequality before dependency installation.reviewer-ciwith the same exact-head boundary.actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd(v6.0.2), immutableactions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e(v6.4.0), Node24.19.0, npm11.17.0, and exactlynpm ci --legacy-peer-deps=false --install-links=false; version mismatches fail before install.node-version: "24".test/workflow-readiness.test.tswas corrected to accept either the Node 24 major declaration or an exact Node 24 patch while continuing to reject Node 20. No production behavior was weakened.#77/#79 remain the broader reproducibility/install-script requirements. The old #78 implementation line has been closed as superseded; Draft PR #89 is its controlled dependency-ordered replacement on this exact #76 predecessor. This PR does not duplicate that broader workstream merely to remediate one transitive vulnerability.
Authoritative evidence
docs/doctoring/nanoid-cve-2026-67213.mdrecords the reviewed GitHub Advisory Database decision for GHSA-2v37-7h3g-55p8 / CVE-2026-67213, npm lockfile and frozen-install semantics, exact Node/npm versions and install flags, exact-head binding, repository-write CAS requirements, trusted-local-checkout criteria, fail-closed verification requirements, evidence-class separation, and APA 7th references to primary technical sources.The lockfile remains a minimal diff from the exact base. The earlier rejected candidate at
59b4bb51df92b1749ced13ce8ed440bc299d6379carried 28 unrelated package-manager metadata rewrites; those rewrites are not present in the current branch. The currentpackage-lock.jsonpatch changes only the three fields in the existingnode_modules/nanoidobject: version, registry tarball URL, and SRI integrity. No dependency declaration, package graph,@esbuild/*metadata, Sharp license metadata, Wrangler bin metadata, or unrelated package object is changed.CHANGELOG.mdrecords the bounded remediation under## Unreleasedand preserves the no-waiver/no-severity-reduction contract.Exact-head verification evidence
All three pull-request-triggered workflows associated with exact head
e0106ce16b7b8b493f46bf075ec5baf58762bd95are terminal-success:cirun31252585269: application checkout explicitly fetchede0106ce16b7b8b493f46bf075ec5baf58762bd95; the exact-head assertion passed before setup/install; Node isv24.19.0; npm is11.17.0;npm ci --legacy-peer-deps=false --install-links=falsesucceeded; 62 test files and 646 tests passed; configured production statement/branch/function/line coverage is 100%;npm audit --audit-level=highfound 0 vulnerabilities; acquisition manifest generation passed. Missing production KPI/deployment/release/revenue/transfer artifacts remain final-gate gaps and are not treated as release evidence.reviewer-cirun31252585267: terminal success after its own exact-head checkout/assertion, hash-pinned Python dependency installation, 100% reviewer test/coverage gate, 100% docstring gate, CodeGraph tooling install, Cosign/Trivy sandbox-image verification, and no-network CodeGraph smoke path.Security Scanrun31252585268: terminal success, but scanner revision binding is classified per job rather than inferred from the top-level check. The OSV job explicitly checked out base9adb784902cae19a150146a8fadd6a0491f67814and heade0106ce16b7b8b493f46bf075ec5baf58762bd95; it reported the baselinenanoid@3.3.16CVE and zero findings on the exact head, and uploaded SARIF forrefs/pull/76/headat the exact head SHA. Trivy's repository checkout used GitHub's synthetic PR merge commitc8c8a96ee9e0abda7fd73afa85830a0f9b343fd7; its zero CRITICAL/HIGH/MEDIUM result is therefore integration evidence, not promoted to exact-head evidence. Check runs, commit statuses, review evidence, scanner revision evidence, and model judgement remain separate evidence classes.The application CI log also warns that
esbuild@0.28.1andworkerd@1.20260625.1install scripts are not yet covered by npmallowScripts. That broader supply-chain execution-authority gap remains owned by #77/#79 and the replacement implementation #89; it is not suppressed or misrepresented as resolved by this security PR.Review status
CodeRabbit's predecessor-head review identified two valid issue families. Both were independently revalidated against the current branch rather than accepted or dismissed solely from thread state:
The corresponding CodeRabbit threads are resolved; one is outdated after the implementation moved its lines. No eligible independent non-author
APPROVEexists on the current head. Fresh permission probes also still showopencode-agenthas no repository collaborator permission andcwl-noema-reviewhas no usable collaborator permission, so those previously rejected review routes are not retried without an eligibility change.Safety policy
No
.github/workflows/repair-*, self-modifying GitHub Action, branch-patching workflow,contents:writerepair path, protection bypass, audit waiver, VEX/ignore, severity reduction, or synthetic approval is permitted. Queued, pending, skipped-required, cancelled, neutral-required, absent, stale-head, status-only, predecessor-head, model-only, or synthetic-merge-only evidence is not merge authority.Review and merge boundary
This PR is not merge-authorized merely because its current application CI, reviewer CI, and Security Scan are green. Merge still requires the enforceable
maingovernance tracked by #27 and the qualifying independent non-author approval required by Noema/CWL governance; issue #29 owns eligible Reviewer/Maintainer App provisioning where that route is used. No version bump or release is warranted until the integrated exact head also satisfies production KPI, deployment, provenance, release-publication, environment-governance, revenue/transfer, and other release-acceptance gates.Related: #27, #29, #75, #77, #79, #80, #89