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

ExtractIPFromRealIPHeader returns RemoteAddr instead of x-real-ip #1834

Closed
georgekarrv opened this issue Apr 2, 2021 · 2 comments · Fixed by #2007
Closed

ExtractIPFromRealIPHeader returns RemoteAddr instead of x-real-ip #1834

georgekarrv opened this issue Apr 2, 2021 · 2 comments · Fixed by #2007

Comments

@georgekarrv
Copy link

Issue Description

ExtractIPFromRealIPHeader does not return what was found in x-real-ip

echo/ip.go

Line 98 in a97052e

func ExtractIPFromRealIPHeader(options ...TrustOption) IPExtractor {

func ExtractIPFromRealIPHeader(options ...TrustOption) IPExtractor {
	checker := newIPChecker(options)
	return func(req *http.Request) string {
		directIP := ExtractIPDirect()(req)
		realIP := req.Header.Get(HeaderXRealIP)
		if realIP != "" {
			if ip := net.ParseIP(directIP); ip != nil && checker.trust(ip) {
				return realIP
			}
		}
		return directIP
	}
}

if realIP != "" should be if realIP == ""
because ultimately the logic that exists now is when you have real and direct ip it will return direct and not real

Checklist

  • [ x] Dependencies installed
  • [ x] No typos
  • [ x] Searched existing issues and docs

Expected behaviour

when x-real-ip is present the IPExtractor should return that ip instead of the directIP from RemoteAddr

Actual behaviour

ExtractIPFromRealIPHeader returns RemoteAddr if both RemoteAddr and x-real-ip exist

Steps to reproduce

Working code to debug

package main

func main() {
}

Version/commit

@hemachandarv
Copy link
Contributor

@georgekarrv Is this still valid? Can I take this issue up?

@yeyisan
Copy link
Contributor

yeyisan commented Oct 10, 2021

Hi @georgekarrv ,
In this case, directIP does not need to be parsed and trusted. Because directIP is always in a valid ip format. But realIP is a plain text value that taken from X-Real-IP header. So realIP needs parsing and trust checks instead of directIP.

The code block below will fix this erroneous situation.

// ExtractIPFromRealIPHeader extracts IP address using x-real-ip header.
// Use this if you put proxy which uses this header.
func ExtractIPFromRealIPHeader(options ...TrustOption) IPExtractor {
	checker := newIPChecker(options)
	return func(req *http.Request) string {
		directIP := ExtractIPDirect()(req)
		realIP := req.Header.Get(HeaderXRealIP)
		if realIP != "" {
			if ip := net.ParseIP(realIP); ip != nil && checker.trust(ip) {
				return realIP
			}
		}
		return directIP
	}
}

ExtractIPFromRealIPHeader returns realIP when realIP is a valid and trusted ip otherwise returns directIP.

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 a pull request may close this issue.

3 participants