Caddy: handle_errors unexpected behaviour

Created on 4 Jun 2020  路  3Comments  路  Source: caddyserver/caddy

Currently handle_errors seems to be able to cause unexpected behaviour, at least behaviour that is not immediately obvious.

As an example:

Caddyfile (using Bob & hiccup Basic Auth from docs)

root * /usr/share/caddy/
file_server
basicauth /* {
    Bob JDJhJDEwJEVCNmdaNEg2Ti5iejRMYkF3MFZhZ3VtV3E1SzBWZEZ5Q3VWc0tzOEJwZE9TaFlZdEVkZDhX
}

handle_errors {
    @404 {
        expression {http.error.status_code} == 404
    }
    rewrite @404 /404.html
    file_server
}

404.html

my 404 page

index.html

hello world

Request index.html with correct auth:

$ curl -L -k -D - https://Bob:hiccup@localhost
HTTP/2 200 
accept-ranges: bytes
content-type: text/html; charset=utf-8
etag: ..
last-modified: ...
server: Caddy
content-length: 11
date: ...

hello world

OK

Request non existing URL with correct auth:

$ curl -L -k -D - https://Bob:hiccup@localhost/abc
HTTP/2 404 
content-type: text/html; charset=utf-8
etag: ...
server: Caddy
content-length: 11
date: ...

my 404 page

OK

Request index.html with incorrect auth:

$ curl -L -k -D - https://Bob:hiccu@localhost/
HTTP/2 401 
content-type: text/html; charset=utf-8
etag: ...
server: Caddy
www-authenticate: Basic realm="restricted"
content-length: 11
date: ...

hello world

Oops - the secret content was revealed.

Request non existing URL with incorrect auth:

$ curl -L -k -D - https://Bob:hiccu@localhost/abc
HTTP/2 200 
server: Caddy
www-authenticate: Basic realm="restricted"
content-length: 0
date: ...


Oops - a 200 response was returned instead of 401.

By adding w.WriteHeader(errStatus) to caddyhttp/server.go at the end of the // well... this is awkward block, the behaviour becomes as I would anticipate. The index.html is not rendered in the case of invalid auth and a 401 status is returned not 200 in the case of both invalid auth and a non existing URL.

I would like to suggest that the response behaviour when the handle_error routes return an error is as if there were no handle_error routes defined.

Most helpful comment

This is working as expected -- you're only changing the request's URI on 404 errors, so the 401 doesn't have any rewrites done, so it just flows back into another file server handler, this time without any auth protections.

rob pike don't do that

Instead of limiting the rewrite to just 404s, consider rewriting all requests: rewrite * /{http.error.status_code}.html

All 3 comments

This is working as expected -- you're only changing the request's URI on 404 errors, so the 401 doesn't have any rewrites done, so it just flows back into another file server handler, this time without any auth protections.

rob pike don't do that

Instead of limiting the rewrite to just 404s, consider rewriting all requests: rewrite * /{http.error.status_code}.html

yes sure - I stepped through the code and understand what and why is going on.

But does it make sense to be how it is ?

Over and out

@richardjennings Yes, it is very flexible and powerful! AFAIK almost all the feature requests from v1 related to error handling are resolved with this, and it can even do things other web servers aren't capable of (without extra scripting or whatever).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ericmdantas picture ericmdantas  路  3Comments

la0wei picture la0wei  路  3Comments

billop picture billop  路  3Comments

treviser picture treviser  路  3Comments

mschneider82 picture mschneider82  路  3Comments