1. The problem I’m having:
Hello!
Is there a way to make Caddy respond with an error message on detecting unsupported query parameters (instead of just logging it)?
Details:
I’ve beein using Caddy for some time to serve a tiny http (no s) web site, delivering static file content only. No issues at all and I like the tiny config that allows this and the neat look of the directory listing.
My company has now changed the security scanning policy and the latest tenable.sc scan reports a critical issue “A CGI application hosted on the remote web server is potentially prone to SQL injection attack.” This is Nessus plugin 43160, “CGI Generic SQL Injection (blind, time based)” with instructions to “Modify the affected CGI scripts so that they properly escape arguments.”.
Clearly this is a false positive - neither does this Caddy instance have a database connection nor does it (afaik) understand CGI in the first place…
This specific scan simply appends “/?sort=namedirfirst&order=desc’;SELECT%20pg_sleep(21);–” to the base URL. Caddy (as per log entry) seems to sanitize/strip these parameters and delivers the directory listing as usual. This in turn is wrongly interpreted by the scanning plugin as a valid response to its specific injected SQL statement.
I’ve already asked our security team to not flag this as a crittical error for the specific web server but I doubt they’ll go along with that. So:
Is there a way to make Caddy respond with an error message on detecting unsupported query parameters (instead of just logging it)?
Or, possibly just to respond with an error on this exact param string?
I’ve found nothing in the documentation but I might be using the wrong terms to search - “question mark” or “query” parameters obviously are far too generic…
Any help or hints appreciated!
Also on any mistakes I might have made in my config…
Thanks!
Regards,
jbon
2. Error messages and/or full log output:
process log:
2023-03-23T05:02:17.760+0100 e[35mDEBUGe[0m http.handlers.file_server sanitized path join {"site_root": "D:\\Caddy-ContentDir", "request_path": "/", "result": "D:\\Caddy-ContentDir"}
2023-03-23T05:02:17.760+0100 e[35mDEBUGe[0m http.handlers.file_server no index file in directory {"path": "D:\\Caddy-ContentDir", "index_filenames": ["index.html", "index.txt"]}
2023-03-23T05:02:17.761+0100 e[35mDEBUGe[0m http.handlers.file_server browse enabled; listing directory contents {"path": "D:\\Caddy-ContentDir", "root": "D:\\Caddy-ContentDir"}
2023-03-23T05:02:17.766+0100 e[35mDEBUGe[0m http.stdlib http: URL query contains semicolon, which is no longer a supported separator; parts of the query may be stripped when parsed; see golang.org/issue/25192
2023-03-23T05:02:17.955+0100 e[35mDEBUGe[0m http.handlers.file_server sanitized path join {"site_root": "D:\\Caddy-ContentDir", "request_path": "/favicon.ico", "result": "D:\\Caddy-ContentDir\\favicon.ico"}
2023-03-23T05:02:17.955+0100 e[35mDEBUGe[0m http.handlers.file_server opening file {"filename": "D:\\Caddy-ContentDir\\favicon.ico"}
access.log
2023-03-23T05:02:17.766+0100 e[34mINFOe[0m http.log.access.log0 handled request {"request": {"remote_ip": "147.161.231.90", "remote_port": "16189", "proto": "HTTP/1.1", "method": "GET", "host": "mail.enmarket.de", "uri": "/?sort=namedirfirst&order=desc%27;SELECT%20pg_sleep(21);--Synopsis:", "headers": {"Accept-Language": ["en-US,en;q=0.5"], "Accept-Encoding": ["gzip, deflate"], "Dnt": ["1"], "Connection": ["keep-alive"], "Cookie": [], "Upgrade-Insecure-Requests": ["1"], "Accept": ["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,*/*;q=0.8"], "User-Agent": ["Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/111.0"], "X-Forwarded-For": ["149.224.53.152"]}}, "user_id": "", "duration": 0.0069085, "size": 5566, "status": 200, "resp_headers": {"Server": ["Caddy"], "Set-Cookie": [], "Content-Type": ["text/html; charset=utf-8"], "Content-Encoding": ["gzip"], "Vary": ["Accept-Encoding"]}}
2023-03-23T05:02:17.960+0100 e[34mINFOe[0m http.log.access.log0 handled request {"request": {"remote_ip": "147.161.231.90", "remote_port": "16189", "proto": "HTTP/1.1", "method": "GET", "host": "mail.enmarket.de", "uri": "/favicon.ico", "headers": {"Accept-Language": ["en-US,en;q=0.5"], "Dnt": ["1"], "Referer": ["http://mail.enmarket.de/?sort=namedirfirst&order=desc%27;SELECT%20pg_sleep(21);--Synopsis:"], "Cookie": [], "X-Forwarded-For": ["149.224.53.152"], "User-Agent": ["Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/111.0"], "Accept": ["image/avif,*/*"], "Accept-Encoding": ["gzip, deflate"], "Connection": ["keep-alive"]}}, "user_id": "", "duration": 0.005148, "size": 59058, "status": 200, "resp_headers": {"Server": ["Caddy"], "Etag": ["\"rbdvm319ki\""], "Content-Type": ["image/x-icon"], "Last-Modified": ["Thu, 05 May 2022 00:20:27 GMT"], "Accept-Ranges": ["bytes"], "Content-Length": ["59058"]}}
3. Caddy version:
v2.6.4 h1:2hwYqiRwk1tf3VruhMpLcYTg+11fCdr8S3jhNAdnPy8=
4. How I installed and ran Caddy:
Windows Service Wrapper executing “D:\Caddy\Caddy.exe run --config D:\Caddy\Caddyfile”
a. System environment:
Windows Server 2019
b. Command:
D:\Caddy\Caddy.exe run --config D:\Caddy\Caddyfile
c. Service/unit/compose file:
n.a.
d. My complete Caddy config:
{
admin off
auto_https off
grace_period 10s
log {
output file "D:\Caddy-Logfiles\caddy-process.log" {
roll_uncompressed
roll_local_time
}
format console {
time_format iso8601
}
level debug
}
}
:80 {
encode zstd gzip
root * "D:\Caddy-ContentDir"
file_server browse
log {
output file "D:\Caddy-Logfiles\caddy-access.log" {
roll_uncompressed
roll_local_time
}
format console {
time_format iso8601
}
level debug
}
handle_errors {
respond "{err.status_code} {err.status_text}"
}
}