Check http argument length

I’m planning to use Caddy as a public reverse proxy to Solr.
Until now I’ve used a configuration like this:

the most importante piece of logic i need to port from Nginx is this: I need to limit the lenght (chars) of some http arguments (ie: ?rows=5000). How could I do this with Caddy?

if ($arg_start ~ ....+) {
  return 403;
}
if ($arg_rows ~ ....+) {
  return 403;
}

Have a look at the request matchers Caddy supports by default Request matchers (Caddyfile) — Caddy Documentation

I guess you could use an inline CEL expression together with {http.request.uri.query.*}.
See the full list of CEL methods at cel-spec/langdef.md at master · google/cel-spec · GitHub

And in that expression you could then use functions like matches() for regex, or something more fun:

# `{http.request.uri.query.rows}` is a string,
# and the size() of a string describes its amount of chars
@prohibited expression size({http.request.uri.query.rows}) >= 4
# or write it as
@prohibited expression {http.request.uri.query.rows}.size() >= 4
❯ curl "https://localhost/?rows=5000"
prohibited%

❯ curl "https://localhost/?rows=999"
permitted%

or

# check if arg is not empty and convert it to an integer
@prohibited expression {http.request.uri.query.rows} != '' && int({http.request.uri.query.rows}) > 1500
❯ curl "https://localhost/?rows=1501"
prohibited%

❯ curl "https://localhost/?rows=999"
permitted%

The whole Caddyfile looks like:

localhost {
	@prohibited expression size({http.request.uri.query.rows}) >= 4
	respond @prohibited prohibited 403
	respond permitted
}

And instead of respond permitted you would use something like reverse_proxy localhost:3000 :slight_smile:

2 Likes