I was able to replicate the issue with this Caddyfile:
:2015
status 401 /secret/files
With the following folder structure:
Matt at hermes in ~/Projects/test
→ exa -lgTL 3
drwxr-xr-x - Matt staff 7 Sep 9:48 .
.rw-r--r-- 58 Matt staff 7 Sep 9:42 ├── Caddyfile
.rw-r--r-- 20 Matt staff 2 Aug 17:02 ├── index.html
drwxr-xr-x - Matt staff 7 Sep 9:42 └── secret
drwxr-xr-x - Matt staff 7 Sep 9:50 └── files
.rw-r--r-- 20 Matt staff 2 Aug 17:02 └── index.html
When requesting //secret/files or /secret//files, I get a 301 to single slashes:
Matt at hermes in ~/Projects/test
→ curl -iL localhost:2015/secret//files
HTTP/1.1 301 Moved Permanently
Location: /secret/files/
Server: Caddy
Date: Wed, 06 Sep 2017 23:51:20 GMT
Content-Length: 49
Content-Type: text/html; charset=utf-8
HTTP/1.1 401 Unauthorized
Content-Type: text/plain; charset=utf-8
Server: Caddy
X-Content-Type-Options: nosniff
Date: Wed, 06 Sep 2017 23:51:20 GMT
Content-Length: 17
401 Unauthorized
Requesting the index.html directly fails with single slashes, as expected:
Matt at hermes in ~/Projects/test
→ curl -i localhost:2015/secret/files/index.html
HTTP/1.1 401 Unauthorized
Content-Type: text/plain; charset=utf-8
Server: Caddy
X-Content-Type-Options: nosniff
Date: Wed, 06 Sep 2017 23:53:38 GMT
Content-Length: 17
401 Unauthorized
Requesting with double slash in the path matched by status bypasses that status directive entirely:
Matt at hermes in ~/Projects/test
→ curl -i localhost:2015/secret//files/index.html
HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Length: 20
Content-Type: text/html; charset=utf-8
Etag: "ou1q7xk"
Last-Modified: Wed, 02 Aug 2017 07:02:21 GMT
Server: Caddy
Date: Wed, 06 Sep 2017 23:54:15 GMT
This is /secret/files/index.html.
Not technically a bug, I suppose - since the request path clearly doesn’t match the path specified by status.
Definitely inconsistent and possibly dangerous, though, requiring ludicrous amounts of Caddyfile syntax to work around. Imagine having to do this for any set of files you care about:
status 401 //path/to/secret/files
status 401 /path//to/secret/files
status 401 /path/to//secret/files
status 401 /path/to/secret//files
status 401 //path//to/secret/files
# ...repeat until 2^n (n = count of path elements)... 11 more permutations!
An excellent candidate for a Github issue if I’ve ever seen one.