Skip to content

fix: correct post-increment in fetchJson redirect counter#24911

Closed
enjoykumawat wants to merge 2 commits intogoogle-gemini:mainfrom
enjoykumawat:fix/fetchjson-redirect-limit
Closed

fix: correct post-increment in fetchJson redirect counter#24911
enjoykumawat wants to merge 2 commits intogoogle-gemini:mainfrom
enjoykumawat:fix/fetchjson-redirect-limit

Conversation

@enjoykumawat
Copy link
Copy Markdown
Contributor

Problem

fetchJson in packages/cli/src/config/extensions/github_fetch.ts uses post-increment (redirectCount++) when passing the counter to the recursive call on line 34. Post-increment evaluates to the current value before incrementing, so every recursive call receives redirectCount = 0. The guard if (redirectCount >= 10) always evaluates 0 >= 10 → false, meaning the "Too many redirects" error is unreachable. A server returning redirect loops causes infinite recursion until a Node.js stack overflow crash.

Fixes #21007 (also reported as #24893)

Root cause

// Before — post-increment: recursive call always receives 0
fetchJson<T>(res.headers.location, redirectCount++)

// After — arithmetic: recursive call receives 1, 2, 3, ... 10
fetchJson<T>(res.headers.location, redirectCount + 1)

The sibling downloadFile function in github.ts already uses redirectCount + 1 — this fix brings fetchJson in line with the established pattern.

Changes

  • packages/cli/src/config/extensions/github_fetch.ts: one-character fix (redirectCount++redirectCount + 1)
  • packages/cli/src/config/extensions/github_fetch.test.ts: regression test — verifies that 11 consecutive 302 redirects result in "Too many redirects" rejection

Testing

All 9 tests pass, including the new redirect-limit test.

redirectCount++ evaluates to the current value before incrementing,
so every recursive call received redirectCount=0. The guard
(redirectCount >= 10) never triggered, allowing infinite redirect
loops that cause a stack overflow crash.

Change to redirectCount + 1 so each recursive call receives the
correctly incremented value, matching the pattern already used in
the sibling downloadFile function.

Fixes google-gemini#21007
@enjoykumawat enjoykumawat requested a review from a team as a code owner April 8, 2026 09:27
@gemini-code-assist
Copy link
Copy Markdown
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 addresses an infinite recursion vulnerability in the fetchJson utility. By fixing an incorrect increment operation, the function now properly tracks redirect counts, preventing potential stack overflow crashes when encountering redirect loops.

Highlights

  • Bug Fix: Corrected the redirect counter logic in fetchJson by replacing post-increment with arithmetic addition to ensure the recursion limit is properly enforced.
  • Regression Testing: Added a new test case to verify that the function correctly rejects requests after exceeding the maximum allowed number of redirects.
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.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, 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
Copy Markdown
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 fixes a bug in the fetchJson function where the redirect count was not correctly incremented due to the use of a post-increment operator, and adds a corresponding unit test to verify that the function rejects after 10 redirects. A security review identified a critical vulnerability where the GITHUB_TOKEN is leaked to untrusted domains during redirects; it is recommended to strip the Authorization header for cross-origin requests to prevent credential exfiltration.

return reject(new Error('No location header in redirect response'));
}
fetchJson<T>(res.headers.location, redirectCount++)
fetchJson<T>(res.headers.location, redirectCount + 1)
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 fetchJson function includes the GITHUB_TOKEN in the Authorization header for all requests. When following redirects (301/302), the function recursively calls itself with the new URL from the location header, which results in the token being sent to the new destination. If a trusted host redirects to an untrusted domain, the sensitive GitHub token will be leaked to the external party.

Remediation: Implement a check to ensure that the Authorization header is only included if the target URL (including redirect locations) belongs to a trusted domain (e.g., github.com). For cross-origin redirects, the token should be stripped. This aligns with the repository requirement to sanitize environment usage and prevent exfiltration of sensitive data.

References
  1. Sanitize the environment used for variable expansion in HTTP headers to prevent malicious extensions from exfiltrating sensitive system environment variables.

When following 301/302 redirects, the GITHUB_TOKEN was forwarded to the
redirect destination without checking the hostname. A trusted GitHub URL
redirecting to an untrusted domain would leak the token.

Pin the trusted hostname from the initial request URL and only include
the Authorization header when the current request hostname matches it.
Cross-origin redirect destinations receive no credentials.
@enjoykumawat
Copy link
Copy Markdown
Contributor Author

Addressed the security feedback: added hostname pinning so the Authorization header is only forwarded when the redirect destination has the same hostname as the original request URL. Cross-origin redirects now receive no credentials. Added a regression test that verifies this.

@enjoykumawat
Copy link
Copy Markdown
Contributor Author

Good point on the token leak. Addressed in the latest commit:

  • Pins the trusted hostname from the initial request URL
  • On each redirect, checks whether the new destination hostname matches the original
  • Only includes the Authorization header when the hostname matches; strips credentials for cross-origin redirects

Added a test covering the cross-origin redirect case to verify the token is not forwarded.

@scidomino
Copy link
Copy Markdown
Collaborator

I approved #24896 instead

@scidomino scidomino closed this Apr 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: fetchJson redirect limit broken due to post-increment — infinite redirect loop on 301/302

2 participants