1

Currently i'm using NodeJS & Express and obtaining the hostname from req.hostname, e.g. example.com

However, when the client call the API (e.g. http://example.com/hello), if the client change the host value from the http header (e.g. change to bar.com), the result obtain from req.hostname (where the example.com hosted) will return bar.com instead of example.com.

Anyone know how to get the real origin hostname from nodejs?

Edit: @Marc suggest to check against local env variable

However, the application is shared among multiple domains, it only helps when the application is using by 1 domain.

Jerry
  • 1,455
  • 1
  • 18
  • 39
  • Using req.headers.origin doesn't show up on localhost but it does show up on the real server with the domain name – Ali Azmoodeh Mar 22 '23 at 11:12
  • @AliAzmoodeh Thats bad, because headers can be faked. Dont trust the client. In my opinion if thats a problem, set a env variable and check the host header against the setted env. – Marc Mar 22 '23 at 11:16
  • @Marc thanks for the suggestion but my application shared among multiple domains, i still can't differentiate the real hostname accurately. – Jerry Mar 28 '23 at 10:27
  • @Jerry Specify multiple domains in the env var, and split them via `,` or what ever, with [`.split()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split?retiredLocale=de). – Marc Mar 28 '23 at 11:09
  • @Marc I still can't check whether domain A spoofing domain B although both domain are whitelisted. E.g. `foo.com` & `bar.com` both is in the env variable, we can tell when the client is spoofing `foo.com` as `baz.com`, but we can't tell when `foo.com` spoof as `bar.com` – Jerry Mar 29 '23 at 08:21
  • Another option could be a nginx in front of your node app. Then a spoofed request wouldnt be handeld by nginx. But why cant you detect when "when `foo.com` spoof as `bar.com`, just do a `process.env.DOMAINS.split(",").include(req.hostname)`. I dont get it tbh. Lets discuss here: https://chat.stackoverflow.com/rooms/252845/75811245 – Marc Mar 29 '23 at 09:04
  • `if the client change the host value` - is the client an app? If so it doesn't have a host value thus spoofing is a valid use to convince your server to return some data for an app. – slebetman Apr 04 '23 at 06:53

2 Answers2

0

As noted by M Surya, you should be getting a header added by your reverse proxy noting the original host. The reverse proxy should also be stripping out any "X-Real-IP" and "X-Forwarded-For" headers that come externally.

You should know and inherently trust your Reverse Proxy, presumably it's also doing your SSL offloading for you. You can designate it's IP address to be trusted by your express app and allow express to do the heavy lifting with the trust proxy functionality.

Documentation here: https://expressjs.com/en/guide/behind-proxies.html

leitning
  • 1,081
  • 1
  • 6
  • 10
0

I hope this answer finds you well. M Surya answer is correct and pretty much what most of the user's would want. However Yes, as mentioned "headers can be faked".

One way you can follow is, use a reverse proxy like Nginx to set a custom header with the real origin hostname and then read that header in your Node.js application. More About it Here.

http {
    ...
    # Show server host name as header
    add_header X-Backend-Server $hostname;
}

This will add a custom header named X-Backend-Server to all responses sent by Nginx, containing the real origin hostname as its value.

Ayush Naik
  • 111
  • 2
  • 14