Skip to content

fix(security): cap Retry-After sleep and sanitize mimeType in uploads#448

Open
anshul-garg27 wants to merge 1 commit intogoogleworkspace:mainfrom
anshul-garg27:fix/cap-retry-after-sleep
Open

fix(security): cap Retry-After sleep and sanitize mimeType in uploads#448
anshul-garg27 wants to merge 1 commit intogoogleworkspace:mainfrom
anshul-garg27:fix/cap-retry-after-sleep

Conversation

@anshul-garg27
Copy link
Contributor

Summary

Two security hardening fixes for agent-facing attack surfaces:

1. Cap Retry-After sleep to 60 seconds (Critical)

A hostile or compromised API server can return Retry-After: 4294967295 in a 429 response, causing the CLI process to sleep for ~136 billion years. This is a denial-of-service vector, especially dangerous in unattended AI agent workflows where the process runs without human supervision.

Fix: Add .min(60) cap on the parsed Retry-After value in send_with_retry().

2. Sanitize mimeType in multipart upload headers (High)

The user-supplied mimeType field from --json body metadata is embedded directly into a MIME Content-Type header:

Content-Type: {media_mime}\r\n\r\n

A crafted mimeType like text/plain\r\nX-Injected: malicious could inject arbitrary MIME headers into the outbound multipart request body.

Fix: Strip \r and \n characters from media_mime before header construction.

Test plan

  • Added test verifying retry cap clamps large values to 60
  • Added test verifying normal values pass through unchanged
  • Existing client and executor tests continue to pass

Two security fixes:

1. Cap Retry-After header value to 60 seconds. A hostile or
   compromised API server could send Retry-After: 4294967295 to hang
   the CLI process indefinitely. This is especially dangerous for AI
   agent workflows where the process runs unattended.

2. Strip CR/LF from user-supplied mimeType before embedding it in
   the multipart MIME header. A mimeType like "text/plain\r\nX-Evil:
   injected" could inject arbitrary MIME headers into the upload body.
@changeset-bot
Copy link

changeset-bot bot commented Mar 12, 2026

🦋 Changeset detected

Latest commit: 12f4e07

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@googleworkspace/cli Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces two critical security enhancements to the CLI's agent-facing attack surfaces. It addresses a potential denial-of-service vulnerability by capping Retry-After sleep durations and mitigates a header injection risk by sanitizing user-provided mimeType values during multipart uploads. These changes improve the robustness and security of the application, especially in automated AI agent workflows.

Highlights

  • Retry-After Sleep Cap: Implemented a 60-second cap on the Retry-After header value to prevent denial-of-service attacks where a malicious server could cause the CLI process to sleep indefinitely, especially in AI agent workflows.
  • mimeType Sanitization: Stripped carriage return and newline characters from user-supplied mimeType values in multipart upload headers to prevent MIME header injection vulnerabilities.
Changelog
  • .changeset/fix-retry-after-and-mime-injection.md
    • Added a new changeset file documenting the security fixes for Retry-After and mimeType sanitization.
  • src/client.rs
    • Introduced a MAX_RETRY_DELAY_SECS constant set to 60 seconds.
    • Applied a .min(MAX_RETRY_DELAY_SECS) cap to the parsed Retry-After header value.
    • Added a new test case retry_after_cap_prevents_unbounded_sleep to verify the Retry-After cap functionality.
  • src/executor.rs
    • Modified the build_multipart_body function to filter out carriage return (\r) and newline (\n) characters from the media_mime string before header construction.
Activity
  • The author added a test to verify the Retry-After cap correctly clamps large values to 60 seconds.
  • A test was added to confirm that normal Retry-After values below the cap pass through unchanged.
  • Existing client and executor tests were confirmed to continue passing.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Generative AI Prohibited Use Policy, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces two important security hardening fixes. The first change caps the Retry-After sleep duration to prevent a potential denial-of-service attack, and the second sanitizes the mimeType in multipart uploads to prevent MIME header injection. The implementations for both fixes are correct. I've added one comment regarding the test for the Retry-After cap to make it more robust.

Comment on lines +67 to +71
const MAX_RETRY_DELAY_SECS: u64 = 60;
// A server sending Retry-After: 999999 should be capped to 60
let server_value: u64 = 999_999;
let capped = server_value.min(MAX_RETRY_DELAY_SECS);
assert_eq!(capped, 60);
Copy link
Contributor

Choose a reason for hiding this comment

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

high

There are a couple of improvements for this test:

  1. The constant MAX_RETRY_DELAY_SECS is redefined here. It's also defined in send_with_retry. This can lead to inconsistencies if one is updated and the other is not. Consider defining it at the module level and reusing it in both places.
  2. The assertion on line 71 uses the magic number 60. It would be better to use the constant MAX_RETRY_DELAY_SECS to make the test more robust to changes.
Suggested change
const MAX_RETRY_DELAY_SECS: u64 = 60;
// A server sending Retry-After: 999999 should be capped to 60
let server_value: u64 = 999_999;
let capped = server_value.min(MAX_RETRY_DELAY_SECS);
assert_eq!(capped, 60);
const MAX_RETRY_DELAY_SECS: u64 = 60;
// A server sending Retry-After: 999999 should be capped to 60
let server_value: u64 = 999_999;
let capped = server_value.min(MAX_RETRY_DELAY_SECS);
assert_eq!(capped, MAX_RETRY_DELAY_SECS);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants