diff --git a/src/settings/command-authorization.ts b/src/settings/command-authorization.ts index 98252bf50b..67b704c0d6 100644 --- a/src/settings/command-authorization.ts +++ b/src/settings/command-authorization.ts @@ -51,7 +51,8 @@ export function normalizeCommandAuthorizationPolicy(input: unknown): { policy: R export function commandAuthorizationAllowedRoles(policy: RepositoryCommandAuthorizationPolicy | null | undefined, commandName: string): CommandAuthorizationRole[] { const normalized = normalizeCommandAuthorizationPolicy(policy).policy; - return dedupeRoles(normalized.commands[commandName] ?? normalized.default); + const commandRoles = Object.hasOwn(normalized.commands, commandName) ? normalized.commands[commandName] : undefined; + return dedupeRoles(commandRoles ?? normalized.default); } export function commandAuthorizationNeedsMinerDetection(args: { diff --git a/test/unit/command-authorization.test.ts b/test/unit/command-authorization.test.ts index 4014a9fd5f..03024def88 100644 --- a/test/unit/command-authorization.test.ts +++ b/test/unit/command-authorization.test.ts @@ -1,5 +1,6 @@ import { describe, expect, it } from "vitest"; import { + commandAuthorizationAllowedRoles, commandAuthorizationNeedsMinerDetection, evaluateCommandAuthorization, normalizeCommandAuthorizationPolicy, @@ -54,6 +55,17 @@ describe("repo command authorization policy", () => { }); }); + it("falls back to default roles for inherited object property command names", () => { + for (const commandName of ["constructor", "toString", "__proto__", "hasOwnProperty"]) { + expect(commandAuthorizationAllowedRoles(undefined, commandName)).toEqual(["maintainer", "collaborator", "confirmed_miner"]); + expect(evaluateCommandAuthorization({ commandName, commenterAssociation: "OWNER" })).toMatchObject({ + authorized: true, + reason: "maintainer_invocation", + allowedRoles: ["maintainer", "collaborator", "confirmed_miner"], + }); + } + }); + it("warns on malformed policy and falls back to default command roles", () => { const nonObject = normalizeCommandAuthorizationPolicy("not-a-policy"); expect(nonObject.warnings).toEqual(["commandAuthorization must be an object; using secure defaults."]);