Query string allowlist

1. The problem I’m having:

I’d like to allow only a predefined set of query strings, but strip any other key/values that might be appended to the request.

For example, the upstream application expects to receive one, or a combination of predefined strings:

?format=car
or
?format=car&dag-scope=all

The allowed queries are defined in this expression:

	@allowedQueries `
	!query({'format': ['car', 'raw', 'ipns-record']})
	&& !query({'format': ['car', 'raw', 'ipns-record'], 'dag-scope': ['block', 'entity', 'all']})
	`
	rewrite @allowedQueries {path}?

This is working fine (only those parameters are sent to the upstream), however using the Caddyfile below, additional queries can be appended to the request which are then sent to the upstream application:

Example: ?format=car&dag-scope=all&this=doesntbelong

In this case, I’d like to only forward the whitelisted strings and remove anything else such as &this=doesntbelong.

2. Error messages and/or full log output:

N/A

3. Caddy version:

v2.7.6-0.20240401181240-45132c5b24b4 h1:RkqsTV1P0EjpiOyNG6hO4kouGTzawDhi1/L43SnKyoM=

4. How I installed and ran Caddy:

xcaddy build master

a. System environment:

Fedora 37

b. Command:

caddy run

c. Service/unit/compose file:

N/A

d. My complete Caddy config:

{
	admin off
	auto_https off

	local_certs

	log {
		level INFO
		format json
	}
}

:8443 {
	bind 0.0.0.0

	tls internal {
		on_demand
	}

	@allowedQueries `
	!query({'format': ['car', 'raw', 'ipns-record']})
	&& !query({'format': ['car', 'raw', 'ipns-record'], 'dag-scope': ['block', 'entity', 'all']})
	`

	rewrite @allowedQueries {path}?
	reverse_proxy http://localhost:8080
}

5. Links to relevant resources:

Addendum: to better summarize, I’m looking for a way to explicitly send ONLY the query strings that are defined in the expression above to the upstream, nothing else (even if the required queries are present in the request, it should be impossible to send additional erroneous strings).

I spent the past day thinking about this, I don’t think we have a good solution for you that exists right now. You might be best served by writing a simple plugin that does it. Extending Caddy — Caddy Documentation

We’re adding a bunch of ways to rewrite the query in the next version, but I don’t think any of the operations we’re adding will do what you need Query rewrite operations · Issue #6096 · caddyserver/caddy · GitHub. What you’re trying to do is a pretty specialized case, so a plugin is likely your best option.

Do you not control your upstream app? Why can’t you filter the query in your app itself?

Thank you for looking into this. It’s an odd problem for sure. Unfortunately we don’t have any control over what the backend is capable of accepting (it’s a long story). We’ll look into writing a plugin. Cheers!

1 Like