fix(security): add path-containment guards to script CLI path inputs - #2162
fix(security): add path-containment guards to script CLI path inputs#21620xDEnYO wants to merge 2 commits into
Conversation
Contain free-form path-building inputs the same way #2143 did for getDeployLogFile: network names in the four propose*Mappings scripts [aikido:286911101,286911102,434639614,434639616,154847648,154847649,161720063,161720065] and generateHexagateImportCsv [aikido:222857805], contract names in getFunctionSelectors [aikido:152923770,152923771], and all path args of generateLedgerClearSigning [aikido:277413157..277413168]. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
WalkthroughThe change adds containment checks for network-derived deployment paths, compiled contract paths, and ledger command paths. It also updates path-traversal matching guidance with supported validation and sanitization cases. ChangesPath containment validation
Estimated code review effort: 3 (Moderate) | ~20 minutes Suggested labels: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 2📝 Generate docstrings 💡
🛠️ Fix failing CI checks 💡
🧪 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 |
…alog pattern Gate-review findings on this PR: the exported getFunctionSelectors gained a new throw branch without a JSDoc @throws tag (same gap fixed for getDeployLogFile after #2143), and the catalog's path_traversal_scripts entry overclaimed SupportedChain typing for call sites that take plain strings — narrowed so free-form CLI paths get guards, not ignores. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
🔒 Gate review (local trial) — residual findingsAuto-fixed in Watch item (from git history): the byte-identical guard on Lower-confidence — human judgment (60–79, not acted):
Dropped (<60): extracting a shared guard helper (48 — inline matches the merged #2143 precedent; valid follow-up refactor), error-message style drift in |
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@script/utils/viemScriptHelpers.ts`:
- Around line 363-371: Replace the prefix-only parent-directory checks with
segment-aware checks that reject only a relative path equal to ".." or beginning
with "..${path.sep}", while retaining the absolute-path check. Apply this
containment predicate in script/utils/viemScriptHelpers.ts lines 363-371,
script/tasks/generateHexagateImportCsv.ts lines 162-170,
script/tasks/proposeAllBridgeChainIdMappings.ts lines 76-80,
script/tasks/proposeDeBridgeDlnChainIdMappings.ts lines 73-77,
script/tasks/proposeMegaETHBridgeRegistrations.ts lines 73-77,
script/tasks/proposePolymerCCTPChainIdMappings.ts lines 76-80, and
tasks/generateLedgerClearSigning.ts lines 136-142; add regression coverage there
for accepting "..name" descendants and rejecting "../" escapes.
🪄 Autofix (Beta)
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: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 5872a68b-14b3-420b-884d-e47c32a28d01
📒 Files selected for processing (8)
.agents/references/aikido-false-positive-catalog.mdscript/tasks/generateHexagateImportCsv.tsscript/tasks/proposeAllBridgeChainIdMappings.tsscript/tasks/proposeDeBridgeDlnChainIdMappings.tsscript/tasks/proposeMegaETHBridgeRegistrations.tsscript/tasks/proposePolymerCCTPChainIdMappings.tsscript/utils/viemScriptHelpers.tstasks/generateLedgerClearSigning.ts
Which Linear task belongs to this PR?
Fixes EXSC-731
Why did I implement it this way?
This PR resolves the 21 open Aikido "Potential file inclusion attack via reading file" findings whose flagged input genuinely is free-form (CLI-supplied path fragments with no upstream allow-list validation), using the same containment-guard pattern PR #2143 established for
getDeployLogFile: resolve against the intended base directory, then reject any path whosepath.relative(base, …)escapes it.propose{PolymerCCTP,AllBridge,DeBridgeDln,MegaETH}…(4 identical localgetDeploymentsFilePathcopies):--networkis interpolated intodeployments/<network>[.staging].jsonbefore anynetworks.jsonvalidation happens (isTestnetNetwork()returnsfalsefor unknown names rather than throwing). The guard lives inside the shared-shape helper so both theexistsSyncandreadFileSyncsites in each file are covered.getFunctionSelectors(script/utils/viemScriptHelpers.ts): same guard fix(security): AI Fix for Potential file inclusion attack via reading file #2143 added togetDeployLogFiletwo functions below, applied to theout/<contractName>.sol/<contractName>.jsonpath.generateHexagateImportCsv.ts:--networksCSV entries are read asdeployments/<n>.diamond.jsonin the samePromise.allthat loadsnetworks.json, i.e. before the unknown-network skip can run — names are now containment-checked at parse time.tasks/generateLedgerClearSigning.ts: all path args (--ledgerFilePath,--outputFilePath,--proposalFilePath,--facetsDir,--foundryOutDir,--deploymentsDir,--networksJson) now resolve through aresolveWithinCwd()helper. Every legitimate invocation stays inside the working directory: repo defaults locally, andledger-registry/<path>insyncLedgerClearSigning.yml(the registry clone is a subdirectory of the workspace).Guards were falsified against real inputs:
--networks '../../etc/passwd'and--networks '../secrets'→Invalid network name,--ledgerFilePath '../../../etc/hosts'→Path escapes the working directory,getFunctionSelectors('../../foundry.toml/x')→Invalid contract name; happy paths (--networks mainnetCSV generation, valid contract name reaching the artifact lookup) confirmed unchanged.Findings where the catalogue's false-positive rationale is actually true for the call site (repo-derived walks,
assertSafePathSegment-sanitized names,networks.json-validated inputs, mktemp-file reads) were ignored in Aikido with per-call-site reasons instead of guarding — a cwd-containment guard would have broken legitimate flows likediamondUpdateFacet.sh's mktemp calldata file.Checklist before requesting a review
Checklist for reviewer (DO NOT DEPLOY and contracts BEFORE CHECKING THIS!!!)