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

getRequestIP returns the last IP address in the X-Forwarded-For header #588

Closed
PitsPower opened this issue Dec 2, 2023 · 2 comments · Fixed by #618
Closed

getRequestIP returns the last IP address in the X-Forwarded-For header #588

PitsPower opened this issue Dec 2, 2023 · 2 comments · Fixed by #618

Comments

@PitsPower
Copy link

Environment

Node: v18.16.0
h3 1.9.0

Reproduction

Call getRequestIP(event, { xForwardedFor: true }) in an application behind a proxy server.

Describe the bug

When calling getRequestIP(event, { xForwardedFor: true }), the last IP address in the list is returned instead of the first one (the client's IP address), when I assume the first one should be.

Additional context

No response

Logs

No response

@PitsPower PitsPower changed the title xForwardedFor returns the last IP address in the X-Forwarded-For header getRequestIP returns the last IP address in the X-Forwarded-For header Dec 2, 2023
@salim-dev
Copy link

the problem is that we use the pop method to retrieve the last one in the list.

https://github.com/unjs/h3/blob/53703dc860f1ff6fe7ce71d543deff1cfa810b11/src/utils/request.ts#L209C3-L209C3

  if (opts.xForwardedFor) {
    const xForwardedFor = getRequestHeader(event, "x-forwarded-for")
      ?.split(",")
      ?.pop();
    if (xForwardedFor) {
      return xForwardedFor;
    }
  }

the solution is that we are another argument to select the position we want. example :

getRequestIP(event, {xForwardedFor: true, xForwardedForPosition: 0 })


export function getRequestIP(
  event: H3Event,
  opts: {
    /**
     * Use the X-Forwarded-For HTTP header set by proxies.
     *
     * Note: Make sure that this header can be trusted (your application running behind a CDN or reverse proxy) before enabling.
     */
    xForwardedFor?: boolean;
    xForwardedForPosition?: number;
  } = {},
): string | undefined {
  if (event.context.clientAddress) {
    return event.context.clientAddress;
  }

  if (opts.xForwardedFor) {
    const xForwardedForArray = getRequestHeader(event, "x-forwarded-for")?.split(",");   
   const xForwardedFor  = (xForwardedForPosition  &&  xForwardedForArray?.[xForwardedForPosition]) ? xForwardedForArray?.[xForwardedForPosition] :  xForwardedForArray?.pop();
    if (xForwardedFor) {
      return xForwardedFor;
    }
  }

  if (event.node.req.socket.remoteAddress) {
    return event.node.req.socket.remoteAddress;
  }
}



@pi0
Copy link
Member

pi0 commented Jan 16, 2024

Thanks for report.Issue is fixed in nightly channel and soon released.

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