openai / openai/codex-security

Bulk-scan wizard drops cancellation while waiting on interactive prompts

Open
#539 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
10.8k
Forks
801
Avg merge
1d 8h
Merged PRs (30d)
257

Description

Summary

runBulkScanWizard() accepts an AbortSignal and propagates it through GitHub authentication/discovery requests, but then stops forwarding it to several blocking interactive prompts.

Once discovery reaches account/repository selection, output-directory entry, or the final confirmation, cancellation can no longer interrupt the prompt even though BulkScanPrompt already exposes a signal parameter for every prompt method.

Reproduction / evidence

The prompt contract is signal-aware:

confirm(question, defaultValue?, signal?): Promise<boolean>;
input(question, defaultValue?, signal?): Promise<string>;
select(question, options, presentation?, signal?): Promise<Value>;

Current main at 37bf87a692fc72d41f7312cc48808d699d204fba correctly forwards the signal to createGitHub() and discoverGitHubRepositories(), but omits it at these call sites:

selectGitHubOwner(...)
  -> prompt.select(...);                  // no signal

selectGitHubRepositories(...)
  -> prompt.select(...);                  // no signal

prompt.input(
  "Where should scan results be saved?",
  "./security-scans",
);                                        // no signal

prompt.confirm("Start scanning?");        // no signal

Minimal deterministic reproduction with an injected BulkScanPrompt:

  1. let GitHub discovery return one active repository;
  2. pass an AbortSignal to runBulkScanWizard();
  3. instrument select, input, and confirm to record the signal they receive;
  4. current main records undefined at those interactive boundaries despite the wizard having the caller's signal.

With a real terminal prompt, cancellation during one of those waits cannot reach Inquirer until the user supplies input or the process is otherwise terminated.

Expected behavior

Every blocking prompt in a signal-aware wizard should receive the same caller AbortSignal that is already used for GitHub requests, so cancellation remains effective throughout the workflow.

Root cause

The signal is threaded through the network/discovery helpers but was omitted from the prompt call sites. selectGitHubRepositories() does not currently accept a signal at all, and selectGitHubOwner() accepts one but does not pass it to prompt.select().

Suggested fix

  • pass signal to account selection;
  • add signal to selectGitHubRepositories() and pass it to repository selection;
  • pass signal to output-directory input and final confirmation;
  • add focused prompt-boundary regression coverage proving all blocking prompts receive the caller signal.

Impact

This is a cancellation/reliability bug rather than data corruption. A user or automation can request cancellation successfully during GitHub discovery, then have the same cancellation become ineffective once the wizard is waiting for terminal input.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the runBulkScanWizard() entry point and trace selectGitHubOwner(), selectGitHubRepositories(), the output-directory prompt.input(), and the final prompt.confirm(). Use an injected BulkScanPrompt to record signals, then add focused regression coverage showing that each blocking prompt receives the caller's AbortSignal.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
cli, testing-qa
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.