Title: Papy3D WAF
Author: papy3d
Published: <strong>October 10, 2026</strong>
Last modified: October 10, 2026

---

Search plugins

![](https://ps.w.org/papy3d-waf/assets/banner-772x250.png?rev=3737718)

![](https://ps.w.org/papy3d-waf/assets/icon-256x256.png?rev=3737718)

# Papy3D WAF

 By [papy3d](https://profiles.wordpress.org/papy3d/)

[Download](https://downloads.wordpress.org/plugin/papy3d-waf.2.0.31.zip)

 * [Details](https://wordpress.org/plugins/papy3d-waf/#description)
 * [Reviews](https://wordpress.org/plugins/papy3d-waf/#reviews)
 *  [Installation](https://wordpress.org/plugins/papy3d-waf/#installation)
 * [Development](https://wordpress.org/plugins/papy3d-waf/#developers)

 [Support](https://wordpress.org/support/plugin/papy3d-waf/)

## Description

Papy3D WAF is a local application firewall that inspects PHP requests before WordPress
loads. It uses `auto_prepend_file`, a standalone bounded runtime, declarative rules,
signed A/B publication and deferred import of authenticated security events.

The plugin provides Observation, Balanced and Hardened modes. Its protections cover
common web attacks and WordPress-specific probes, including SQL injection, XSS, 
command injection, traversal, file inclusion, sensitive-file access, malicious uploads,
webshell patterns, SSRF, XXE and repeated login abuse. Administrators can review
detections, create narrow exceptions, apply temporary source blocks and monitor 
runtime performance.

Installation of the early loader is never automatic. An administrator must review
the diagnostics and explicitly start installation. The installer does not replace
an unknown `auto_prepend_file`, validates the published runtime before activation
and restores the previous compatible Papy3D loader if validation fails. Multisite
runtime installation is intentionally unavailable. Mutable runtime data created 
by WordPress is confined to the dedicated directory below the base returned by `
wp_upload_dir()`, under `papy3d-waf/`, with direct HTTP access protection; these
files are non-executable JSON, DAT, LOG or text data. Because `auto_prepend_file`
must keep working while WordPress replaces the plugin directory during an automatic
update, the installer also maintains one dedicated `papy3d-waf-runtime/` directory
directly below the dynamically resolved WordPress content directory. That exceptional
directory contains only byte-for-byte copies of the PHP runtime files shipped with
this plugin, plus non-executable bootstrap metadata; it contains no remotely supplied
code, generated rules, logs or visitor data. Direct HTTP access to both directories
is denied and verified before activation. On supported PHP-FPM/CGI/LiteSpeed or 
Apache setups, the explicit installation also writes only the marked Papy3D WAF `
auto_prepend_file` block to the site-level `.user.ini` or `.htaccess`; it never 
edits WordPress core files, theme files or plugin source files, and removal targets
only its own files and marker.

Request values are inspected only in memory. WordPress authentication and password
cookies are excluded, authorization headers are not collected, and the journal stores
payload-free detection markers instead of URI queries, cookie values, request bodies,
header values or uploaded-file content. IP storage can use complete addresses or
irreversible IPv4 /24 and IPv6 /64 network obfuscation.

Papy3D WAF can integrate with Papy3D Security Guard through signed capability delegation.
Trusted-proxy remote updates are disabled by default, require explicitly selected
providers and a separate administrator opt-in for scheduled refresh; manual refresh
remains an explicit administrator action. The optional Cloudflare list integration
runs only when enabled or explicitly requested by an administrator. Automatic Cloudflare
append is disabled by default and requires exact-IP storage, an active blocking 
mode, a configured account and an existing selected IP list. No telemetry, remote
code or remotely executable rule is used.

See the FAQ, Privacy, External services and Changelog sections for detailed behavior,
data handling and release history.

### Privacy

Events are stored locally. WordPress authentication and password cookies are excluded
from inspection, and authorization headers are not collected. Request values are
inspected only in memory: the queue and database journal store payload-free detection
markers rather than URI queries, cookie values, request bodies, header values, or
uploaded-file content. The queue has bounded files and the WordPress event retention
period is configurable.

Administrators can retain complete IP addresses or store IPv4 as /24 networks and
IPv6 as /64 networks. Switching to obfuscated logging irreversibly transforms imported
historical IPs; pending authenticated events are masked in the interface and exports
and are stored obfuscated at import. A local HMAC remains available for grouping
and temporary blocking. JSON export can include the whole retained journal, or one
exact IP only while complete-IP storage is enabled. Exports contain sensitive security
data and must be protected and deleted after use.

Papy3D WAF also stores the administrator-configured “always allowed” IPv4, IPv6 
or CIDR ranges locally as mandatory security configuration. This allowlist is independent
of the journal IP-storage mode and is not obfuscated, because changing the configured
range would make the access-control rule ineffective. The detected current source
is only saved after an authorized administrator explicitly submits the first-run
form.

Automatic trusted-proxy updates are disabled by default. When an administrator selects
providers and separately enables automatic refresh, the server contacts only those
selected providers’ published IP-list endpoints over HTTPS. The providers necessarily
receive the server source IP and standard HTTPS metadata. The request user agent
identifies Papy3D WAF and its version but does not include the site URL, users, 
content, settings, or visitor addresses. Retrieved data is validated locally and
cached as last-known-good network ranges.

When an administrator configures the optional Cloudflare API integration, the account
ID, selected list ID, and API token are sent only to Cloudflare over HTTPS. Manual
actions remain explicit. When automatic append is separately enabled, one exact 
public IP and a bounded WAF comment can also be sent after the configured cumulative
or burst threshold. Cumulative counters use local HMAC identities. A local synchronization
registry links retained WAF identities to pending or confirmed membership of the
selected Cloudflare list so the Log can display AUTO, MANUAL, EXTERNAL or pending
state without querying Cloudflare for each row. Exact registry addresses are erased
when obfuscated-IP mode is enabled and are not repopulated by later reconciliation.
The token is stored locally with authenticated encryption, is never displayed again,
and is removed with the connection data on request. Automatic submission and real
reports are suspended when IP obfuscation is active.

### External services

The optional direct Cloudflare API integration uses `https://api.cloudflare.com/
client/v4/` and sends the account ID, selected list ID, Bearer API token and standard
HTTPS metadata. Credential management, list selection, refresh, download, manual
append and clearing remain administrator-triggered. If the administrator separately
enables automatic append, WordPress can send one exact public IP and a bounded WAF
comment after a cumulative or burst threshold; the pre-WordPress runtime never contacts
Cloudflare directly. An optional daily report sends exact blocked IPs, trigger counts,
reasons and outcomes through the site’s configured `wp_mail()` transport to administrator-
selected recipients. Cloudflare privacy and terms: https://www.cloudflare.com/privacypolicy/
and https://www.cloudflare.com/policies/terms/.

Trusted-proxy remote updates are optional. The explicit refresh button contacts 
only providers selected by an administrator. Scheduled WP-Cron refresh is disabled
by default and runs only after the administrator separately enables automatic refresh
while at least one provider remains selected. The request sends no site URL, user,
visitor IP, content, or plugin configuration. The selected provider receives only
the server source IP, standard HTTPS metadata, and a generic plugin/version user
agent. Retrieved values are locally validated as public IP addresses or CIDR ranges,
bounded, cached as last-known-good data, and merged with manual entries that are
never overwritten.

The following public sources can be contacted:

 * Cloudflare public IP API: https://api.cloudflare.com/client/v4/ips (machine-readable
   IPv4/IPv6 CIDR data)
    - Privacy: https://www.cloudflare.com/privacypolicy/
    - Terms: https://www.cloudflare.com/policies/terms/
 * QUIC.cloud combined server list: https://www.quic.cloud/ips-all
    - Privacy: https://www.quic.cloud/privacy-policy/
    - Terms: https://www.quic.cloud/terms-of-use/
 * bunny.net IPv4/IPv6 edge lists: https://bunnycdn.com/api/system/edgeserverlist
   and https://bunnycdn.com/api/system/edgeserverlist/IPv6
    - Privacy: https://bunny.net/privacy/
    - Terms: https://bunny.net/tos/
 * Fastly public IP list: https://api.fastly.com/public-ip-list
    - Privacy: https://www.fastly.com/privacy
    - Terms: https://www.fastly.com/terms
 * Imperva public integration API: https://my.imperva.com/api/integration/v1/ips
    - Privacy: https://www.imperva.com/trust-center/privacy-statement/
    - Terms: https://www.imperva.com/legal/website-terms-of-use/

Sucuri ranges are bundled from its published firewall documentation, so selecting
Sucuri does not contact GoDaddy or Sucuri. Documentation source: https://docs.sucuri.
net/website-firewall/troubleshooting/same-ip-for-all-users/

## Installation

 1. Upload and activate the plugin.
 2. Open the top-level **Papy3D WAF** administration page.
 3. Record at least one administrator IPv4, IPv6 or CIDR range in “Always-allowed addresses”;
    verify the detected source before saving.
 4. Review the detected SAPI, effective directive, owner, storage, and multisite status.
 5. Start the explicit installation. The initial runtime policy is always Observation
    and installation is unavailable while the administrator allowlist is empty.
 6. Keep an administration page open while the signed probe validates automatically;
    WP-Cron continues in the background if the page is closed.
 7. Use the manual probe button only if the automatic validation cannot complete, then
    review events before selecting Balanced or Hardened mode.

For emergency recovery, contact hosting support and provide the `P3DWAF_EMERGENCY_BYPASS`
recovery identifier. Any temporary recovery setting must be removed immediately 
after access is restored.

## FAQ

### What happens when an active WAF is updated?

The first runtime installation remains an explicit administrator action. After the
WAF has been activated successfully, plugin updates do not require a visit to the
status page. The external loader keeps the last validated runtime active while the
updated plugin schedules a deferred reconciliation. A new runtime is compiled in
the inactive slot, tested through an exact signed loopback probe, and activated 
atomically only after validation. On failure, the previous loader and runtime stay
active and a bounded retry is scheduled.

### Does it replace a network firewall or CDN?

No. It cannot stop traffic before PHP, static-file requests, or volumetric denial-
of-service attacks.

### Does it overwrite another auto_prepend_file?

No. An unknown owner is never overwritten. Security Guard integration is used only
when its public protocol-1.0 connector satisfies the minimum supported plugin and
connector versions.

### Does Observation mode block requests?

No. It records matching rules without blocking or banning.

### How do I import the malicious-IP file into Cloudflare?

Create or open an IP custom list in Cloudflare, choose Upload CSV, and select the
file generated by the “Malicious IPs” tab. The file intentionally has no header 
and contains one exact IPv4 or IPv6 address per line followed by an optional description.
Review the candidates before using the list in a blocking rule.

### Why is Cloudflare export disabled in obfuscated-IP mode?

A stored IPv4 /24 or IPv6 /64 network cannot be converted back to the original visitor
address. Exporting it could block an entire network, so the plugin requires exact-
IP storage for new candidates. Historical obfuscation remains irreversible.

### How does direct Cloudflare list addition work?

Create a Cloudflare API token restricted to the target account with the Account 
Filter Lists: Edit permission, then save the account ID and token in the “Malicious
IPs” tab. Select an existing list of type IP. The existing append button remains
manual and unchanged. A separate disabled-by-default option can append an exact 
IP automatically after either a cumulative threshold or a rolling burst threshold
is reached. Both paths reload the remote list, skip exact duplicates and IPs already
covered by a remote CIDR, verify the local 10,000-entry safety ceiling, and submit
only new entries. A separate explicitly confirmed action can clear all items while
preserving the remote list object and any WAF rule that references it. The selected
list must already be referenced by a Cloudflare blocking rule; the plugin does not
create or modify that rule.

## Reviews

There are no reviews for this plugin.

## Contributors & Developers

“Papy3D WAF” is open source software. The following people have contributed to this
plugin.

Contributors

 *   [ papy3d ](https://profiles.wordpress.org/papy3d/)

[Translate “Papy3D WAF” into your language.](https://translate.wordpress.org/projects/wp-plugins/papy3d-waf)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/papy3d-waf/), check
out the [SVN repository](https://plugins.svn.wordpress.org/papy3d-waf/), or subscribe
to the [development log](https://plugins.trac.wordpress.org/log/papy3d-waf/) by 
[RSS](https://plugins.trac.wordpress.org/log/papy3d-waf/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

#### 2.0.31

 * Corrected the WPCS suppression scope for the intentional pre-WordPress queue 
   writability check and fixed assignment alignment; no runtime behavior or security
   policy change.

#### 2.0.30

 * Hardened all persistent runtime state writes against pre-existing symlinks and
   path-swap races by verifying the opened regular file identity before writing;
   probe receipts now use exclusive random temporary files.

#### 2.0.29

 * Removed the unsupported `Tested up to` field from the main PHP plugin header;
   WordPress compatibility remains declared only in `readme.txt`.

#### 2.0.28

 * Harden pre-WordPress request ingestion across server headers, query, form, cookies,
   uploads and JSON/XML bodies; restore complete header inspection and client-IP
   resolution, make lifecycle shutdown fail-safe, and neutralize spreadsheet formulas
   in CSV exports.
 * Initial public release.
 * Hardened all pre-WordPress runtime class entry points so direct HTTP requests
   return 404 even after the early loader has initialized.
 * WordPress Coding Standards cleanup: complete parameter PHPDoc and alignment-only
   formatting fixes; no runtime behavior change.
 * Security Guard handoff is started only when Security Guard actually owns the 
   effective early loader; an available connector with owner `none` no longer causes
   a false transfer failure.
 * Hardened `auto_prepend_file` ownership detection to avoid false owner conflicts
   while preserving fail-closed handling for unknown loaders.
 * Provides the standalone pre-WordPress WAF runtime, signed A/B publication, Observation/
   Balanced/Hardened modes, authenticated event journal, privacy controls, trusted-
   proxy support, Cloudflare integration, Security Guard ownership handoff, and 
   bounded performance diagnostics.
 * WordPress 7.1 compatible, with English source strings and bundled French translation.
 * Hosting-configuration diagnostics direct administrators to hosting support and
   do not request direct edits to server or plugin files.

## Meta

 *  Version **2.0.31**
 *  Last updated **2 days ago**
 *  Active installations **Fewer than 10**
 *  WordPress version ** 6.8 or higher **
 *  Tested up to **7.1.3**
 *  PHP version ** 8.3 or higher **
 * Tags
 * [Brute Force](https://wordpress.org/plugins/tags/brute-force/)[firewall](https://wordpress.org/plugins/tags/firewall/)
   [hardening](https://wordpress.org/plugins/tags/hardening/)[security](https://wordpress.org/plugins/tags/security/)
   [WAF](https://wordpress.org/plugins/tags/waf/)
 *  [Advanced View](https://wordpress.org/plugins/papy3d-waf/advanced/)

## Ratings

No reviews have been submitted yet.

[Your review](https://wordpress.org/support/plugin/papy3d-waf/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/papy3d-waf/reviews/)

## Contributors

 *   [ papy3d ](https://profiles.wordpress.org/papy3d/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/papy3d-waf/)