Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GrailsWebRequest.getBaseUrl() returns wrong result when "X-Forwarded-Proto" request header is present #14090

Open
ilPittiz opened this issue Mar 28, 2025 · 4 comments
Assignees

Comments

@ilPittiz
Copy link

Expected Behavior

No response

Actual Behaviour

WebUtils.retrieveGrailsWebRequest().getBaseUrl() does not return a consistent request base URL when:

  • X-Forwarded-Proto request header is defined
  • X-Forwarded-Port request header is not defined

Steps To Reproduce

Example:
curl -H 'X-Forwarded-Proto: https' https://my.domain.com/path

MyController.groovy

def debug() {
    println WebUtils.retrieveGrailsWebRequest().getBaseUrl()
}

Output:
https://my.domain.com:null

There's an ambiguous logical expression at

} else if (forwardedPort != null &&
("http".equals(forwardedScheme) && !"80".equals(forwardedPort)) ||
("https".equals(forwardedScheme) && !"443".equals(forwardedPort))) {
sb.append(":").append(forwardedPort);
}

where

  • forwardedScheme = "https"
  • forwardedPort = null

The if statement is in the form of A && B || C, while it should be A && (B || C), as forwardedPort is indeed null.

Environment Information

Not relevant

Example Application

No response

Version

Issue found on Grails 6.x

@jdaugherty
Copy link
Contributor

Can you please provide a sample application? There are numerous configuration settings in spring that control the proxy behavior & headers. A sample application would make sure we address this issue properly.

@jamesfredley
Copy link
Contributor

This code was introduced in 6.1.1 #13197

ilPittiz added a commit to ilPittiz/GrailsWebRequest-baseUrl that referenced this issue Apr 3, 2025
@ilPittiz
Copy link
Author

ilPittiz commented Apr 3, 2025

Sorry for the late feedback. Here's a small sample app, created via Grails Application Forge and edited to remove all overabundant dependencies: https://github.com/ilPittiz/GrailsWebRequest-baseUrl

To replicate the issue, run the app and execute

curl -H 'X-Forwarded-Proto: https' http://localhost:8080

It'll print as result

http://localhost:null

We identified this bug right after our IT team moved all microservices to Cloudfare CDN, that by default adds X-Forwarded-Proto header to all requests, while does not add X-Forwarded-Port header.

@jdaugherty
Copy link
Contributor

As a work around, you could add a filter to remove the header prior to the GrailsWebRequest creation.

I'll see about fixing this in 7.x.

@jdaugherty jdaugherty self-assigned this Apr 5, 2025
@jdaugherty jdaugherty added this to the grails:7.0.0-M4 milestone Apr 5, 2025
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

No branches or pull requests

3 participants