mirror of
https://github.com/openai/codex.git
synced 2026-11-06 20:20:34 +00:00
Reject oversized reviewed terminal input (#41159)
## Why Reviewing a shortened `write_stdin` action while sending the complete input could allow unreviewed bytes to reach an escalated terminal. ## What changed - Require the fully formatted action and approval reason to fit within 8,000 bytes. - Reject truncated or oversized actions before requesting approval or writing any bytes to the terminal. - Document the reviewed stdin size limit in the app-server protocol. ## Testing Add an integration test that uses JSON escaping to push a formatted action over the limit and verifies that it is neither offered for approval nor executed, while a subsequent valid write still succeeds. GitOrigin-RevId: f6c96a78a65a136366c8119a7d242dfc2ec05fe6
This commit is contained in:
@@ -244,8 +244,7 @@ impl GuardianRejectionCircuitBreaker {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
use approval_request::format_guardian_action_pretty;
|
||||
pub(crate) use approval_request::format_guardian_action_pretty;
|
||||
#[cfg(test)]
|
||||
use approval_request::guardian_assessment_action;
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -266,7 +266,9 @@ impl ApprovalAction {
|
||||
}
|
||||
}
|
||||
|
||||
fn into_guardian_request(self) -> std::io::Result<crate::guardian::GuardianApprovalRequest> {
|
||||
pub(crate) fn into_guardian_request(
|
||||
self,
|
||||
) -> std::io::Result<crate::guardian::GuardianApprovalRequest> {
|
||||
Ok(match self {
|
||||
Self::ExecCommand {
|
||||
id,
|
||||
|
||||
@@ -798,6 +798,22 @@ impl UnifiedExecProcessManager {
|
||||
};
|
||||
let _interaction_guard = locked_process.interaction_lock().lock_owned().await;
|
||||
if let Some(approval) = approval {
|
||||
let approval_reason = "Send input to an existing escalated terminal. The cwd is its launch directory; the terminal's current directory and state may have changed.".to_string();
|
||||
let reviewed = crate::guardian::format_guardian_action_pretty(
|
||||
&approval.clone().into_guardian_request().map_err(|err| {
|
||||
UnifiedExecError::StdinApproval(ToolError::Rejected(err.to_string()))
|
||||
})?,
|
||||
)
|
||||
.map_err(|err| UnifiedExecError::StdinApproval(ToolError::Rejected(err.to_string())))?;
|
||||
// Bound the entire serialized action plus its reason, including JSON
|
||||
// escaping. Reject, never execute an unreviewed tail.
|
||||
if reviewed.truncated
|
||||
|| reviewed.text.len().saturating_add(approval_reason.len()) > 8_000
|
||||
{
|
||||
return Err(UnifiedExecError::StdinApproval(ToolError::Rejected(
|
||||
"terminal input and permission details are too large to review safely; use a smaller input or start a new terminal with fewer grants".to_string(),
|
||||
)));
|
||||
}
|
||||
let strict_auto_review = context
|
||||
.session
|
||||
.active_turn_context_and_strict_auto_review()
|
||||
@@ -809,7 +825,7 @@ impl UnifiedExecProcessManager {
|
||||
call_id: context.call_id.clone(),
|
||||
tool_name: ToolName::plain("write_stdin"),
|
||||
strict_auto_review,
|
||||
approval_reason: Some("Send input to an existing escalated terminal. The cwd is its launch directory; the terminal's current directory and state may have changed.".to_string()),
|
||||
approval_reason: Some(approval_reason),
|
||||
retry_reason: None,
|
||||
network_approval_context: None,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user