Skip to content

fix: respect X-Forwarded-Prefix in RequestURL#4555

Open
wyh0626 wants to merge 1 commit intoory:masterfrom
wyh0626:fix/requesturl-forwarded-prefix
Open

fix: respect X-Forwarded-Prefix in RequestURL#4555
wyh0626 wants to merge 1 commit intoory:masterfrom
wyh0626:fix/requesturl-forwarded-prefix

Conversation

@wyh0626
Copy link
Copy Markdown

@wyh0626 wyh0626 commented Apr 4, 2026

Kratos rebuilds the public request URL from forwarded headers such as
X-Forwarded-Host and X-Forwarded-Proto, but it currently ignores
X-Forwarded-Prefix.

When Kratos runs behind a reverse proxy that strips a path prefix before
forwarding the request, the stored request_url loses that external prefix.

This PR updates x.RequestURL() to preserve X-Forwarded-Prefix and avoid
adding the prefix twice when the incoming path already contains it.

Related issue(s)

Fixes #4548

Checklist

  • I have read the contributing guidelines.
  • I have referenced an issue containing the design document if my change
    introduces a new feature.
  • I am following the
    contributing code guidelines.
  • I have read the security policy.
  • I confirm that this pull request does not address a security
    vulnerability. If this pull request addresses a security vulnerability, I
    confirm that I got the approval (please contact
    security@ory.com) from the maintainers to push
    the changes.
  • I have added tests that prove my fix is effective or that my feature
    works.
  • I have added or changed the documentation.

Further Comments

Added regression coverage for:

  • preserving X-Forwarded-Prefix
  • avoiding double-prefixing when the request path already includes the prefix

Tested with:

  • go test ./x -run TestRequestURL

I used AI assistance while drafting and implementing this change, then reviewed
the final diff and validated the behavior manually before opening the PR.

@wyh0626 wyh0626 requested review from a team and aeneasr as code owners April 4, 2026 09:30
return path
case path == "":
return prefix
case strings.HasSuffix(prefix, "/") && strings.HasPrefix(path, "/"):

Check warning

Code scanning / CodeQL

Bad redirect check Medium

This is a check that
this value
, which flows into a
redirect
, has a leading slash, but not that it does not have '/' or '' in its second position.
This is a check that
this value
, which flows into a
redirect
, has a leading slash, but not that it does not have '/' or '' in its second position.
This is a check that
this value
, which flows into a
redirect
, has a leading slash, but not that it does not have '/' or '' in its second position.
This is a check that
this value
, which flows into a
redirect
, has a leading slash, but not that it does not have '/' or '' in its second position.
This is a check that
this value
, which flows into a
redirect
, has a leading slash, but not that it does not have '/' or '' in its second position.
This is a check that
this value
, which flows into a
redirect
, has a leading slash, but not that it does not have '/' or '' in its second position.
This is a check that
this value
, which flows into a
redirect
, has a leading slash, but not that it does not have '/' or '' in its second position.
This is a check that
this value
, which flows into a
redirect
, has a leading slash, but not that it does not have '/' or '' in its second position.
This is a check that
this value
, which flows into a
redirect
, has a leading slash, but not that it does not have '/' or '' in its second position.
return prefix
case strings.HasSuffix(prefix, "/") && strings.HasPrefix(path, "/"):
return prefix + strings.TrimPrefix(path, "/")
case !strings.HasSuffix(prefix, "/") && !strings.HasPrefix(path, "/"):

Check warning

Code scanning / CodeQL

Bad redirect check Medium

This is a check that
this value
, which flows into a
redirect
, has a leading slash, but not that it does not have '/' or '' in its second position.
This is a check that
this value
, which flows into a
redirect
, has a leading slash, but not that it does not have '/' or '' in its second position.
This is a check that
this value
, which flows into a
redirect
, has a leading slash, but not that it does not have '/' or '' in its second position.
This is a check that
this value
, which flows into a
redirect
, has a leading slash, but not that it does not have '/' or '' in its second position.
This is a check that
this value
, which flows into a
redirect
, has a leading slash, but not that it does not have '/' or '' in its second position.
This is a check that
this value
, which flows into a
redirect
, has a leading slash, but not that it does not have '/' or '' in its second position.
This is a check that
this value
, which flows into a
redirect
, has a leading slash, but not that it does not have '/' or '' in its second position.
This is a check that
this value
, which flows into a
redirect
, has a leading slash, but not that it does not have '/' or '' in its second position.
This is a check that
this value
, which flows into a
redirect
, has a leading slash, but not that it does not have '/' or '' in its second position.
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.

RequestURL returns incorrect URL behind reverse proxy with stripped path prefixes

2 participants