Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions packages/cli/src/gemini.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ import { setupTerminalAndTheme } from './utils/terminalTheme.js';
import { runDeferredCommand } from './deferred.js';
import { cleanupBackgroundLogs } from './utils/logCleanup.js';
import { SlashCommandConflictHandler } from './services/SlashCommandConflictHandler.js';
import { initializeConsoleStore } from './ui/hooks/useConsoleMessages.js';

export function validateDnsResolutionOrder(
order: string | undefined,
Expand Down Expand Up @@ -295,7 +294,6 @@ export async function main() {
process.exit(ExitCodes.FATAL_INPUT_ERROR);
}

initializeConsoleStore();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

The removal of initializeConsoleStore() in gemini.tsx is incorrect as the redirection of output to stderr is intentional and expected behavior. Reverting this change is necessary to maintain the intended architecture. Furthermore, the resulting logic that writes raw data chunks directly to stdout and stderr poses a terminal injection risk. All user-provided data must be treated as untrusted and sanitized at the point of use, following the principle of defense-in-depth.

References
  1. In gemini.tsx, the ConsolePatcher is intentionally configured with stderr: true to redirect all console output to the standard error stream; this is the expected behavior.
  2. Always treat user-provided data as untrusted and apply proper validation and sanitization at the point of use, even if it is believed to have been filtered or sanitized upstream.

const isDebugMode = cliConfig.isDebugMode(argv);
const consolePatcher = new ConsolePatcher({
stderr: true,
Expand Down
2 changes: 2 additions & 0 deletions packages/cli/src/interactiveCli.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import { TerminalProvider } from './ui/contexts/TerminalContext.js';
import { isAlternateBufferEnabled } from './ui/hooks/useAlternateBuffer.js';
import { OverflowProvider } from './ui/contexts/OverflowContext.js';
import { profiler } from './ui/components/DebugProfiler.js';
import { initializeConsoleStore } from './ui/hooks/useConsoleMessages.js';

const SLOW_RENDER_MS = 200;

Expand All @@ -57,6 +58,7 @@ export async function startInteractiveUI(
resumedSessionData: ResumedSessionData | undefined,
initializationResult: InitializationResult,
) {
initializeConsoleStore();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

The initializeConsoleStore call registers listeners for CoreEvent.ConsoleLog and CoreEvent.Output, which collect raw data. To prevent terminal injection attacks, ensure that UI components rendering these messages properly sanitize terminal control characters, treating all user-provided data as untrusted. Additionally, to ensure early startup messages are captured, explicitly drain the coreEvents backlog after initializing the store.

Suggested change
initializeConsoleStore();
initializeConsoleStore();
coreEvents.drainBacklogs();
References
  1. Always treat user-provided data as untrusted and apply proper validation and sanitization at the point of use, even if it is believed to have been filtered or sanitized upstream.

// Never enter Ink alternate buffer mode when screen reader mode is enabled
// as there is no benefit of alternate buffer mode when using a screen reader
// and the Ink alternate buffer mode requires line wrapping harmful to
Expand Down
Loading