Skip to content

feat(tower): Capture client IP addresses - #1274

Closed
Guflly wants to merge 2 commits into
getsentry:masterfrom
Guflly:agent/tower-user-ip
Closed

feat(tower): Capture client IP addresses#1274
Guflly wants to merge 2 commits into
getsentry:masterfrom
Guflly:agent/tower-user-ip

Conversation

@Guflly

@Guflly Guflly commented Jul 27, 2026

Copy link
Copy Markdown

What changed

Capture REMOTE_ADDR from the first X-Forwarded-For value, X-Real-IP, or the request socket extension when PII collection is enabled. Leave the address out when PII collection is disabled.

Tests

  • cargo test -p sentry-tower --all-features --locked
  • cargo +1.88.0 test -p sentry-tower --all-features --locked
  • cargo test --workspace --all-features --all-targets --locked
  • cargo clippy --all-features --workspace --tests --examples --locked -- -D clippy::all

Closes #769

Populate REMOTE_ADDR from X-Forwarded-For, X-Real-IP, or request socket extensions when PII collection is enabled. Keep the address out of captured requests when PII is disabled.

Closes getsentry#769
@sdk-maintainer-bot

Copy link
Copy Markdown

👋 Thanks for sending this our way! Before a maintainer reviews the code, we ask community contributors to align with us on the approach first — it keeps your time pointed at changes we can land.

The easiest way is to open or find a GitHub issue and discuss the approach with a maintainer there, then link that issue from this PR. If the issue is already assigned to someone else, please check in with them (or with us) before continuing — otherwise two people may end up working on the same task.

See our contributing guidelines for the full picture.

@Guflly
Guflly marked this pull request as ready for review July 27, 2026 18:24
@Guflly
Guflly requested a review from a team as a code owner July 27, 2026 18:24
Comment thread sentry-tower/src/http.rs
Comment on lines +245 to +255
.and_then(|value| value.split(',').next())
.map(str::trim)
.filter(|value| !value.is_empty())
.or_else(|| {
request
.headers()
.get("x-real-ip")
.and_then(|value| value.to_str().ok())
.map(str::trim)
.filter(|value| !value.is_empty())
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: The remote_addr_from_request function extracts an IP from the x-forwarded-for header without validating if the value is a syntactically correct IP address, potentially capturing and sending invalid data.
Severity: MEDIUM

Suggested Fix

Update the remote_addr_from_request function to validate that the extracted string is a valid IPv4 or IPv6 address before returning it. This can be achieved by parsing the string using a standard library function like std::net::IpAddr::from_str. This will ensure only valid IP addresses are processed.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: sentry-tower/src/http.rs#L243-L255

Potential issue: The `remote_addr_from_request` function extracts a potential IP address
from the `x-forwarded-for` header. It processes the header value but does not validate
if the resulting string is a syntactically correct IP address. The only check performed
is to ensure the string is not empty after trimming. This allows malformed values, such
as `not-an-ip`, or even malicious content to be captured and sent to Sentry as the
`REMOTE_ADDR`. While the Sentry backend may perform its own validation, this behavior
allows invalid data from an untrusted source to be processed and transmitted over the
network.

Did we get this right? 👍 / 👎 to inform future reviews.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5f80b05. Configure here.

Comment thread sentry-tower/src/http.rs
.extensions()
.get::<IpAddr>()
.map(ToString::to_string)
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Axum peer IP lookup fails

Medium Severity

The socket fallback looks up bare SocketAddr and IpAddr in request extensions, but axum stores the peer address as ConnectInfo&lt;SocketAddr&gt;. With the documented axum setup—and especially axum::serve, which provides that extension by default—the fallback never finds a client IP when proxy headers are absent, so REMOTE_ADDR is left unset.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5f80b05. Configure here.

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.

Capture user IP in tower-http integration

2 participants