fix: verify automation re-export path stays inside the automations root - #33
Open
mittalpk wants to merge 1 commit into
Open
fix: verify automation re-export path stays inside the automations root#33mittalpk wants to merge 1 commit into
mittalpk wants to merge 1 commit into
Conversation
exportAutomation() derived the re-export directory from a persisted automation's exportedPath (path.dirname(prior.exportedPath)) with no check that it still resolves inside automationsRoot(), then mkdirSync + writeFileSync(automation.json) into it. A relocated or tampered exportedPath in the persisted built-automation.json (which lives under the sessions root, a separate directory) causes automation.json to be written outside the automations root. The sibling Skill Builder already guards the equivalent re-install path via an isInside(root, dir) containment check (electron/skillbuilder/builder.ts); this defense-in-depth guard was missing for the Automation Builder's re-export path. Fixed by exporting isInside from skillbuilder/builder.ts and reusing it here: only reuse the prior directory when it's still inside the automations root, otherwise fall back to a fresh, non-colliding directory (matching the exact reuse-decision pattern already used by exportSkill()). Fixes microsoft#17.
Author
|
@microsoft-github-policy-service agree |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #17.
What's wrong
AutomationBuilder.exportAutomation()derives the re-export directory from a persisted automation'sexportedPath:with no check that it still resolves inside
automationsRoot(), beforemkdirSync+writeFileSync(automation.json)into it.priorcomes frombuilt-automation.json, persisted under the sessions root — a separate directory from the automations root. A relocated or tamperedexportedPathin that file causesautomation.jsonto be written outside the automations root on re-export.The sibling Skill Builder already guards the equivalent re-install path with an
isInside(root, dir)containment check (electron/skillbuilder/builder.ts) — this defense-in-depth guard was just missing for the Automation Builder's re-export path.Fix
Exported
isInsidefromskillbuilder/builder.tsand reused it inautomationbuilder/builder.ts: only reuse the prior directory when it's still inside the automations root, otherwise fall back to a fresh, non-colliding directory — this is exactly the reuse-decision patternexportSkill()already uses, applied here for consistency rather than inventing a new approach.How I tested it
electron/automationbuilder/builder.test.ts(registered inpackage.json'stestscript), two cases:built-automation.jsonwhoseexportedPathpoints outside the automations root (anoutsideRoottemp dir), callsAutomationBuilder.create()with a fully-formed plan (no live Copilot session needed —create()is deterministic when passed an explicit plan, per its own docstring), and asserts the resulting export path stays inside the automations root and nothing is written into the attacker-controlled directory.builder.tsviagit stash— the exact reported bug reproduces,automation.jsonlands in the outside directory. Passes after the fix.npm run typecheck— clean.npm test— 59/60 subtests pass; 1 pre-existing failure (writeDebugBundle zips the whole session...inelectron/debug-bundle.test.ts) confirmed to fail identically on cleanmainwith none of this PR's changes present — unrelated to this change.This PR was developed with AI-assisted tooling (Claude Code); I reviewed the diagnosis, the fix, and the tests, and ran typecheck/tests locally as noted above.