Dear community,
I need your support with a security question regarding host header injection. As far as I can tell, the default behaviour of caddy is not optional, but let me explain.
My configuration
Imagine this docker-compose.yml
file:
services:
caddy:
container_name: caddy
image: caddy:2.8.4
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- /opt/caddy:/data
- ./Caddyfile:/etc/caddy/Caddyfile
and this Caddyfile
:
142.132.160.129.nip.io {
respond "awesome."
}
The “normal” requests
http is redirected just fine
curl http://142.132.160.129.nip.io -I
HTTP/1.1 308 Permanent Redirect
Connection: close
Location: https://142.132.160.129.nip.io/
Server: Caddy
Date: Mon, 14 Oct 2024 10:35:45 GMT
https is returning my content:
curl https://142.132.160.129.nip.io
awesome
Security concerns
My question is regarding host header injection. More info about it here: Skeleton Scribe: Practical HTTP Host header attacks. So let’s assume somebody is sending this request:
curl http://142.132.160.129.nip.io -I -H "Host: evil.com"
My attempts to solve that
I tried multiple things, but this is what turned out to work:
:80 {
redir https://142.132.160.129.nip.io{uri}
}
:443 {
tls internal
respond "not ok..."
}
https://142.132.160.129.nip.io {
respond "awesome"
}
This prevents Caddy to redirect to any other site.
What I also tried
I tried for example inside my https:// block the following:
https://142.132.160.129.nip.io {
@correct_host host 142.132.160.129.nip.io
handle @correct_host {
respond "aweseome"
}
respond "Wrong host" 443
}
Unfortunately, this does not solved my problem. The inbuild redirect of caddy takes place before this blocks is executed.
My questions
What do you think about my observation? I know this still requires uses to click to a false link etc, but still I would like to avoid, that the server is so easily tricked with a new host value.
Is there a simpler way to achieve this?