Summary
The opt-in safe-bash OpenAI LLM provider ignores a configured maxResponseBytes below 64 KiB when handling non-2xx HTTP responses. Severity: Low, a bounded resource-budget enforcement defect. No credential leak or sandbox escape is claimed.
Current-code evidence
Reviewed revision d126d35.
- packages/safe-bash/src/commands/llm/openai-http.ts:106 calls openAiJson(response, input.signal, 64 * 1024) on errors.
- packages/safe-bash/src/commands/llm/openai.ts constructs the configured limits but does not pass maxResponseBytes to openAiResponse.
- packages/safe-bash/src/commands/llm/README.md:236 documents maxResponseBytes as the maximum bytes in each response body.
Reproduction
Run from repository root. Uses current TypeScript source, a fake credential and in-memory transport; no files, external requests or real LLM calls. One-byte chunks demonstrate continued consumption beyond the limit rather than merely receiving one oversized transport chunk.
// node --import tsx --input-type=module
import { createOpenAiProvider } from './packages/safe-bash/src/commands/llm/openai.ts';
let consumed = 0, disposed = 0;
const transport = async () => ({
status: 401, statusText: 'Unauthorized', headers: [],
body: (async function* () {
for (const byte of new TextEncoder().encode(JSON.stringify({
error: { message: 'denied' }, padding: '1234567890'
}))) { consumed++; yield Uint8Array.of(byte); }
})(),
async dispose() { disposed++; }
});
const provider = createOpenAiProvider({
transport, apiKey: 'mock', models: [{ id: 'chat', endpoint: 'chat' }],
limits: { maxResponseBytes: 1 }
});
try {
for await (const chunk of provider.complete({
model: 'chat', prompt: 'p', attachments: [], options: {},
signal: new AbortController().signal
})) {}
} catch (error) {
console.log({ error: error.message, consumed, disposed });
}
Observed independently after the Daybreak Blue scan:
{"error":"OpenAI HTTP 401: denied","configuredMaxResponseBytes":1,"responseBytesConsumed":53,"disposed":1}
Expected: error-body parsing honors the configured cap, with only bounded overflow detection, and always disposes the response. Actual: all 53 one-byte chunks are read and parsed despite the one-byte cap. The error path has its own 64 KiB ceiling, so this is not unbounded consumption and does not exceed the default 64 MiB setting.
Scope and acceptance criteria
Affected hosts must explicitly register the LLM plugin and reference provider, configure a response cap below 64 KiB, and receive an HTTP error. LLM is not included in default agentCommands.
Pass the configured budget into error handling (retaining the smaller diagnostic ceiling), add a mocked regression covering small limits and cleanup, and preserve cancellation and useful bounded error reporting. No fix is included in this report.
Summary
The opt-in safe-bash OpenAI LLM provider ignores a configured maxResponseBytes below 64 KiB when handling non-2xx HTTP responses. Severity: Low, a bounded resource-budget enforcement defect. No credential leak or sandbox escape is claimed.
Current-code evidence
Reviewed revision d126d35.
Reproduction
Run from repository root. Uses current TypeScript source, a fake credential and in-memory transport; no files, external requests or real LLM calls. One-byte chunks demonstrate continued consumption beyond the limit rather than merely receiving one oversized transport chunk.
Observed independently after the Daybreak Blue scan:
{"error":"OpenAI HTTP 401: denied","configuredMaxResponseBytes":1,"responseBytesConsumed":53,"disposed":1}Expected: error-body parsing honors the configured cap, with only bounded overflow detection, and always disposes the response. Actual: all 53 one-byte chunks are read and parsed despite the one-byte cap. The error path has its own 64 KiB ceiling, so this is not unbounded consumption and does not exceed the default 64 MiB setting.
Scope and acceptance criteria
Affected hosts must explicitly register the LLM plugin and reference provider, configure a response cap below 64 KiB, and receive an HTTP error. LLM is not included in default agentCommands.
Pass the configured budget into error handling (retaining the smaller diagnostic ceiling), add a mocked regression covering small limits and cleanup, and preserve cancellation and useful bounded error reporting. No fix is included in this report.