[security] fix(approvals): require admin for approval responses#2478
Open
Hinotoi-agent wants to merge 1 commit into
Open
[security] fix(approvals): require admin for approval responses#2478Hinotoi-agent wants to merge 1 commit into
Hinotoi-agent wants to merge 1 commit into
Conversation
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.
Summary
This PR hardens NanoClaw's approval-response trust boundary: a valid approval
questionIdis no longer enough to resolve a pending privileged approval.<channelType>:<userId>format used by the permissions tables before role checks are evaluated.Security issues covered
questionIdbefore authorizing the responder identityBefore this PR
handleApprovalsResponse()looked up a pending approval byquestionIdand then resolved OneCLI approvals or dispatched module approval handlers.userId,channelType,platformId,threadId), but the responder identity was not checked against owner/admin privileges before the approval decision was accepted.After this PR
hasAdminPrivilege(userId, agentGroupId).Why this matters
Approval callbacks are transport-facing input. Even when approval cards are intended for admin DMs or controlled channels, the inbound callback payload itself should not be the security decision. Privileged actions such as package/plugin/self-modification style workflows should depend on a server-side role check for the actual responder identity, not only on possession of a
questionId.How this differs from related issue/PR
PR #2308 tightened approval-card prompting and removed a ghost tool reference. This PR addresses a different boundary in the approval response handler itself: the server-side authorization check that decides whether the clicker/responder is allowed to resolve a pending approval.
Attack flow
Affected code
src/modules/approvals/response-handler.tssrc/modules/approvals/response-handler.test.tsRoot cause
Issue: approval response authorization was keyed too narrowly to the approval id.
handleApprovalsResponse()treated a matching pending approval row as sufficient to continue to the approval resolver/handler path.CVSS assessment
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:NRationale:
Safe reproduction steps
install_packages.questionIdbut a non-admin responder identity.The new regression test implements this flow with a local test database and safe fake package payloads.
Expected vulnerable behavior
Changes in this PR
namespacedUserId()to normalize responder ids before permission checks and handler dispatch.isAuthorizedApprovalClick()to enforce owner/global-admin or scoped admin authorization before approval resolution.Files changed
src/modules/approvals/response-handler.tssrc/modules/approvals/response-handler.test.tsMaintainer impact
Fix rationale
hasAdminPrivilege,isOwner, andisGlobalAdminkeeps the fix aligned with the existing role model.Type of change
Test plan
Executed with:
pnpm exec vitest run src/modules/approvals/response-handler.test.tspnpm test -- --run src/modules/approvals/response-handler.test.tspnpm typecheckpnpm format:checkgit diff --check HEAD~1..HEADpnpm lintNotes:
pnpm test -- --run src/modules/approvals/response-handler.test.tsexecuted the repository's Vitest suite in this environment; it passed with 30 test files and 326 tests.pnpm lintfails on pre-existing unrelated lint issues such as unused imports/variables and broad catch-block warnings in files not touched by this PR.ciandlabelchecks for this PR.Disclosure notes