Real-time write firewall for WordPress
Security that runs before WordPress does
Most security plugins find the webshell after it's on disk. Must-Have Security stops it from becoming a file at all. An engine loaded before WordPress judges every write by what it contains, and refuses executable code that nothing on your site was allowed to create. And for what was already there before you installed it, a scanner that proves files harmless instead of guessing.
A malware scanner reacts. This intercepts.
Signatures describe payloads that have already been seen and are already on disk. The webshell that breaks into your site next has no signature anywhere yet.
Must-Have Security doesn't try to recognise the payload. It watches the one thing every persistent attack has in common. Sooner or later, the code has to become a file. An extension proves nothing, so the engine reads the bytes: a .txt that carries <?php next to eval($_POST[…]) is not documentation. The write is refused before the file exists.
Being an admin isn't permission to write code
Four layers, each judging a different thing, and all following one principle: the ability to modify executable code is a capability WordPress hands out too freely, so this takes it back and lends it out deliberately.
Code control
Acts at the write, before the file exists
Every write is judged by its bytes, uploads included, and executable code needs a permission you opened yourself.
- Two-stage content detection, every dotted segment checked
- Scoped write permissions, timed in minutes
- Trusted admins and their factors kept outside the database
- Footprint whitelist keyed on content, never on a location
Request firewall
Acts on every request, before WordPress loads
Decides what may be asked for in the first place, and which clients get an answer at all.
- Direct-request layer: which PHP files may be asked for by name
- Bad-bot and AI-crawler rules
- Optional country database (DB-IP, opt-in)
- Path decoded and collapsed before matching
Database and cron monitoring
Acts in the background, while the site runs
Watches where an attacker goes when a file write is refused: scheduled tasks and writes into the database.
- New and changed cron entries reported
- SQL writes recorded with their payload
- Findings arrive with the evidence attached
- Optional daily or weekly e-mail summary
Malware scanner
Acts on schedule, and whenever you ask
For what was already on disk. Core is checked against the official checksums, everything else is read as code.
- Two passes, everything executable first
- A classifier proves files harmless, under 1 % reach AI
- Shared reputation: each file content judged once
- Flags with the evidence, never deletes on its own
Every layer writes to the same append-only journal: the proposed content, its hash and the caller chain. Blocked payloads are kept under quarantine, so you can allow one once and replay it through the same policy.
See a webshell get refused at the write
A live upload with a payload inside, monitor mode showing exactly what enforce would do, and a scoped permission opening for a real plugin update.
Updates work. Injections don't.
Under enforcement, writing PHP needs a scoped write permission, one you open yourself, from the screen you're on. Click "Update plugin", tap your passkey, and a permission for wp-content/plugins/** opens for a few minutes.
A stored XSS firing from the same administrator session, trying to write functions.php? No permission covers themes, so it's refused, even though WordPress considers the session entirely legitimate. Proving a factor never opens a window: every permission costs a fresh tap, so a script has nothing recent to ride on.
The one screen it can't lock you out of
A security plugin that bricks the screen where you'd turn it off has failed, whatever it caught on the way. So Must-Have Security starts in monitor mode: every write is evaluated and recorded with its full payload, and nothing is blocked. You see precisely what enforce would do on your real site, at zero risk.
The response layer fails toward letting people in. An address a trusted admin has used is never refused, blocks are timers not walls, and the whole thing only starts refusing writes once you've read the log and flipped the switch yourself.
The most dangerous line of code on your site, handled with care
Running before WordPress means one broken line takes every URL to a 500, wp-admin included. Nothing else this plugin does can fail that badly, so the loader is shaped entirely around never failing that way.
The method is chosen from the SAPI, not a server banner. Removing a loader is a two-stage retirement, never a delete. The stub is replaced with an inert file that exists and does nothing, because a missing auto_prepend_file is a fatal, not a warning. If the engine itself ever fatals, it switches itself off, lets the site boot and e-mails every trusted administrator. And because "make the engine fail" must never become a way to turn the protection off, that switch is yours to disable, behind a passkey.
Prove it on your host
Hosting environments differ enough that the only trustworthy answer is a measured one. The built-in self-test lab writes real payloads through real PHP functions into a sandbox, with enforcement on for that directory only, and reports per vector whether the operation was stopped.
It also measures the wrapper's per-operation overhead on your server, and it's honest about the gaps: exec(), move_uploaded_file() and code that's already executing are named, not hidden. It has already earned its keep. ZipArchive::extractTo() was written down as a bypass, and the lab disproved it.
A scanner that proves files harmless
The write firewall stops what tries to arrive. The scanner is for what arrived before: over FTP, in a plugin that shipped with a backdoor, or as an SVG with a script inside. It runs in two passes: everything that can execute first (PHP in any dotted segment, .htaccess, uploads that shouldn't be there), then every other file for hidden PHP.
Core is verified against the official WordPress checksums. Everything else goes through a classifier that reads PHP as tokens and follows request input through the code: a file with no backdoor mechanism reachable from any input is good, no AI needed; eval($_POST[…]) is bad by rule, whatever anyone says. Only what cannot be decided either way (under 1 % of files on a real site) is judged by AI, and only that leaves your site. It flags, never deletes. You review each finding with the file in front of you.
The webshell never becomes a file.
Not scanned after the fact. Refused at the write, before WordPress even loads.
Get Must-Have Security NowSimple, Transparent Pricing
Every layer in every plan. It keeps protecting your site even if your subscription lapses.
Single
- 1 website
- Write firewall & upload gate
- Malware scanner
- Passkeys & scoped permissions
- Request firewall & direct-request layer
- Evidence journal & quarantine
- Self-test lab
- Updates & support
Multi
- 5 websites
- Write firewall & upload gate
- Malware scanner
- Passkeys & scoped permissions
- Request firewall & direct-request layer
- Evidence journal & quarantine
- Self-test lab
- Updates & support
Try it risk-free in monitor mode. Not for you? Every cent back, no questions asked.
Frequently Asked Questions
A signature scanner looks for known-bad code that is already on your disk. Must-Have Security first stops the code from being written at all. It runs before WordPress, judges every file write by its content, and refuses executable code that nothing on your site was authorised to create, so a brand-new webshell with no signature anywhere is still refused. It also has a scanner for what was already there, but a different kind: core is verified against the official checksums, and everything else is read as code. A classifier follows request input through the file and either proves it harmless, condemns it by rule, or hands the rare undecidable case to AI. No signature list to be one step behind.
No. When you update a plugin, theme or core, you open a scoped write permission from the screen you're on with one tap of a passkey. It covers exactly that path, for a few minutes. And it ships in monitor mode, so you can watch what enforce would do on your real site before turning it on.
It is engineered specifically not to. It starts in monitor mode, the response layer fails toward letting people in, an address a trusted admin has used is never refused, and the loader is retired in two safe stages rather than deleted. If the engine itself ever fatals, it switches itself off, lets the site boot and e-mails every trusted administrator, who re-arms it from the dashboard. (That self-disable is a switch: if you would rather a broken engine mean a 500 than an unprotected site, you can turn it off, behind your passkey, because the other direction is a weakening.)
Each file operation round-trips through PHP userland, which costs single-digit microseconds per operation on a typical host, so a few milliseconds on a full admin request. Don't take that on faith: the built-in self-test lab measures the exact per-operation overhead on your server.
WordPress and PHP with the ability to set auto_prepend_file via .user.ini or .htaccess, which covers almost all shared and managed hosting. Where no loader fits, it falls back to booting after WordPress. It needs no root, no server module and no daemon.
The administrator role lives in the database, which is exactly what an injection can rewrite. So the trusted-admin registry and every credential live outside the database, protected by the engine as its own control files. Being a WordPress admin, even a freshly injected one, is never enough to write executable code.
WordPress moves uploads with move_uploaded_file(), which skips the write wrapper, so the upload gate judges the temp file first, by both its bytes and its name. A JPEG carrying a PHP payload is refused, and so is shell.php.jpg, because every dotted segment of the name is checked.
The write engine is fully deterministic: no network, no database, no AI. The same inputs give the same verdict on every request, and nothing can overturn it. The malware scanner is the one part that talks to a service, and it is off until you turn it on and acknowledge that. Even then it sends as little as possible: core is checked by hash, files already known to the shared reputation database by hash, and of the rest a classifier decides most on your own server. Only files it cannot prove harmless or condemn by rule (under 1 % on a real site) are sent to be judged by AI, over HTTPS, with your secrets (wp-config, .env, keys, backups) excluded from the walk entirely. AI reviews are capped per site (3,000 an hour, 300 a day); a file over the cap simply waits for the next scan.
It stops persistence, not post-exploitation. Code that is already executing in a request can call exec() or unhook the wrapper. This layer stops a payload from becoming a file; it does not contain code that is already running. The self-test lab reports exactly which of those gaps are open on your host, rather than the docs pretending they're closed.
Yes. The engine keeps enforcing, so your security is never held hostage. An active subscription is required for updates and support. Deactivating cleanly removes the loader, and uninstalling keeps your settings unless you tick "delete all data".
Stop cleaning up webshells. Stop them being written.
Join the WordPress professionals who moved from scanning for the breach to preventing it.
Get Must-Have Security
Must-Have Backup