Prerequisites
Fastify version
4.x.x
Plugin version
No response
Node.js version
18.x
Operating system
Linux
Operating system version (i.e. 20.04, 11.3, 10)
Any
Description
@fastify/url-data
does not use X-Forwarded-Host
header when composing request URL and instead only uses Host
header. This could cause issues for applications behind a reverse proxy, for example, NGINX by default will rewrite Host
header to the host set in the proxy_pass directive.
Fastify will set req.hostname
to the value of X-Forwarded-Host
header when trustProxy
option is set to true, and falls back to Host
header otherwise.
I would be more than happy to submit a PR.
Possible solution
In the source for fastify-url-data the host is retrieved using
const host = this.headers[':authority'] || this.headers.host
I believe we can instead use
const host = this.hostname
This would keep the implementation of hostname consistent with fastify
The implementation in fastify for hostname is as follows link
if (this.ip !== undefined && this.headers['x-forwarded-host']) {
return getLastEntryInMultiHeaderValue(this.headers['x-forwarded-host'])
}
return this.headers.host || this.headers[':authority']
Steps to Reproduce
const fastify = require('fastify')
const app = fastify({ trustProxy: true })
app.register(require('@fastify/url-data'))
app.get('/', async (req) => {
const urlData = req.urlData()
console.log('headers: ', req.headers)
console.log('url-data host:', urlData.host)
console.log('fastify hostname: ', req.hostname)
})
app.inject({
url: '/',
headers: {
Host: 'internal.example.com',
'X-Forwarded-Host': 'example.com',
},
})
Output:
headers: {
host: 'internal.example.com',
'x-forwarded-host': 'example.com',
'user-agent': 'lightMyRequest'
}
url-data host: internal.example.com
fastify hostname: example.com
Expected Behavior
Behaviour for setting hostname should be consistent with fastify server.