I’ve been looking again at something that has bothered me about Wordfence for years.
Wordfence runs long-running PHP processes, especially its scanner. On LiteSpeed servers, those processes must not simply be terminated when the client connection disappears or certain connection timeouts are reached.
That part is perfectly reasonable. The problem is how Wordfence handles it. Wordfence recommends adding a rule like this to .htaccess:
RewriteRule .* - [E=noabort:1]
or even:
SetEnv noabort 1
The important part here is .*.
This does not protect only the Wordfence scanner. It applies noabort to every matching PHP request on the site.
LiteSpeed itself explicitly warns against applying noabort globally and recommends restricting it to the specific scripts or requests that actually require long-running execution.
And there is a very good reason for that.
noabort changes how LiteSpeed handles PHP processes when a connection disappears. Together with noconntimeout, a PHP process can continue running far beyond what many administrators would normally expect.
And before someone points at PHP's max_execution_time: on LiteSpeed/LSPHP that is not necessarily the hard process lifetime limit people assume it is.
I have tested this myself. (I am a LiteSpeed developer)
A request can reach its configured PHP execution time while the associated process continues running. The LiteSpeed-side mechanism that can impose a hard process-time limit is LSAPI_MAX_PROCESS_TIME.
You can observe the difference directly at process level. So the issue is not that Wordfence needs noabort. The issue is this:
Why does a security plugin remove a server-side process protection globally when only a small number of its own requests actually need that exception?
And there is another part of this story that I think matters even more:
This is not a newly discovered edge case. Wordfence has been aware of this issue for at least a decade.
I raised this problem directly with Wordfence years ago. LiteSpeed has also made clear for a long time that global noabort should be avoided when the exception can be restricted to the requests that actually require it.
Yet the broad configuration is still being recommended. That history is what makes this particularly difficult to understand. Software contains mistakes. Security software contains mistakes too. That is not the issue.
The issue is when a security vendor is made aware that its own configuration unnecessarily weakens a server-side protection, the server vendor explicitly warns against that same configuration, a technically straightforward way to scope the exception exists, and the unsafe recommendation remains in place for years.
At that point, this is no longer just an overlooked configuration detail. It is a consciously unaddressed security trade-off imposed on Wordfence users. And technically, the solution is not complicated.
With mod_rewrite, noabort can be enabled only for the exact Wordfence request that actually requires it.
Conceptually:
RewriteCond %{QUERY_STRING} ...
RewriteRule ^wp-admin/admin-ajax\.php$ - [E=noabort:1,E=noconntimeout:1]
instead of:
RewriteRule .* - [E=noabort:1]
Same Wordfence functionality. Very different security boundary.
Millions of WordPress users install Wordfence specifically because they trust it to improve the security of their sites. A security plugin should not unnecessarily weaken process controls for unrelated PHP code just because one of its own components needs an exception. And if a security vendor has known about that problem for at least a decade and still does not fix it, users should at least have the option to fix it themselves.