Security

PHP2Shell: closing a site without losing SEO

PHP2Shell: if you must close your site while waiting for the patch, how you close it matters. 503 code, robots.txt, duration: how not to lose your rankings.
Share via
PHP2Shell: closing a site without losing SEO

🇫🇷 Lire en français : PHP2Shell : couper son site sans perdre son SEO

PHP2Shell is the name given to two critical flaws in the PHP engine, patched on 21 October 2026, that let an attacker take over a server without a password. Updating WordPress, Drupal, PrestaShop or SPIP does nothing against them: it is PHP that must be patched, on the server side. If you cannot patch right away, closing is the right call, but how you close is decided in minutes and paid for over months. A 503 status code, a reachable robots.txt, under a day of downtime: here is the method, and why security and search visibility are handled together.

  • PHP2Shell (CVE-2026-109618 and CVE-2026-109619, CVSS v4.0 score of 9.2 out of 10) affects PHP itself: updating your CMS protects you from nothing, every PHP site is concerned.
  • If you close, return a 503, never a maintenance page with a 200. It is the only answer that tells Google “come back later” instead of “here is my new page”.
  • Keep robots.txt reachable with a 200 and aim for under a day: beyond that, Google treats the outage as permanent and removes the pages from its index.
  • Close the vulnerable service, not the whole site. A webmail or a client area can be stopped without closing the showcase.
  • The corrected versions are PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. PHP 8.1 and older no longer receive corrective releases from the PHP project.

“People call us to put a site back online. They should call us before they take it down: that is where everything is decided, and nobody prepares for that moment.”

— Olivier Watte, known as Oliver · founder of Kimoun


What is PHP2Shell, and why is updating your CMS not enough?  

  Tip

PHP2Shell is a flaw in the PHP engine: only whoever runs the server can fix it, not the CMS publisher.

PHP is the language that generates pages across a very large part of the web: WordPress, Drupal, Joomla, Magento, PrestaShop, SPIP, but also webmails, support tools and business software. The two flaws allow remote code execution with no password at all. According to the researchers who analysed them, the second also leaks fragments of memory where passwords, tokens or API keys belonging to other visitors may be sitting.

Every common execution mode is affected, and the risk peaks with mod_php, where an anonymous request can trigger the attack before a single line of your site runs. PHP published its patches on 21 October at 14:00 UTC, which was 10 in the morning in Guadeloupe. Exploitation attempts had been spotted before public disclosure; at this stage, no compromise has been publicly confirmed.

The difference with WP2Shell matters. In July, WP2Shell struck the WordPress core, and WordPress was able to force an update on millions of sites. This time the flaw sits below the CMS. Your WordPress can be perfectly up to date, plugins included: if the server runs a vulnerable version of PHP, the site is exposed.

Staying online without the patch: what are the risks?  

  Caution

Leaving a vulnerable PHP site online is not a trade-off between two options. A flaw rated 9.2 out of 10, exploitable without a password, gets scanned at scale within hours of publication. The question is not whether your site will be found, but when.

Let us be blunt: there is no reasonable scenario in which you keep a vulnerable site online while waiting for a better moment. The bots hunting for unpatched servers target nobody in particular. They sweep entire address ranges, probe, and keep whatever answers. A small site in Guadeloupe is exactly as interesting as a large one in Paris: it is a machine that responds, and that is all that counts.

A takeover is invisible. It breaks nothing, it slows nothing, and that is precisely the problem: most victims learn of the intrusion from a third party, weeks later. Here is what is actually at stake.

Your reputation, and it takes months to come back  

This is the costliest damage, and the most underestimated. A compromised site is typically used to host spam pages, redirects to dubious destinations, or phishing pages imitating a bank. Your legitimate pages stay intact: the new ones are added in directories nobody looks at.

Google finds them before you do. Your domain then gets flagged as deceptive, and browsers show a red warning screen to your visitors before the page even opens. For a hotel or a shop, that is the equivalent of an “unfit premises” notice on the window. The technical cleanup takes hours; getting the warning lifted and the rankings back takes weeks, sometimes months.

Your customer data, and your legal exposure  

Access to the server means access to the database: customer records, addresses, orders, phone numbers, passwords. With the second flaw, even the credentials your visitors type can leak at the moment they enter them.

A personal data leak is not merely a technical incident. Once unauthorised access is reasonably established, even without proof that data was copied, it is a breach under the GDPR. It must be reported to the supervisory authority without undue delay and, where feasible, within 72 hours of becoming aware of it, unless it is unlikely to result in a risk to individuals. Where the risk is high, you must also inform your customers directly. And in every case, including when no notification is required, the breach must be logged in an internal register.

Writing to your customers to tell them their data has circulated is an ordeal few businesses come through unscathed. Recent enforcement, incidentally, bears less on failure to notify than on weak security upstream and botched communication to individuals downstream.

Your resources, hijacked at your expense  

A compromised server is a free resource for whoever controls it. The classic uses: fraudulent emails sent from your domain, which gets it blacklisted and then stops your own messages from arriving; cryptocurrency mining, which saturates the processor; or taking part in attacks on other sites, with your IP address as the signature.

You pay for the bandwidth, you pay for the compute, and it is your name that appears in the logs of the next victims.

And above all: the other services on the same machine  

This is the least known risk, and often the most serious. A vulnerable site does not endanger only that site.

On shared hosting, dozens of sites live on the same server. A takeover on one of them opens the way to exploring neighbouring directories, reading their configuration files, and therefore reaching their databases. Your own credentials can be compromised without your site having had a single defect.

Even on a dedicated server the danger is real. Cryptocurrency mining that monopolises the processor and the memory brings down the other applications on the machine, one after another: your mail, your client area, your invoicing tool. The attacker does not need to compromise them, starving them of resources is enough. And if your services share the same database or the same internal network, the compromise spreads on its own.

That is why we handled our seven applications within hours, not days: a single vulnerable application was enough to put the other six at risk.

The exposed estate is considerable  

The problem is a large one, overseas territories included. In September, our Observatory found that 35% of overseas sites whose PHP version was readable were running an end-of-life release. For those sites, waiting for a fix leads nowhere: none is coming.

The only question worth asking becomes: patch now, migrate, or close cleanly while you get organised. All three answers are acceptable. Doing nothing is not.

How do you close your site without losing your rankings?  

  Tip

Close as little as possible, for as short a time as possible, and tell Google with a 503.

If your site cannot be patched right away, here is the order we recommend:

  1. Close only the vulnerable service. A webmail, a form or a client area can be stopped without closing the showcase site. That is exactly what our targeted webmail outage allowed.
  2. Return a 503 on the closed pages. It means “unavailable for now, come back later”, and Google ignores the content of the maintenance page.
  3. Add a Retry-After header to tell crawlers when to return.
  4. Keep robots.txt reachable, with a 200. A robots.txt returning a server error is handled separately by Google and can suspend crawling of the whole site.
  5. Aim for under a day. If the outage must last, serve a static version of the site, as Google suggests, rather than an empty page.
  6. Watch the reopening for a few days in Google Search Console (indexed pages, crawl stats) and in Bing Webmaster Tools.

In practice, on an Nginx server, a clean outage takes a few lines: return 503 across the site, let robots.txt through, and say when to come back.

location / {
    return 503;
}

# robots.txt must stay reachable with a 200: a robots.txt
# returning an error can suspend crawling of the whole site.
location = /robots.txt {
    try_files $uri =404;
}

error_page 503 @maintenance;
location @maintenance {
    add_header Retry-After 3600 always;
    try_files /maintenance.html =503;
}

These settings live at server or proxy level, not in the CMS. A badly configured “maintenance mode” plugin often returns a 200: precisely the mistake to avoid.

What remains is to understand why that technical detail weighs so much. That is the subject of the next section.

Why the HTTP status code decides what Google remembers  

On 21 October, hundreds of organisations chose to close. In France, every prefecture website was taken offline at the request of ANSSI, as were public sites in the Netherlands and Finland. In Quebec, the STM, the SAQ and the SAAQ locked their sites; at federal level, the Government of Canada shut down several services on the advice of the Canadian Centre for Cyber Security.

For a prefecture, search visibility is a secondary concern. For a small business, a hotel or an online shop, it is not. What Google takes away from an outage depends above all on the HTTP status code your server returns while it lasts:

OptionSecurityGoogle rankingsVisibility in AI answers
Stay online without the patchServer exposed to takeoverIntact until the hack, then spam, redirects and a “dangerous site” warningHacked content can be picked up
Close with a “maintenance” page returning 200ProtectedThe maintenance page may be indexed in place of your pagesSame risk in AI answers
Close with 404 / 410, or redirect everything to one pageProtectedPages treated as deleted or mergedPages lost as sources
Close cleanly with 503, under one dayProtectedPages kept, crawling slowed for a few daysLimited effect
Patch PHP without closingProtectedNo effectNo effect

Duration matters as much as the code. John Mueller, of Google, summed it up this way: a 503 is the right answer for an outage of about a day, but after a few days Google treats it as a permanent state and starts removing pages from its index. Even a clean outage leaves a trace: Google reduces its crawl rate in proportion to the pages in error, and raises it again only gradually.

Answer engines are no exception, and the risk there lasts longer. They rely on the same indexes or on their own crawlers, such as Labrador for ChatGPT. A “maintenance” page served as real content can end up summarised in an AI answer, in place of your offer.

The difference with Google is that a generative index does not refresh at the same pace. Where Google recrawls a reopened page within days, an AI answer can keep citing what it retained for weeks: your maintenance page, or worse, a hacked version of your site. That is the whole point of ranking inside AI answers: what gets captured at a given moment follows you for a long time. Our first AI Overview findings across 189 overseas sites already showed that cited sources change slowly.

How did we handle PHP2Shell on our servers?  

We apply this method to ourselves first. Here is how we handled our own servers on 21 October, and why we only had to close a single service.

Our work followed five steps. None of them required genius; all of them required knowing precisely what was running.

  1. Inventory. No PHP is installed directly on our three production servers: everything runs in Docker containers. Checking the PHP version on the server therefore showed nothing. We read the version container by container, then cross-referenced with the public domains. Result: 7 PHP applications exposed on the internet, all vulnerable, from PHP 8.1 to 8.5.9. Static sites and applications in Node, Python or Go were unaffected.
  2. Judgement call. Not every application deserved the same answer. One was removed, its usefulness no longer justifying the risk. An old PrestaShop on PHP 8.1 could not be patched as it stood: it had to be migrated in a hurry to a maintained version. The other five were patched. In the meantime, a targeted outage remained possible: shutting down the vulnerable webmail while keeping mail delivery and sending alive.
  3. Patching. The fix touched no line of application code: it was enough to change the base image of the containers, pinning the corrected version rather than a floating tag whose actual contents nobody can state. For one mail application whose publisher had not yet released a fixed version, we rebuilt the image replacing only the PHP packages, checking that the modules remained strictly identical.
  4. Verification. Each image was built and started locally with its database: service health, home page, login, business modules. Whenever a behaviour looked suspicious, the same test was replayed on the old image to tell a regression apart from something that was already there.
  5. Delivery. For two applications, the deployment platform was not tracking the repository’s main branch. Pushing the fix there would have changed nothing in production, while everyone would have believed the application was patched. For another, the image used in production was defined by a platform setting, not by the repository.

What this episode taught us (and what to ask your provider)  

These lessons hold for any PHP site, whoever manages it:

  • The inventory happens where PHP actually runs. In containers, the host server shows nothing: you have to look inside each container.
  • An up-to-date repository proves nothing. Only the version actually deployed in production counts.
  • A “latest” tag gives false security. Without an explicit pull, nothing updates itself.
  • A PHP version that is no longer maintained will never get a fix. You migrate, or you shut down.
  • A fix is verified on the running application, not only in the code.

Why a local, responsive provider makes the difference  

The patch landed at 10 in the morning, Guadeloupe time. For a provider based here, that was an ordinary morning’s work, not an on-call night from another time zone. Our seven applications were dealt with the same day, within hours of the patch going out. But the hour is not the main point: most of our work consisted of knowing. Knowing where PHP was running, which version was actually deployed, which application deserved to be patched and which one could go.

That last decision is not taken remotely, nor by a tool. Migrating one shop in a hurry while removing another application rather than spending the day on it means knowing what each is actually worth. That is the heart of managed hosting: a human who knows the estate, decides, and verifies. We wrote as much back in September: the problem is not the tool, it is the absence of oversight.

This is the third major alert in three months, after WP2Shell in July and the Shai-Hulud attack in August. The question to ask today is simple: who, in your organisation, has checked your site’s PHP version since 21 October? If nobody can answer, nobody is at the controls. Our hosting and managed services offer exists so that this question always has an answer.

And the technical answer is not enough on its own. A site that is patched but deindexed, or misquoted by an AI for weeks, is still a site that earns nothing. That is why we handle both sides together: the server on one hand, visibility in Google and in AI answers on the other. A security alert is also a search-visibility event, and few providers look at both at once.

Frequently asked questions

No, not by those updates. PHP2Shell is a flaw in PHP, the engine that runs WordPress on the server, not a flaw in WordPress itself. Automatic core and plugin updates never touch PHP: your site can display “everything is up to date” and remain fully exposed. Your host or your provider has to move the server to a corrected version, released on 21 October 2026: PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35. That is the difference with WP2Shell in July, when WordPress was able to force an update on millions of sites: this time the fix can only come from whoever administers the server.

The simplest route is to ask your host or your provider in writing, requesting the exact version, not just “PHP 8”. In WordPress, the Tools then Site Health screen shows it too, under Info. Two traps are common. If your site runs in containers, only the version read inside the container counts: the host server says nothing useful, and that is exactly what we found on our own machines. And a code repository that looks up to date proves nothing either, since only the version actually deployed in production matters. On two of our own applications, the deployment platform was not even tracking the main branch.

The PHP project no longer publishes corrective releases for those branches, even though it did provide source-level backports, and some distributions pass them on in their packages. In practice three options remain: migrate to a maintained version, which sometimes means adapting the site; buy commercial extended support; or shut the site down if it is no longer essential. That is the call we made internally: an urgent migration for an old PrestaShop on PHP 8.1, and the removal of another application whose usefulness no longer justified the risk. Leaving a site on an unmaintained version, exposed, is not a reasonable option.

About a day, provided you return a 503 status code and keep your robots.txt reachable with a 200. A 503 means “unavailable for now, come back later”: Google then ignores the content of your maintenance page instead of indexing it in place of your real pages. Beyond a few days it treats that code as permanent and starts removing pages from its index. If the outage has to last, serve a static version of the site during the work. Beware of CMS maintenance-mode plugins: many return a 200, which is precisely the mistake to avoid. The status code is set at server or proxy level, not inside the CMS.

No. A static site runs no PHP when a visitor arrives: it serves HTML files that were generated beforehand, so the flaw has nothing to exploit. On our own servers, static sites and applications written in Node, Python or Go were unaffected, and only the seven exposed PHP applications required work. Do check, though, that no secondary PHP tool is still reachable on the same domain or a subdomain: a contact form, a webmail, a support tool or a forgotten client area is enough to reopen the door. The inventory is worth doing even for a static site, and it takes minutes rather than hours.