Skip to main content
A shield stops one known vulnerability from being exploited, for an app you can’t upgrade yet. It recognises the request (a path, and where it takes one, a parameter or header shape) and answers it with a 403 page, before your servers see it. Upgrading is still the fix. Shields are off by default, a DNZ Proxy runs them, and they work whether the route’s web application firewall is on or off.

Turn one on

1

Open the route

On the proxy’s page, open the route in front of the app (Routes → the route).
2

Pick its shields

Under Shields for apps that can’t be upgraded, tick those for what the app runs. Each says its CVE, the product, what it stops and what it costs.
3

Save

Every node has it within a second.
Or from the terminal:
In the route’s YAML it is shields: [cve-2022-26134], and route history shows and restores it.

The shields

php2shell is a preset of the upload limits, since it looks at an upload’s fields as the body streams in; its flag stays --php2shell. The others look at the path, the query and the headers, never at a request’s body: a vulnerability reached only through a body isn’t covered.

What they stopped

A request a shield stopped shows on the WAF page like a rule of the WAF, under the attack type Known vulnerabilities, each event with its CVE. It counts toward bans and the attack alerts too. Shields on that page lists them all, with the release that added each one, the routes that have it on and the requests it stopped. Below that, Worth a look names routes that seem to run a shield’s product, going by their hostnames, upstream and server ports (wordpress in a hostname, port 8090 for Confluence). DNZ doesn’t ask the app, so check before you rely on it: a shield does nothing for an app without the vulnerability. The WAF’s exceptions don’t reach a shield. When one stops something real, Not an attack… on its event turns it off for the routes of that hostname, and route history can undo that.

What they cost

Off, nothing: a route without a shield runs nothing more. On, a request that matches none costs one pass over the path, and over what the picked shields look at without a path of their own: the query, or every header for Shellshock and Log4Shell. Each shield’s line in the route dialog says which. Measured on one CPU with a browser-like request (11 query parameters, 8 cookies, a browser’s user agent): a shield tied to a path, under 1 µs; Log4Shell’s, about 5 µs (5% fewer requests a second at the most a node handles); all twelve on one route, about 9 µs (10% fewer), and about 3 µs on a plain GET /. Details in Proxy benchmarks.

How they update

The definitions come from DNZ, only those a proxy’s routes use, and each node compiles them. So new shields and corrected signatures reach your nodes with DNZ’s own release, without updating the nodes. DNZ doesn’t fetch new shields between releases. A node older than DNZ 2.5 can’t run them: its routes go on without them, and the WAF page names it until it is updated.

Traefik and Caddy

Shields run on DNZ Proxy only. A route that a Traefik or Caddy also serves has them on the DNZ Proxy alone, so visitors reaching it through the others aren’t shielded: the route dialog, the API, batch edit and the CLI all say so. A proxy YAML naming shields for a Traefik or Caddy is refused.