Replace HOST_URL by Host header
Currently, each invidious process is fixed to it's domain config value which makes it really difficult for anyone to host Invidious using multiple domains, Tor and I2P.
If someone wants to host Invidious on Tor, a dedicated Invidious instance for it needs to be made setting domain to the Tor address, and the same goes for I2P.
On some places, HOST_URL is still used and it shouldn't be changed, like for example: https://github.com/iv-org/invidious/blob/adcdb8cb92bbf61bac46102eff026593d0bc87b0/src/invidious/helpers/utils.cr#L297
If this get merged when it's finished, it shouldn't break the setup of anyone using NGINX since the invidious documentation already mentions the use of the Host header on the NGINX configuration: https://github.com/iv-org/documentation/blob/65ecfccb10f15b4b9ce95c03b0d6d6ebd88bca7a/docs/nginx.md?plain=1#L24
Consider this a WIP since it's a big change that could break a lot of things, however, most of the changes made on the first commit are already applied to my Invidious fork at https://git.nadeko.net/Fijxu/invidious for a very very long time already, multiple domains works fine and Tor works fine.
Just asking out of curiosity: This would change something from a know source to an "attacker controlled" source, right? Does this need any additional sanitizing?
Would env.response.headers["Location"] = "#{env.request.headers["Host"]}/api/v1/auth/playlists/#{playlist.id}" then be open to some kind of header injection attack via adding newlines (and therefor foreign headers) or something?
Just asking out of curiosity: This would change something from a know source to an "attacker controlled" source, right? Does this need any additional sanitizing? Would
env.response.headers["Location"] = "#{env.request.headers["Host"]}/api/v1/auth/playlists/#{playlist.id}"then be open to some kind of header injection attack via adding newlines (and therefor foreign headers) or something?
As far as I know, no. env.request.headers["Host"] is a string and imagine you do a request to Invidious with a custom Host header, if you try to set any input on it like -H "Host: �e(�����-�J���hc��u�9�����{��1���bE��XQ�", you will only get an invalid URL (an URL that is not pointing to any Invidious host for example) of the input of the Host header and the webserver will return to you 404 Not Found (or any other error related to a non valid Host).
I may be wrong, but I can't think of any way to exploit this.
Ref: https://crystal-lang.org/reference/1.15/tutorials/basics/40_strings.html#interpolation
Example:
I was more thinking of something like having a newline in there :) not just invalid binary stuff, just saw that "external controlled" data gets written directly back, just wanted to make sure
I was more thinking of something like having a newline in there :)
I see, Crystal handles it well
Does this need any additional sanitizing?
From my previous research on this subject, many implementations have a "trust 'Host' header" option for that purpose, as well as a "Trust the first N headers" to allow more than one level of proxying, and make sure that none of the attacker-controlled headers gets parsed.
Though some sanitization never hurts.
I may be wrong, but I can't think of any way to exploit this.
To override other header, the usual way is by sending Cookie: FOO=bar\nHost: evil.com.
But you can also do some XSS injections!
@Fijxu Some places like the thumbnails would require a significative rewrite, as they never see the HTTP context of the request (and worse, it ends up in the cache): https://github.com/iv-org/invidious/blob/0c07e9d27ac773d8423143c11bbcd36eaae0f8e4/src/invidious/videos.cr#L362-L374