elysiajs / elysia

Ergonomic Framework for Humans
https://elysiajs.com
MIT License
10.35k stars 220 forks source link

Handling Multiple X-Forwarded-For Headers in Elysia #890

Open vanisoul opened 5 days ago

vanisoul commented 5 days ago

What version of Elysia is running?

1.1.23

What platform is your computer?

Linux 6.8.0-47-generic x86_64 x86_64

What steps can reproduce the bug?

Description: The Elysia framework's request handling for the X-Forwarded-For header is incorrectly using only the last value when multiple headers are sent. According to the HTTP specification, if multiple X-Forwarded-For headers are present, the values should be concatenated, with the addresses from all headers forming a comma-separated list.

Steps to Reproduce: Use curl to send a POST request with multiple X-Forwarded-For headers: curl -X POST -H "X-Forwarded-For: 192.168.1.101, 192.168.2.102" -H "X-Forwarded-For: 192.168.3.103" http://127.0.0.1:3000/

Code Example:

import { Elysia } from "elysia";

const app = new Elysia()
    .onRequest(({ request }) => {
        // request.headers x-forwarded-for only 192.168.3.103
    })
    .get("/", () => "Hello Elysia")
    .listen(3000);

console.log(`🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}`);

Expected Behavior:

Actual Behavior:

Additional Information: If you observe the network output using nc -l 3000, the raw HTTP request shows that both X-Forwarded-For headers are correctly passed:

POST / HTTP/1.1
Host: 127.0.0.1:3000
User-Agent: curl/8.5.0
Accept: */*
X-Forwarded-For: 192.168.1.101, 192.168.2.102
X-Forwarded-For: 192.168.3.103

What is the expected behavior?

No response

What do you see instead?

No response

Additional information

No response

Have you try removing the node_modules and bun.lockb and try again yet?

No response

sudityashrivastav commented 4 days ago

This is very interesting bug but in production most of the time only one ip address will came in the request.

vanisoul commented 4 days ago

That's true, in many cases, only one IP address may appear in production requests. only one IP address will appear in the X-Forwarded-For header. However, there could be situations where multiple proxies are involved, such as with environments using something like K3s and Traefik Ingress Controller. In those cases, it's possible that multiple X-Forwarded-For headers might be passed along, so concatenating the headers correctly would be necessary.

kravetsone commented 1 day ago

That's true, in many cases, only one IP address may appear in production requests. only one IP address will appear in the X-Forwarded-For header. However, there could be situations where multiple proxies are involved, such as with environments using something like K3s and Traefik Ingress Controller. In those cases, it's possible that multiple X-Forwarded-For headers might be passed along, so concatenating the headers correctly would be necessary.

Can u try it with just Bun.serve?

vanisoul commented 1 day ago

That's true, in many cases, only one IP address may appear in production requests. only one IP address will appear in the X-Forwarded-For header. However, there could be situations where multiple proxies are involved, such as with environments using something like K3s and Traefik Ingress Controller. In those cases, it's possible that multiple X-Forwarded-For headers might be passed along, so concatenating the headers correctly would be necessary.

Can u try it with just Bun.serve?

Thank you for the suggestion! I had actually noticed this issue with Bun.serve earlier and submitted a bug report to the Bun team before your reply. The problem seems to stem from how Bun.serve handles multiple X-Forwarded-For headers—it only keeps the last value, instead of concatenating them into a comma-separated list as per the HTTP specification.

Here’s the issue I submitted to Bun: https://github.com/oven-sh/bun/issues/14782.