Handbook · v1.2.0
Documentation
Everything needed to install, configure and operate Total Security WP — written for the person who has to answer for the site when something goes wrong. Each module explains what it does, what it changes on your server, and how to undo it.
Requirements
| Component | Minimum | Notes |
|---|---|---|
| PHP | 8.0 | Hard requirement. The plugin refuses to activate below this. |
| WordPress | 6.0 | Tested up to WordPress 7.0. |
| Database | MySQL 5.7 / MariaDB 10.3 | The plugin creates its own tables on activation. |
| Optimized WAF mode | auto_prepend_file or writable .user.ini | Optional. Falls back to Standard Mode automatically. |
| Build tooling | None | No Node.js, no Composer, no compile step. |
The admin dashboard is a React application that runs on WordPress core's own bundled
wp-element, loaded as native ES modules. Every PHP class is resolved by a
small built-in autoloader. There is nothing to build and no vendor directory to install.
Installation
- Upload the
total-security-wpfolder to/wp-content/plugins/, or install it from Plugins → Add New. - Activate it from the Plugins screen. Activation creates the plugin's tables and default settings; it does not yet change anything at the server level.
- Open Total Security WP in the admin menu. The Setup Wizard starts automatically on first run.
- Work through the wizard, then review Total Security WP → Settings and enable two-factor authentication for every administrator.
If another firewall or file-scanning plugin is active, deactivate it before running the
wizard. Two plugins writing competing rules into the same .htaccess is the
single most common cause of a broken site after installing any security plugin.
Installing via WP-CLI
wp plugin install total-security-wp --activate
wp total-security-wp statusThe Setup Wizard
The wizard probes your hosting environment and deploys the firewall in the strongest mode the server actually supports, rather than asking you to guess. It runs four steps:
- Server probe — detects the PHP SAPI (mod_php, CGI, FPM), whether
auto_prepend_filecan be set, and whether.user.iniis writable. - Firewall deployment — writes the prepend bootstrap and bundles the WAF kernel outside the plugin directory so it survives plugin updates.
- Self-test — issues a loopback request carrying a benign test payload to confirm the deployed firewall actually intercepts traffic.
- Rollback on failure — if the self-test does not come back clean, the wizard removes what it wrote and falls back to Standard Mode. It never leaves a half-deployed prepend behind.
You can re-run the wizard at any time from the dashboard — for example after moving hosts, where the right firewall mode may have changed.
The dashboard
Everything lives under the Total Security WP admin menu, entirely inside wp-admin. It is independent of your active theme and works identically on block and classic themes.
Security Score
An A–F health grade computed from module status, hardening coverage, outstanding findings and account hygiene. It is also rendered in the admin bar on every page, front end and back, so a site manager sees a regression without opening the dashboard.
Onboarding checklist
Tracks the handful of steps that genuinely matter after install — firewall deployed, first scan run, 2FA enabled, backup taken — and dismisses itself when they are done.
Capability
Access is gated on the manage_total_security_wp capability, granted to
administrators on activation. Grant it to a custom role to give a security contractor
access to the dashboard without making them an administrator.
Firewall & WAF modes
The web application firewall scores each request against a signature set covering SQL injection, cross-site scripting, local and remote file inclusion, path traversal, remote code execution and SSRF. Requests that cross the block threshold are terminated; requests that score but do not cross it are logged for review.
| Mode | Runs | Requires | Trade-off |
|---|---|---|---|
| Optimized | Before WordPress loads, via a PHP prepend | auto_prepend_file or a writable .user.ini |
Blocks hostile traffic before the WordPress bootstrap, database connection or plugin loading. Recommended. |
| Standard | Inside WordPress, as early as possible | Nothing | Works everywhere. WordPress has already begun booting by the time a request is blocked. |
The Optimized Mode prepend is written to fail open. If its configuration or any of its files are missing, unreadable or corrupt, it does nothing at all rather than throwing a fatal error. A security plugin that takes your site offline when it breaks is a worse outcome than one that briefly stops filtering.
Getting the real visitor IP right
Behind Cloudflare, a load balancer or any reverse proxy, REMOTE_ADDR is the
proxy — blocking on it would ban every visitor at once. Set the trusted proxy header
under Settings → Firewall so bans, rate limits and the audit log all
record the true client address. Only trust a header your proxy actually sets and strips
from inbound requests.
Rate limiting, brute force & bots
- Rate limiter — per-IP request budgets over a rolling window, with a separate, tighter budget for
wp-login.phpand the REST authentication routes. - Brute-force protection — progressive lockout on repeated failed logins, counted per IP and per username so an attacker cannot rotate one to escape the other.
- DDoS shielding — detects request floods and sheds load before they reach the WordPress bootstrap.
- Bad-bot blocker — blocks scrapers and vulnerability scanners by user-agent and behaviour, with verification for bots that claim to be search engines.
- Geo-blocking — country-level allow or deny lists, appliable to the whole site or to the login and admin surfaces only.
Blocking your own country locks you out. Add your own address to the allowlist first, and keep the standalone recovery endpoint enabled — see Emergency recovery.
Virtual patching
When a vulnerability is published for a plugin or theme you have installed, there is a gap between disclosure and the moment you can safely apply the vendor's fix. A virtual patch closes that gap at the firewall: a targeted rule that blocks the specific request shape the exploit needs, without touching the vulnerable code.
- Bundled patches ship with the plugin and cover widely exploited CVEs in popular plugins. Free
- Custom patches let you write your own rule for something specific to your stack. Free
- Suggested patches are generated by correlating your installed plugin inventory against known advisories. Free
- Patch-gap intelligence flags plugins with a public CVE but no vendor fix yet — the highest-risk window there is. Pro
- Automatic patching applies approved patches as new CVEs are published, without waiting for you to log in. Pro
A virtual patch is a stopgap. Apply the real update as soon as your release process allows.
Hardening
Each hardening control is individually toggleable, states plainly what it changes, and can be reverted from the same screen. Nothing is applied silently.
| Control | What it does |
|---|---|
| Server rules | Generates .htaccess or Nginx rules blocking direct execution of PHP in uploads, and access to backup, log and configuration files. |
| wp-config hardening | Sets DISALLOW_FILE_EDIT and related constants inside a clearly marked, reversible block. |
| Directory guard | Disables directory browsing and adds index guards to writable directories. |
| REST API guard | Restricts anonymous REST access — notably user enumeration via /wp/v2/users — without breaking the block editor. |
| XML-RPC guard | Disables XML-RPC entirely, or blocks only system.multicall and pingback.ping if you still need Jetpack or the mobile app. |
| Version obfuscation | Strips the WordPress version from the generator tag, feeds and asset query strings. |
| Security headers | Emits HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy and Permissions-Policy. |
| Redirect guard | Blocks open-redirect abuse of the redirect_to parameter to off-site hosts. |
| Host header guard | Rejects forged Host headers used for cache poisoning and password-reset poisoning. |
| Outbound request guard | Constrains where the site itself may make HTTP requests, limiting SSRF impact from a compromised plugin. |
| Honeypot | Plants decoy paths that no legitimate visitor requests; anything that touches them identifies itself as a scanner. |
| Exposure scanner | Finds files that should not be publicly readable — stray database dumps, .env files, editor backups, exposed .git directories. |
Content Security Policy
A hand-written CSP usually breaks a WordPress site, because no one can enumerate every script a theme and twenty plugins load. Total Security WP builds one by observation instead:
- The CSP scanner crawls your own pages and records the sources actually in use.
- A candidate policy is proposed from that inventory, with each source shown alongside what requested it.
- You run it in report-only mode. Violations collect in a dashboard list rather than breaking anything.
- When the violation stream is quiet, you promote the policy to enforcing.
Pending sources are held in their own queue, so a source that appears after a plugin update surfaces as a decision to make rather than as a silently broken page.
Malware scanner
The scanner combines three detection strategies, because signature matching alone misses anything new and heuristics alone produce noise:
- Signature matching against a bundled malware signature database.
- Token analysis, which parses PHP into tokens rather than matching raw text — so obfuscation through concatenation, encoding or variable functions does not hide a payload.
- Taint analysis, which traces untrusted input to dangerous sinks to catch backdoors that no signature covers.
What gets scanned
- Every PHP, JavaScript and HTML file under the WordPress root, including mu-plugins and drop-ins.
- The database — posts, comments, options and user meta — for injected spam, malicious redirects and rogue administrator accounts.
Scheduling
- On-demand full scans, any time. Free
- A weekly automatic baseline scan on every install. Free
- Daily or twice-daily scheduled scans with emailed results. Pro
- Auto-quarantine of infected files the moment a scan finds them. Pro
Handling false positives
Any finding can be whitelisted, individually or in bulk. Whitelisting is recorded by file and content hash, so a whitelisted file that later changes is flagged again rather than being trusted forever.
File integrity monitoring
Integrity monitoring answers a different question from the scanner: not “does this look malicious?” but “is this the file the author shipped?”
- Checksum verification — core, plugin and theme files are compared against the official WordPress.org checksums, the same source core uses for update checks. Any modification is reported with a diff.
- Baseline diffing — for everything without published checksums (custom themes, premium plugins, mu-plugins, drop-ins), the plugin records a baseline and reports every subsequent addition, change and deletion.
If you deploy custom code, re-baseline as the last step of your deploy. Otherwise your own release shows up as a wall of integrity alerts and trains you to ignore them.
Live Traffic
A real-time feed of requests hitting the site, with each visitor classified as human, verified search engine crawler, or unverified bot. Two views: security events only, or all traffic. Any address can be blocked or unblocked in one click straight from the feed, and the whole view exports to CSV for an incident write-up.
Audit log
A full event trail of everything security-relevant: logins and failures, user and role changes, plugin and theme activity, settings changes, file events and firewall decisions. Each entry records the acting user, the source IP, the proxy chain and the request context.
- 90-day retention, with CSV export. Free
- Extended retention, scheduled email digests and PDF export. Pro
The incident correlator groups related events into a single narrative — a login failure burst, a successful login from a new country, then a plugin file edit reads as one incident rather than three unrelated rows.
Quarantine & repair
Finding an infected file is the easy part. The plugin's incident tooling is built around never making a bad situation worse:
- Quarantine — the file is moved to a protected store rather than deleted, so a false positive is one click from being restored.
- Clean-file recovery — modified core, plugin and theme files are replaced with the authentic copy fetched from WordPress.org.
- Plugin reinstall — a badly infected plugin can be reinstalled from source asynchronously, without a timeout on a large site.
- Repair backups — every repair snapshots what it replaced first, with its own retention setting.
- Permission reset — restores sane file and directory modes after an attacker has loosened them.
- Bulk triage — on a heavily infected site, findings are grouped so you can repair everything of one kind in a single operation.
Backup & restore
On-demand full-site backups covering both files and the database, written in chunks so large sites do not hit a PHP timeout. Backups are listed with their manifest, and the list degrades gracefully rather than erroring if a manifest becomes unreadable.
- On-demand full backup and restore. Free
- WooCommerce delta backup — capturing orders and customer records between full backups, where a nightly-only cadence would lose a day of transactions. Pro
A backup stored only on the machine you are backing up does not survive that machine. Pull a copy off-site on whatever schedule matches how much work you are prepared to lose.
Emergency recovery
The worst moment to discover your recovery plan needs a working wp-admin is when wp-admin will not load. Total Security WP ships a standalone recovery endpoint that runs independently of WordPress: it can restore a backup even when WordPress itself is fatal.
- Enable recovery under Settings → Backup.
- Download the generated recovery script and note its credentials. The script is generated on demand, not shipped as a static file in the plugin — a permanent recovery endpoint sitting in every install would itself be an attack surface.
- Store it somewhere you can reach without the site. It can be re-downloaded any time while recovery stays enabled.
Run one restore into a staging copy while everything is calm. An untested restore procedure is a hypothesis, not a backup.
Two-factor authentication
TOTP-based two-factor authentication, compatible with any standard authenticator app. Enrolment is by QR code, with one-time backup codes issued at the same time.
- Enforcement by role — require 2FA for administrators and editors while leaving subscribers alone.
- Trusted devices — optionally let a user skip the second factor on one browser for 30 days, with a self-service list and one-click revoke.
- Session management — see every active session for an account and terminate any of them.
- Admin reset — an administrator can clear a locked-out user's 2FA enrolment, from the dashboard or via WP-CLI.
WP-CLI resets 2FA without needing to log in: wp total-security-wp twofa reset <user>
Login protection
- CAPTCHA — optional Cloudflare Turnstile or Google reCAPTCHA on the login form. Off by default; enabling it loads that provider's script on the login page only.
- Password policy — minimum length and complexity, enforced per role.
- Breached-password check — on login, the password is checked against the Have I Been Pwned Pwned Passwords corpus using k-anonymity: only the first five characters of a SHA-1 hash ever leave your server, and the password itself never does. It warns the user; it never blocks the login.
- Custom login URL — move
wp-login.phpto a path of your choosing to shed automated login traffic. - Impossible-travel detection — flags a login from a location the account could not physically have reached since its last one. Pro
Save the new URL somewhere outside the site before you log out, and tell anyone else with an account. This is obscurity, not security — useful for cutting noise, no substitute for 2FA and a strong password.
Notifications
Alerts go out by email or webhook — Slack and Microsoft Teams incoming webhooks work out of the box. Every notification carries human-readable guidance explaining what the event means and what to do about it, rather than a bare event code.
- Per-event-type muting, so one chatty rule does not train you to ignore the channel.
- A sent-history log, so you can confirm whether an alert actually went out.
- PagerDuty and OpsGenie adapters, and uptime monitoring, for teams already running an on-call rotation.
WP-CLI
All commands live under the wp total-security-wp namespace.
# Overall posture, module status and security score
wp total-security-wp status
# Full malware scan (--quick limits it to high-risk paths)
wp total-security-wp scan
wp total-security-wp scan --quick
# List active firewall rules and virtual patches
wp total-security-wp firewall list
# Take a full backup (files + database)
wp total-security-wp backup create
# Clear a locked-out user's 2FA enrolment
wp total-security-wp twofa reset admin
These are the commands to reach for in a deploy pipeline: run a scan after a release, take a
backup before a migration, and check status in a health check.
REST API
The dashboard is a client of the plugin's own REST API, which means anything the dashboard can do, your own tooling can do too. All routes live under:
/wp-json/total-security-wp/v1/
Every route requires the manage_total_security_wp capability and a valid
nonce or application password. Controllers are grouped by module — status, firewall,
scanner, quarantine, repair, backup, logs, traffic, hardening, auth, notifications,
settings, jobs and the setup wizard — with Pro modules exposing their own routes when
licensed.
Long-running work (scans, backups, bulk repairs) runs as a job: the route returns a job handle immediately and progress is polled, so nothing depends on a single long HTTP request surviving.
Configuration constants
Define these in wp-config.php above the “stop editing” line.
| Constant | Purpose |
|---|---|
TOTALSECWP_LICENSE_API_URL | Overrides the license and threat-intel service endpoint. Mainly for staging environments. |
TOTALSECWP_LICENSE_ITEM_SLUG | Product slug used during license activation. |
TOTALSECWP_TELEMETRY_API_URL | Endpoint for opt-in firewall-bypass telemetry. Unused unless you have explicitly consented. |
Read-only constants you can reference from your own code:
TOTALSECWP_VERSION, TOTALSECWP_SLUG,
TOTALSECWP_REST_NAMESPACE, TOTALSECWP_CAP,
TOTALSECWP_MIN_PHP.
Pro modules
Pro is aimed at people running security as an ongoing operation rather than a one-time install. Full detail on the Pro page; in short:
- Threat intelligence — hourly WAF signature updates and CVE-matched virtual patching from a live advisory feed, with cryptographically verified signature bundles.
- Under Attack Mode — a one-click emergency shield: aggressive rate limits, a bot challenge wall, REST/XML-RPC/login lockdown, and automatic expiry so you cannot leave it on by accident.
- Sentinel AI — builds a redacted evidence bundle for a suspicious actor and returns a threat verdict with a recommended action. Opt-in, consent-gated, and it falls back to local rule-based triage when disabled.
- Cloud reputation — distributed file and IP verdicts from a shared reputation network, cached locally.
- Compliance reporting — control coverage mapped to common frameworks, exportable as PDF for an auditor.
- Agency tooling — white-label dashboard, security roles, multisite support, and a hub-and-satellite model where many sites report into one console.
The Pro tier is decided locally by cryptographic token verification — no HTTP call on every request, and an offline grace window that survives a temporary network failure. From 1.2.0 the plugin updates exclusively through WordPress.org; Pro features unlock via the license token, while fast-moving security data updates independently through the threat-intel feed.
Troubleshooting
The wizard says Optimized Mode is unavailable
Your host allows neither auto_prepend_file nor a writable .user.ini. Standard Mode is deployed instead and your site is still protected — the firewall simply runs inside WordPress rather than ahead of it.
On PHP-FPM, ask your host to make .user.ini writable in the web root. On some managed hosts this is deliberately locked and Standard Mode is the correct answer.
I locked myself out
Most lockouts come from geo-blocking, a custom login URL, or a 2FA device that is gone. WP-CLI resolves all three without logging in:
wp total-security-wp twofa reset <user> clears an enrolment. wp total-security-wp firewall list shows what is currently blocking.
With no CLI access, rename the plugin folder over SFTP to deactivate it, fix the setting, then rename it back. Server-level changes are written into clearly marked, reversible blocks.
A legitimate request is being blocked
Open Live Traffic and find the blocked request — it shows the rule that matched and the score it produced. From there, whitelist the specific rule for that path, or exempt the address.
Payment gateway callbacks and webhook endpoints are the usual culprits, because they post payloads that look structurally like injection attempts. Exempt the specific route rather than lowering the global threshold.
The scanner times out on a large site
Scans run as chunked background jobs and resume where they stopped, so a timeout normally self-heals on the next cron tick. If WP-Cron is unreliable on your host, run the scan from WP-CLI instead, where no web request timeout applies.
Integrity monitoring reports my own custom theme
Expected: custom code has no published checksums, so it is monitored against a recorded baseline. Re-baseline after each deploy and the noise disappears.
Can I run this alongside another security plugin?
You can, but running two firewalls or two file scanners is redundant and occasionally harmful — both plugins writing competing .htaccess rules is the classic failure. Deactivate other WAF plugins before activating this one.
Will it slow down my site?
In Optimized Mode, malicious requests are terminated before the WordPress bootstrap, the database connection and plugin loading — typically faster than firewall plugins that only hook into WordPress. Legitimate requests pay a small signature-evaluation cost. Scans and backups run as background jobs, off the request path.
Uninstalling
Deactivating or deleting the plugin behaves predictably, and the two categories are treated differently on purpose:
- Server-level changes are always reverted on delete — the firewall prepend, generated
.htaccessand Nginx rules, andwp-configmarkers. These are removed regardless of your settings, because leaving them behind could break a site that no longer has the plugin to manage them. - Your security data is kept by default — audit logs, scan history and settings stay in the database so a reinstall picks up where you left off.
For a complete wipe, enable Delete all data on uninstall under Settings before removing the plugin. Once the plugin is gone, its uninstall routine can no longer run.
Support
General support
Usage questions, configuration help and bug reports go to the WordPress.org support forum for the plugin.
Security vulnerabilities
Found a flaw in the plugin itself? Report it privately — see the disclosure policy. Please do not post it in the public forum.
Plugin version, WordPress version, PHP version, active firewall mode, your host, and the relevant rows from the audit log or Live Traffic. The CSV export from either view is the fastest way to send it.