Context
Follow-up to GHSA-3g98-ffw6-87mg (PR in advisory private fork).
The fix for the repo-supplied .opencli/settings.json confused-deputy attack dropped project-scoped allow entirely and routed every "always allow" grant to the global ~/.opencli/config.json. That closes the attack but widens the blast radius: a grant approved in repo A (e.g. bash:*) now silently carries into the next repo a user clones — including a hostile one.
Proposal
Restore per-project grant scoping without giving repo-shipped files any authority: store project grants somewhere the repository cannot write, keyed by the project path, e.g.
~/.opencli/project-permissions/<sha256(cwd)>.json { "allow": ["bash:*", ...] }
buildPermissionSources would merge this file's allow into the grant set (trusted, because it lives in the user's home, not the repo).
- The interactive "always for this project" choice (removed in the GHSA-3g98 fix) could return, writing to this file instead of the repo's
.opencli/settings.json.
- Repo-supplied
.opencli/settings.json allow stays ignored; ask/deny from the repo stay honoured (restrictive only).
Acceptance
- A grant made in project A does not apply in project B.
- A
.opencli/settings.json shipped with permissions.allow still has no auto-approve authority (the original GHSA-3g98 invariant holds).
- The "ignored project-scoped allow" warning (
ignoredProjectAllowWarning) stays in place.
References
- GHSA-3g98-ffw6-87mg
src/cli/confirm.ts (buildPermissionSources, ignoredProjectAllowWarning)
- Review note on the GHSA-3g98 PR: "removing project grants widens blast radius"
Context
Follow-up to GHSA-3g98-ffw6-87mg (PR in advisory private fork).
The fix for the repo-supplied
.opencli/settings.jsonconfused-deputy attack dropped project-scopedallowentirely and routed every "always allow" grant to the global~/.opencli/config.json. That closes the attack but widens the blast radius: a grant approved in repo A (e.g.bash:*) now silently carries into the next repo a user clones — including a hostile one.Proposal
Restore per-project grant scoping without giving repo-shipped files any authority: store project grants somewhere the repository cannot write, keyed by the project path, e.g.
buildPermissionSourceswould merge this file'sallowinto the grant set (trusted, because it lives in the user's home, not the repo)..opencli/settings.json..opencli/settings.jsonallowstays ignored;ask/denyfrom the repo stay honoured (restrictive only).Acceptance
.opencli/settings.jsonshipped withpermissions.allowstill has no auto-approve authority (the original GHSA-3g98 invariant holds).ignoredProjectAllowWarning) stays in place.References
src/cli/confirm.ts(buildPermissionSources,ignoredProjectAllowWarning)