Skip to content

Conversation

@jnschaeffer
Copy link
Contributor

What kind of change does this PR introduce?

This PR updates performRateLimiting to treat the rate limit header value as a comma-separated list and enforce rate limiting based on the first value in that list.

What is the current behavior?

Certain HTTP headers, such as X-Forwarded-For and other headers that are combined according to RFC 7230, can be represented as a comma-separated list of values. Intermediate proxies may add their own values to these headers, modifying the resulting value. For example, an end user with a single IP address proxied through a fleet of load balancers using the X-Forwarded-For header may be associated with multiple X-Forwarded-For header values, e.g., 2.2.2.2,100.100.100.100 and 2.2.2.2,300.300.300.300. The current implementation of performRateLimiting treats each of these as separate rate limiting keys.

What is the new behavior?

This PR splits the rate limit header by commas and takes the first value (with whitespace removed) to use as the rate limiting key.

Note that this logic is superficially similar to the utilities.GetIPAddress function with two key differences. In performRateLimiting, there is no set format for a given rate limiting key, nor is there a fallback value after the first value in the list that the API should use.

This commit changes the conditional logic in performRateLimiting to
prefer returning early rather than nesting if/else statements.

This is largely preparation for changing the behavior of
performRateLimiting to accept comma-separated lists of header values,
which will incur some additional conditional logic.
This commit updates performRateLimiting to treat the rate limit header
value as a comma-separated list and enforce rate limiting based on the
first value in that list.

Certain HTTP headers, such as X-Forwarded-For and other headers that
are combined according to RFC 7230, can be represented as a
comma-separated list of values. Intermediate proxies may add their own
values to these headers, modifying the resulting value. For example,
an end user with a single IP address proxied through a fleet of load
balancers using the X-Forwarded-For header may be associated with
multiple X-Forwarded-For header values, e.g.,
"2.2.2.2,100.100.100.100" and "2.2.2.2,300.300.300.300". The current
implementation of performRateLimiting treats each of these as separate
rate limiting keys.

To address this issue, this commit splits the rate limit header by
commas and takes the first value (with whitespace removed) to use as
the rate limiting key.

Note that this logic is superficially similar to the
utilities.GetIPAddress function with two key differences. In
performRateLimiting, there is no set format for a given rate limiting
key, nor is there a fallback value after the first value in the list
that the API should use.
@jnschaeffer jnschaeffer requested a review from a team as a code owner December 5, 2025 18:10
@coveralls
Copy link

coveralls commented Dec 5, 2025

Pull Request Test Coverage Report for Build 20066956799

Details

  • 28 of 30 (93.33%) changed or added relevant lines in 1 file are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.02%) to 68.471%

Changes Missing Coverage Covered Lines Changed/Added Lines %
internal/api/middleware.go 28 30 93.33%
Totals Coverage Status
Change from base Build 20062718781: 0.02%
Covered Lines: 14670
Relevant Lines: 21425

💛 - Coveralls

Copy link
Contributor

@fadymak fadymak left a comment

Choose a reason for hiding this comment

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

Nice work 👏 Left a couple of small comments/questions whenever you have a moment!

This commit updates performRateLimiting to emit a warning for headers
that start with a comma rather than return an error.

It is possible under some circumstances that Auth servers could
receive a rate limit header value of the form ", foo". Rather than
break functionality for servers using this, it is safer to instead
emit a warning and then change this to be an error in a future
release.
@jnschaeffer jnschaeffer enabled auto-merge (squash) December 9, 2025 13:49
@jnschaeffer jnschaeffer merged commit 5f2e279 into master Dec 9, 2025
6 checks passed
@jnschaeffer jnschaeffer deleted the feat/comma-separated-header-keys branch December 9, 2025 15:50
hf added a commit that referenced this pull request Jan 12, 2026
cemalkilic pushed a commit that referenced this pull request Jan 12, 2026
Resets the main branch (`master`) to have the same changeset as 2.184.0
but under 2.185.0.

Original release please notes:


### Features

* Add Sb-Forwarded-For header and IP-based rate limiting
([#2295](#2295))
([e8f679b](e8f679b))
* allow amr claim to be array of strings or objects
([#2274](#2274))
([607da43](607da43))
* Treat rate limit header value as comma-separated list
([#2282](#2282))
([5f2e279](5f2e279))


### Bug Fixes

* check each type independently
([#2290](#2290))
([d9de0af](d9de0af))
* fix the wrong error return value
([#1950](#1950))
([e2dfb5d](e2dfb5d))
* **indexworker:** remove pg_trgm extension
([#2301](#2301))
([c553b10](c553b10))
* **oauth-server:** allow custom URI schemes in client redirect URIs
([#2298](#2298))
([ea72f57](ea72f57))
* tighten email validation rules
([#2304](#2304))
([33bb372](33bb372))

---------

Co-authored-by: depthfirst-app[bot] <184448029+depthfirst-app[bot]@users.noreply.github.com>
cemalkilic pushed a commit that referenced this pull request Jan 12, 2026
🤖 I have created a release *beep* *boop*
---


##
[2.185.0](v2.184.0...v2.185.0)
(2026-01-12)


### Features

* Add Sb-Forwarded-For header and IP-based rate limiting
([#2295](#2295))
([e8f679b](e8f679b))
* allow amr claim to be array of strings or objects
([#2274](#2274))
([607da43](607da43))
* reset main branch to 2.185.0
([#2325](#2325))
([b9d0500](b9d0500))
* Treat rate limit header value as comma-separated list
([#2282](#2282))
([5f2e279](5f2e279))


### Bug Fixes

* additional provider and issuer checks
([#2326](#2326))
([cb79a74](cb79a74))
* check each type independently
([#2290](#2290))
([d9de0af](d9de0af))
* fix the wrong error return value
([#1950](#1950))
([e2dfb5d](e2dfb5d))
* **indexworker:** remove pg_trgm extension
([#2301](#2301))
([c553b10](c553b10))
* **oauth-server:** allow custom URI schemes in client redirect URIs
([#2298](#2298))
([ea72f57](ea72f57))
* tighten email validation rules
([#2304](#2304))
([33bb372](33bb372))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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.

4 participants