Prevent Host Header Injection

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"

image

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?

How is that a vulnerability? Browser links don’t allow you to override the Host header.

This doesn’t do anything because the site address itself is a host matcher under the hood, so it would only run those routes if they already matched anyway. Your matcher is tautological.

This also doesn’t work because the HTTP->HTTPS redirect route is inserted ahead of any catch-all :80 or http:// route.

If you want to disable HTTP->HTTPS redirects, you can do so by set the auto_https disable_redirects global option.

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.