Every public web service is continuously scanned by automated tools looking for files that should never have been published:
/.envfiles holding database passwords,/.git/directories exposing the whole source tree, forgotten/backup.sqldumps, cloud credentials in/.aws/credentials, CI tokens, editor swap files.
These probes cost the attacker nothing, they are launched by the million, and a single hit is enough to compromise an application that was otherwise perfectly maintained.Dangerous Paths watches the requests your reverse proxy is already serving, recognises those probes against a curated database of known dangerous paths, scores the source, and bans it at the firewall before it finds anything.
The engine works on the access log stream the reverse proxy produces anyway. There is no extra parsing daemon, no additional listening socket, and nothing is added to the request path — a request is examined after it has been answered, so the feature cannot slow your web sites down.
Three ideas make up the whole design:
/.env is already worth 100 points, because a hit on that file is game over. /.gitignore is worth far less on its own — but a source asking for /.gitignore, then /.gitattributes, then /.env is unmistakably enumerating, and the accumulated score crosses the threshold. The status code of the answer decides what happens, and this distinction is the heart of the feature:
| Answer | Meaning | Engine reaction |
|---|---|---|
| 404 | The file is not there | Scored. The source is probing for something that does not exist — that is reconnaissance, and it is what gets banned. |
| 2xx | The file was actually served | Reported, never banned. A dangerous file is genuinely exposed on your site. Banning the source would not close the file It stays readable by everyone else. This is an alert for you, not a sanction for the visitor. |
| 3xx | A redirect was returned | Ignored. A redirect serves nothing. Sites that redirect HTTP to HTTPS answer 301 to every cleartext probe, which would otherwise raise a permanent, meaningless alert. |
| 403, 407, 444 | The request was refused | Ignored. Another layer already blocked it. Nothing was served and nothing was discovered. |
| 5xx | The backend failed | Ignored. A backend error says nothing about whether the file exists. |
200, you are told — by the very traffic that was trying to find it. Few tools give you that./.env is a perfectly well-formed request that no WAF rule has any reason to reject..env next to the application root. Where to find it
The feature is configured per web service.
Open Web services, select your site, and look for Dangerous Paths in the Security section of the service parameters.
The first tab reports what the engine is actually doing.
It is the page to open when you want to know whether protection is real, not merely enabled.
| Field | What it tells you |
|---|---|
| Database Loaded / Rule Count | Whether the path database is in memory, and how many paths it holds. Without a loaded database, nothing can be detected. |
| Generation Date | When the database was published, and how old it is. |
| Settings Source | Database in normal operation. If it reads Cache fallback, the appliance could not read its configuration database and is running on its last known good copy — protection is still active, but a change you make may not be applied. |
| Enforcement | Blocking when at least one enabled site actually writes bans to the firewall, Alert only when every enabled site is in observation mode. This field exists so that an absence of firewall rules is never mistaken for a failure. |
| IPv4 / IPv6 Rules | OK means the firewall rules were verified as present. Missing means they were removed and will be restored automatically within a minute. Not applicable means there is nothing to install (no enabled site, or no IPv6 stack). Unknown means the appliance could not check — that is not a healthy state, and it is deliberately never displayed as one. |
| Currently Blocked Sources | How many addresses are banned right now, across all sites. |
| Served Dangerous Paths | How many times a dangerous path was actually served with a 2xx answer. Any value above zero deserves investigation: it means a file that should not be reachable was handed to a client. |
| Alert Only Events | How many sources crossed the threshold on a site running in observation mode. In other words, how many bans enforcement would have applied. |
| Score Entries | How many sources are currently being tracked. |
| Block Failures, Queue Saturated, Score Capacity Hits, Params Read Failed | Health counters. They should stay at zero. A non-zero value means bans were requested but could not be applied, or that the engine hit an internal limit Never a silent degradation. |
Detection is disabled by default and is turned on per site.
| Setting | Default | Description |
|---|---|---|
| Enable Dangerous Paths Detection | Off | Turns the engine on for this web service. Nothing is detected, scored or banned while this is off. |
| Score Threshold | 100 | The score a source must accumulate to be banned. Accepted range: 30 to 1000. Lowering it makes the engine more aggressive; raising it requires more evidence before acting. At the default of 100, a single request for a critical file such as /.env is enough. |
| Scoring Window | 1 minute | How long points survive. Requests spread over a period longer than this window never add up. Accepted range: 10 seconds to 1 hour. |
| Firewall Ban Duration | 1 hour | How long a banned source stays blocked. Accepted range: 1 minute to 7 days. |
| Ban Offenders At The Firewall | On | When on, crossing the threshold bans the source. When off, the site runs in observation mode: identical detection, identical scoring, identical alerting — but nothing is written to the firewall. |
Out-of-range values are refused, never silently adjusted.
If you enter a scoring window of 5 seconds, the appliance tells you so rather than quietly applying 10 — you always know what is running.
Turning Ban Offenders At The Firewall off is the recommended way to introduce the feature on a sensitive production site.
The engine behaves exactly as it would in blocking mode, and every threshold crossing is written to the log in the following form:
DangerousPaths: 203.0.113.42 signalé SANS bannissement (site=78 règle=/.env catégorie=env-secrets score=100) — EnableDangerousPathsFw=0
Compare it with what a real ban looks like:
DangerousPaths: 203.0.113.42 banni 3600s (site=78 règle=/.env catégorie=env-secrets score=100)
Both lines carry the source, the site, the rule that matched, its category and the accumulated score — so a week in observation mode gives you the complete list of what enforcement would have blocked, with the reason for each decision.
One point deserves attention.
The firewall is shared by every site on the appliance: a single set of banned addresses, a single chain, one common set of protected ports.
Turning this setting off stops this site from arming bans; it does not exempt it from bans armed by another site sharing the same port.
This is a deliberate design decision, not a limitation to work around — a banned scanner is hostile to every site it can reach.
Sources listed here are never scored and never banned, whatever they request.
Each entry combines a source address and a path:
*, means all — * as the path exempts the source from everything.* to cover a subtree, for example /.well-known/*.*). Ranges in CIDR notation such as 192.168.90.0/24 are not accepted: an exemption is granted to a machine you know, not to a subnet whose future occupants you do not.Typical entries: a monitoring probe that checks unusual URLs, an ACME validation agent, a partner scanner, or a contracted penetration tester for the duration of the engagement.
The sources banned at this instant, across every site, with the time each one has left.
The padlock on the right releases an address immediately.
Releasing an address removes it from the firewall, but the engine keeps its memory of that source until the ban duration has elapsed:
it will not be banned twice for the same burst. If you want a released address to be permanently exempt, add it to the whitelist.
IPv6 sources are banned by their /64 prefix, not by their exact address.
A single machine is routinely given billions of addresses inside its prefix and changes them at no cost, so banning one address would make IPv6 support purely decorative.
The last tab lets you browse the path database the engine matches against. Search by path, filter by category, or both.
Each entry shows its path, its category and its score.
This is where you check why a given source was banned, or confirm that a path you consider sensitive is covered.
Results are capped, and the page tells you when a search returned more entries than it displays — narrow the search rather than assume you have seen everything.
Bans are enforced by a dedicated firewall chain that touches nothing else on the appliance:
ipset sets, one for IPv4 (exact addresses) and one for IPv6 (/64 prefixes), with the expiry handled by the set itself.NGINX_DANGEROUS_FS chain that drops it.