# Web Application Firewall

> Rule families, blocking modes, the attack radar and the event log — the layer that inspects every request before it reaches a site.

Source: https://www.corepanel.net/docs/security/waf/
Last updated: 2026-08-12
Part of the CorePanel documentation — https://www.corepanel.net/docs

---

CorePanel includes a web application firewall that inspects every HTTP request before it
reaches a site. Attacks are stopped at the web server, so nothing reaches PHP, the
database or a vulnerable plugin.

The engine is **pxShield**, and the panel's **WAF** section is where you see what it is
catching and decide how strict it should be.

## Rule families

Rules are grouped into families. Three of them are simply what the firewall *is* — they run
on every edition, always blocking, and cannot be turned off:

| Family | Covers | State |
|---|---|---|
| **BASE** | Protocol integrity and catastrophic attack classes: null bytes, path traversal, CRLF injection, `.sql` file probing, dangerous uploads, `.env` and VCS exposure | Always blocking |
| **SQLI** | SQL and MS-SQL injection in GET and POST | Always blocking |
| **XSS** | Cross-site scripting in GET, POST, User-Agent and headers | Always blocking |

The fourth is opt-in:

| Family | Covers | State |
|---|---|---|
| **WPE** | WordPress Extended: login brute force, XML-RPC amplification, user enumeration, config/backup exposure, traversal in arguments, malicious uploads, comment spam | Off / Detect / Block, your choice |

WPE is opt-in for a technical reason, not a commercial one: its rules touch XML-RPC, author
enumeration and comment flows that a legitimate plugin or a mobile app may rely on. Turning
it on is a decision about your sites, so the panel asks instead of assuming.

### Modes

Only WPE has a mode. The three are:

| Mode | Behaviour |
|---|---|
| **Block** | Matching requests are refused |
| **Detect** | Matches are logged, the request goes through |
| **Off** | The family is not evaluated at all |

*Detect* is a run-in mode: enable it on a live server, watch the event log for a few days,
confirm nothing legitimate is matching, then switch to *block*. It is not a lesser tier.

> **The WAF is complete in every edition, including the free one**
>
> There is no "detection-only" plan. Personal blocks SQL injection, cross-site scripting,
> path traversal and everything else exactly as Pro and Business do, and can run WordPress
> Extended too. What the paid editions add on the WAF side is **per-domain granularity** —
> tuning one site without touching the rest — plus the Business-only network layer (custom
> rules, Geo blocking, DDoS L7).
>
> A firewall that watches an attack go through is not a firewall, and a free edition that
> merely reports what it could have stopped protects nobody.
Manage the WPE package under **WAF → Overview → Protection packages**. The setting is
server-wide and applies to every site.

### Upgrading a server installed before this change

Servers set up before 6 August 2026 ran an older model, where SQLI and XSS logged instead of
blocking on the free edition. Nothing has to be clicked: on the first restart after the
upgrade, CorePanel raises both families to *block* and leaves your WordPress Extended choice
as it was.

If a site depended on that gap — a form posting something a SQL rule reads as an injection,
say — it will start being refused at that point. The event log names the rule and the URL,
and the fix is an [exception](https://www.corepanel.net/docs/security/waf-tuning), not a downgrade.

## Per-rule control

**Rules** lists every rule in the catalog with its ID, its family, its engine default and
whether it is currently on. Most rules can be toggled individually — that is how you
handle a rule that misfires on one application without disabling a whole family.

Some rules ship **off by default** and are opt-in, because they trade a higher false
positive rate for extra coverage. Examples: `XSS-001`/`XSS-002` (XSS in GET/POST),
`WPE-003` (wp-login POST without a Referer), `WPE-021` (exposed database dumps),
`WPE-023` (installer lockout).

> **The protocol-integrity floor cannot be turned off**
>
> `STD-004` through `STD-008` — null bytes, path traversal and the CRLF injection rules —
> are fixed. The panel refuses to write an override for them, at any level. If one of these
> is firing on legitimate traffic, that traffic is malformed and the fix belongs in the
> application.
In **Pro and above**, rules can also be tuned **per domain**: a rule turned off for one
site while every other site keeps it. Personal edits the server-wide layer, which every
domain inherits — the same rules applied to every site at once.

> **The limit is enforced by the server, not by the panel**
>
> Per-domain rules, exceptions and trusted IPs are refused by CorePanel itself, so the API
> returns the same refusal the panel shows — never a silent downgrade, never a quiet accept.
Per-domain overrides are **not** removed when a server drops back to Personal: an
override usually exists because a rule was breaking a working site, and deleting it
during a billing event would break that site again. They stay in place, and you can
still delete them on any edition — what Personal cannot do is add a new one.

## The attack radar

The **Overview** is a live picture of what is hitting the server:

- attacks over time, so a spike is visible at a glance;
- the top attacking IP addresses;
- the most-triggered rules;
- a breakdown by domain, so you can see which site is the target.

This is also the fastest way to size a problem: one IP hammering `wp-login` is a
different situation from a distributed scan across every domain you host.

## The event log

**Event log** is the detailed record: timestamp, client IP and country, domain, request,
rule that matched, and whether it was blocked or only detected. Opening an event shows
the full request context that triggered it.

Two things it is for:

1. **Confirming an attack was stopped** — the answer to "were we affected?".
2. **Diagnosing a false positive** — when a customer says "the panel of my site says
   403", the event log is where you see which rule fired and on which URL, which is
   exactly what you need to write an [exception](https://www.corepanel.net/docs/security/waf-tuning).

### The event reference

Every event has a reference of the form `WAF-1284391`, shown on its own column in the log
and in the detail dialog. It is what a customer quotes: their own [Security
section](https://www.corepanel.net/docs/client-panel#security-their-own-attack-radar-and-none-of-the-controls) shows
the same reference on the events for their sites, with a button that copies it.

Paste it into the **Reference** field of the filter bar to go straight to that request. A
reference that does not resolve simply matches nothing — including one from another
account, which is the case a customer's ticket occasionally produces after a copy/paste
between two panels.

You can filter by domain, rule, action, client IP and country. The country comes from a
local GeoIP database the server keeps up to date on its own — there is nothing to
configure and no lookup leaves the machine. A few addresses have no country: anycast
ranges and networks the database does not map show an empty flag, which is normal and
not a sign of anything being wrong.

## Trusted IPs and exceptions

Two escape hatches, documented in [Tuning the WAF](https://www.corepanel.net/docs/security/waf-tuning):

- **Trusted IPs** — addresses that skip rule inspection entirely.
- **Exceptions** — skip specific rules on a specific URL prefix, optionally narrowed by
  method and client IP.

Reach for an exception before a rule toggle, and for a rule toggle before turning off a
family. The narrower the change, the less protection you lose.

## If the WAF is unavailable

When the engine's control socket cannot be reached, the security views degrade rather
than failing the page: statistics and the event log are unavailable while the sites
themselves keep being served. It is a monitoring outage, not a hosting one — but it does
mean you are flying blind until it is back.
