fix(dispatcher): also treat -p as non-subcommand short for --print (#1352)

Red-team follow-up to #1341: the original fix only guarded --print but
Claude accepts -p as the short form, and CCS itself passes -p in
headless-executor.ts. Without this check the security bypass survived
via the short flag.

Added regression tests: ['-p', 'agents'], ['-p', 'doctor'], ['-p']
alone, and injector short-circuit verification for -p form.
This commit is contained in:
Kai (Tam Nhu) Tran
2026-05-23 17:33:38 -04:00
committed by GitHub
parent 9a420988bc
commit 8335f0c73c
2 changed files with 15 additions and 1 deletions
+1 -1
View File
@@ -144,7 +144,7 @@ export function getClaudeSubcommandName(args: readonly string[]): string | null
const arg = args[i];
if (arg === '--') return null;
if (arg === '--print') return null;
if (arg === '--print' || arg === '-p') return null;
if (arg.startsWith('-')) {
if (VALUE_TAKING_FLAGS.has(arg)) {
@@ -62,6 +62,14 @@ describe('isClaudeSubcommandInvocation', () => {
expect(isClaudeSubcommandInvocation(['--print', 'doctor'])).toBe(false);
});
it('treats -p (short form of --print) as non-subcommand — regression for #1341', () => {
// CCS uses -p in headless-executor; without this check the security bypass
// survived via the short flag form.
expect(isClaudeSubcommandInvocation(['-p', 'agents'])).toBe(false);
expect(isClaudeSubcommandInvocation(['-p', 'doctor'])).toBe(false);
expect(isClaudeSubcommandInvocation(['-p'])).toBe(false);
});
it('handles --flag=value forms', () => {
expect(isClaudeSubcommandInvocation(['--model=sonnet', 'agents'])).toBe(true);
});
@@ -214,6 +222,12 @@ describe('subcommand passthrough — injectors short-circuit', () => {
expect(out).toContain('--disallowedTools');
});
it('injectors still inject in -p prompt mode — regression for #1341', () => {
const out = appendThirdPartyWebSearchToolArgs(['-p', 'agents']);
expect(out).toContain('--append-system-prompt');
expect(out).toContain('--disallowedTools');
});
it('injectors still inject for non-subcommand interactive launches', () => {
const out = appendThirdPartyWebSearchToolArgs(['fix the bug']);
expect(out).toContain('--append-system-prompt');