refactor(server): use parseOwnerRepo helper in artifact route for defense-in-depth#1243
refactor(server): use parseOwnerRepo helper in artifact route for defense-in-depth#1243shaun0927 wants to merge 1 commit intocoleam00:devfrom
Conversation
…ense-in-depth
The artifact endpoint parsed codebase.name with split('/') and only
checked nameParts.length < 2, duplicating and weakening the shared
parseOwnerRepo helper already used by registerRepository. Replace with
the helper that also rejects '..', '.', empty segments, and non-safe
characters.
Not an exploitable bug today — registration already goes through
basename()/URL parsing which feed parseOwnerRepo — but collapses a
future regression class if a new name-creation path is ever added.
📝 WalkthroughWalkthroughThe Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
|
Hi @shaun0927 — thanks for opening this PR. This repository uses a PR template at
Could you fill those out (even briefly)? The template helps reviewers understand scope, risk, and rollback — it speeds up review significantly. If a section genuinely doesn't apply, just write "N/A" in it rather than leaving it blank. |
|
Updated the PR description with the missing template sections (Architecture Diagram, Label Snapshot, Change Metadata, Security Impact, Compatibility/Migration, Side Effects/Blast Radius, Rollback Plan, Risks and Mitigations). No code change in this comment — CodeRabbit reported "no actionable comments" and there are no pending bot findings on this branch. The change itself is a single-callsite swap from inline |
Summary
packages/server/src/routes/api.ts:2405-2410parsescodebase.namewithsplit('/')and only checksnameParts.length < 2, duplicating — and weakening — the sharedparseOwnerRepohelper already used byregisterRepository,cloneRepository, and project-structure initialization. Today no hostile input reaches this path (registration goes throughbasename()/ URL parsing which feedparseOwnerRepo), so this is not an exploitable bug. It is a consistency and defense-in-depth fix.parseOwnerRepo(packages/paths/src/archon-paths.ts:221) already rejects..,., empty segments, and non-SAFE_NAMEcharacters — with 18 test cases covering traversal, injection, and edge cases. The artifact endpoint rejects none of those. Using the helper collapses one class of future regression if a new name-creation path is ever added. It also means the validation contract lives in one place.split('/') + length < 2check in theGET /api/workflow-runs/:runId/artifacts/:filenamehandler with aparseOwnerRepo(codebase.name)call. Same 404 shape on rejection. AddedparseOwnerRepoto the@archon/pathsimport block.owner/reponames (the common case). The filename guard above it ('\0'+..segment check at lines 2374-2377) is untouched. Thenormalize(filePath).startsWith(normalize(artifactDir))final safety check at lines 2416-2419 is untouched. Registration paths (registerRepository/cloneRepository) already useparseOwnerRepo— unchanged.UX Journey
No user-facing behavior change for valid inputs. For the (currently unreachable) malformed case:
Before
After
Files Changed
1 file:
packages/server/src/routes/api.ts(+4 −3)Testing
bun run type-check— all 10 packages cleanbun run lint— zero warningsbun test packages/server/src/routes/api.workflows.test.ts— 27 pass, 0 failparseOwnerRepohas 18 dedicated test cases inpackages/paths/src/archon-paths.test.ts:275-329covering traversal, injection, empty, dot, and SAFE_NAME patternsSummary by CodeRabbit
Bug Fixes
Refactor
Architecture Diagram
Before
Other paths already centralized:
After
Connection inventory:
routes/api.tsartifact handler@archon/paths::parseOwnerReporoutes/api.tsartifact handlersplit('/')Label Snapshot
risk: lowsize: XSserverserver:routes/api.tsChange Metadata
refactorserverpackages/server/src/routes/api.ts)Linked Issue
Validation Evidence
CodeRabbit summary review reported "No actionable comments." Build/CI on the branch is green at the time of this update.
Security Impact
.././empty/non-SAFE_NAME inputs that the inline check accepted in principle)basename()/URL parsing). The change closes a future-regression class if a new name-creation path is ever added.Compatibility / Migration
owner/repocodebase names continue to resolve identically. The only behavior delta is for inputs that already would have failed the downstreamnormalize().startsWith()guard, which now fail earlier with the same 404 shape.Human Verification
GET /api/workflow-runs/<id>/artifacts/<file>for a valid registered codebase returns artifact bytes unchanged.nameis missing the/separator (returns the same 404 the inline check returned).Side Effects / Blast Radius
owner/reponame that previously slipped pastlength<2but contained suspicious characters will now 404 earlier. No existing valid codebase names match that pattern.archon.artifact_404events.Rollback Plan
archon.artifact_404for previously-served codebases (none observed in pre-merge testing).Risks and Mitigations
parseOwnerRepois stricter thanlength<2, so a legacy codebase row with an unusual name could now 404. Mitigation: all current registration flows already produce names that satisfyparseOwnerRepo(verified by reading the registration code paths cited above).parseOwnerRepoever needs to be loosened/tightened.