What Is Camouflage Security and How Does It Protect WordPress?
Camouflage Security disables PHP for public WordPress visitors, serves static HTML, and hides login and plugin paths from scanners.
Most WordPress security plugins start from the same assumption. A request arrives, WordPress boots, PHP runs, and the plugin tries to decide whether that request is an attack. Firewalls, malware scanners, login lockouts, and two-factor authentication all sit in that same layer: they filter what already reached PHP.
That model is weaker than it looks. Almost every WordPress vulnerability is a PHP vulnerability. Core, themes, and plugins are all PHP. An attacker cannot exploit code that never runs.
On a typical site, most public traffic is people reading pages. They do not need WordPress to boot. They do not need a database query. They do not need a plugin to execute. They need HTML.
Serious operators already know this. Some export the site to static HTML and host it on Netlify, Cloudflare Pages, or S3. Some go headless and put Next.js in front of the REST API. Both approaches try to get PHP off the public internet. Camouflage Security is built for the people who want that same outcome without a second host or a new frontend stack.
TL;DR: Camouflage Security disables PHP for public visitors. It crawls the site, saves a static HTML snapshot of every page, and has Apache serve those files from disk. WordPress never boots for those requests. The login page returns 404. Plugin and theme paths disappear from the page source. Anything that cannot be served statically is blocked until an administrator explicitly allows it. You keep the WordPress dashboard on the same server. You do not export to another host, and you do not stand up a headless frontend.
Why Security Plugins Don’t Actually Stop Attackers
A plugin like Wordfence, Sucuri, or iThemes Security is itself PHP. It loads inside WordPress. By the time it can inspect a request, WordPress has already bootstrapped, plugins have already been included, and a lot of code has already run. Anything that executes before the security plugin’s hooks — a must-use plugin, a drop-in, a vulnerability in a plugin that loads earlier — never has to pass that firewall.
What those plugins actually do is pattern-match. They look for known exploit strings, block IPs after enough failed logins, scan files for malware signatures, and lock the login form after N attempts. That catches commodity noise. It does not catch the hole that landed in a contact form plugin last Tuesday. Signature lists are reactive. Bots are not. They scan for wp-login.php, xmlrpc.php, REST routes, and plugin paths, then try whatever is in this week’s exploit kit against the versions they find.
Login lockout still requires the login page to exist. PHP still runs to count the failures. Hiding wp-login.php with WPS Hide Login or Hide My WP changes the address. WordPress is still behind that address. xmlrpc.php, admin-ajax.php, author archives, and the REST API are still PHP entry points. A scanner that finds any one of them is back in the same place.
Malware scanners find files after they are already on disk. They do not prevent the upload that arrived through a plugin vulnerability. File integrity checks tell you something changed. They do not stop the request that changed it.
The security plugin is also a large PHP codebase sitting on the public site. Wordfence and its peers have had their own CVEs. Adding a security plugin adds more PHP that can be exploited, more hooks that run on every request, and a false sense that the public surface is closed. It is not. PHP is still running for strangers on the internet.
Camouflage takes a different position. If PHP never runs for public visitors, there is nothing to filter on that surface. The attack has to find a request that is allowed to reach WordPress at all.
How Camouflage Serves a Site Without Booting WordPress
When Camouflage is active, a built-in crawler walks the site and writes a static HTML snapshot of every page. Apache then serves those files through .htaccess. A public GET for a cached page never starts PHP, never opens MySQL, and never loads a plugin or theme.
Content updates invalidate the relevant file. Publish a post or edit a page, and that snapshot is rebuilt. Regular content pages are not blocked. They are cached. Blocking only applies to requests WordPress itself could not resolve, AJAX calls, and POST submissions such as forms and comments.
The performance side effect is not a side effect. Apache handing a file off disk is faster than even a cached WordPress response, because cached WordPress still has to boot enough PHP to decide what to serve. Server CPU that would have gone to PHP is free, so the same hardware can take more concurrent traffic.
What Public Visitors and Bots Actually See
Most attacks against WordPress are automated. Bots look for known URLs, try the login page, read generator tags and script paths, then test vulnerabilities that match the versions they think you run. A site serving static HTML gives them much less to work with.
Login and core lockdown. wp-login.php and other WordPress core entry points return 404 to anyone without an admin bypass cookie or a one-time unlock link. Brute force against the login page cannot start if the login page does not exist for the attacker.
AJAX endpoint disguising. The real AJAX endpoint is not advertised. Cached pages point at a configurable decoy path, /assets/sync by default, which Apache rewrites internally. Public HTML and public logs do not show admin-ajax.php.
Optional asset rewriting. Theme, plugin, and core scripts, styles, and images can be mirrored into the static cache under hashed filenames. Cached pages reference those copies. Tools like WPScan and Wappalyzer that fingerprint WordPress from path patterns find nothing identifying in the source.
The public site still looks like the real site. It is the real site, frozen into HTML. What is missing is the PHP process behind it.
Dynamic Requests Are Denied Until You Allow Them
A contact form, a comment, or a theme AJAX call cannot be answered by a static file. Camouflage does not guess which of those are safe. It blocks them with a 404 until an administrator reviews the request and allows it.
Allow rules match on path, HTTP method, and the set of field names, not the values a visitor typed. A contact form keeps working no matter what someone puts in the message box. Unknown requests stay denied. That is an allowlist, not a blocklist, which is the point: the public surface is closed unless you open a specific hole.
There is an initial setup session for that reason. Camouflage is not a one-click firewall for a store with a live cart, a membership area, and a dozen AJAX widgets. It is built for developers who can walk the tracked requests and decide what the site actually needs.
How Administrators Still Get a Live Site
Logged-in administrators are not stuck looking at a snapshot. On login, Camouflage issues a signed bypass cookie so the admin always sees the live, editable WordPress site. A one-time login unlock link and a downloadable backup file cover the case where that cookie is lost, so you are not locked out of your own dashboard.
WordPress remains the CMS. You write, edit, and configure as usual. The static layer is what the public internet gets.
Exporting Static HTML, Going Headless, or Staying on WordPress
People who want PHP off the public internet usually pick one of three setups. Two of them work. Both of them cost a second system. Camouflage is the third option: keep WordPress where it is, and stop serving PHP to strangers.
Export the site and host the HTML somewhere else
This is the Simply Static / Staatic / WP2Static model, and it is a real security model. You crawl WordPress, write HTML, CSS, and JavaScript to disk, then deploy that tree to Netlify, Cloudflare Pages, GitHub Pages, or S3. The public hostname has no PHP, no WordPress, and no database. Bots that hit it have nothing to exploit.
The cost is a second host and a deploy pipeline. Every publish means a crawl, a build, and a push. Forms, comments, search, and anything POST-based do not survive unless you bolt on a third-party form service, a separate search index, or client-side hacks. Previews, staging, and “I just need to fix a typo” all go through that pipeline instead of the WordPress editor on the live URL.
WordPress still has to live somewhere. If the origin stays on a public URL — and it often does, because someone still needs to log in and edit — you now have two sites. The static one is safe. The CMS that generated it is still a PHP WordPress install on the internet, still running plugins, still a target. People lock that origin behind VPN or HTTP auth. Many do not. The export only helps if the PHP origin is actually unreachable from the public internet.
Camouflage keeps WordPress on the same server as the public site. There is no zip, no git deploy, no second DNS record. Apache serves the snapshot to the public. Admins hit the live dashboard on that same hostname. The PHP origin is not “somewhere else you might forget to lock down.” It is gated on this server: no bypass cookie, no PHP.
Go headless
Headless WordPress means the public site is a JavaScript frontend — Next.js, Nuxt, Astro, or similar — and WordPress is only a CMS behind the REST API or WPGraphQL. Visitors never hit index.php. They hit a Node app or pre-rendered HTML on a CDN. SQL injection against a theme file, and most plugin front-end holes, go away for those visitors because those files are not in the request path.
The WordPress install is still PHP. The frontend has to reach it. That means a public or semi-public API: REST routes, GraphQL, application passwords, sometimes preview callbacks. User enumeration, leaked drafts, and misconfigured CORS are the new shape of the same problem. You did not remove the attack surface. You moved it from theme PHP to an API, then added a Node app, a build pipeline, preview environments, and another place credentials can leak.
That split is the right architecture for a product team shipping a custom frontend. It is a lot of machinery for a blog, a marketing site, or documentation. Camouflage is for the case where the WordPress theme is already the site you want, and the missing piece is “don’t run that theme in PHP for the public.”
Install another security plugin and keep serving PHP
This is the default, and it is the one that does not solve the problem. A WAF still inspects requests that reached PHP. Hide My WP still renames paths in a running WordPress. 2FA and malware scans are worth having for people who log in, and Camouflage does not replace them. They do not change the fact that strangers can boot PHP on your server by requesting a page.
Camouflage can sit next to a WAF. On a brochure or content site it usually makes the public-facing WAF redundant. Use 2FA and a scanner for the admin session. Do not expect a security plugin to stop an exploit in a plugin that loaded before it did.
What Camouflage Requires
The plugin writes its own rules into .htaccess. It needs Apache with mod_rewrite. If rewrite is missing, the admin UI tells you the security rules are not active.
It does not support nginx. nginx does not read .htaccess, so an equivalent server block would have to be written by hand. Shared hosts that only offer nginx, and setups that cannot write .htaccess, are not a fit.
It also expects an allowlist pass. A marketing site, a blog, or a documentation site with a contact form is the intended shape. A WooCommerce checkout, a page builder with heavy AJAX, or a membership plugin will need more rules before it feels natural. That is a design choice, not an unfinished feature: unknown dynamic requests are supposed to fail closed.
If the site is already a static export on a CDN, or already a headless Next app, Camouflage is the wrong layer. Those stacks already took WordPress off the public hostname. Camouflage is for WordPress that still is the public hostname, and should stop behaving like PHP for everyone who is not an admin.
Install It
Camouflage Security is free and open source. Install it from the WordPress plugin directory, or clone the GitHub repository into wp-content/plugins/camouflage and activate it.
It requires WordPress 5.2+, PHP 7.4+, and Apache with mod_rewrite. After activation, build the static cache, walk the tracked requests, and allow the forms and AJAX calls the site actually needs. Until those are allowed, they 404 on purpose.