fix(security): update transitive nanoid for CVE-2026-67213 - #76
fix(security): update transitive nanoid for CVE-2026-67213#76seonghobae wants to merge 16 commits into
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)
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/#78 remain the broader acquisition-readiness workstream for repository-level
packageManager/devEngines, strict dependency install-script policy, immutable Node-24-native Actions across the remaining workflows, and lockfile change control. This PR does not duplicate that entire 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 policy gap remains in #77/#78; 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.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 an eligible independent non-author approval, enforceable
maingovernance under #27, Reviewer/Maintainer App provisioning under #29 where required by repository policy, and acceptance of the explicitly classified scanner revision evidence. 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: #75, #77, #78, #80, #27, #29
Summary by CodeRabbit
보안
nanoid의존성을 최신 보안 수정 버전으로 업데이트했습니다.문서