PHP2Shell on ispmanager and CloudLinux: what didn’t go by the book

Hosting, Security

On 21 October 2026 the PHP project released 8.5.12, 8.4.27, 8.3.36 and 8.2.35, fixing two critical vulnerabilities, CVE-2026-109618 and CVE-2026-109619 (CVSS v4.0 9.2). Both allow unauthenticated remote code execution, and the vulnerable component is not a plugin but the interpreter itself: every PHP site, from WordPress to custom code.

On a regular server the story is short: update the package and restart PHP. On hosting servers with ispmanager and CloudLinux it turned out to be more interesting. Over one night and morning we patched all our servers and stepped on almost every rake that neither the PHP advisory nor the panel documentation mentions.

This is not a retelling of the advisory but a list of what didn’t go by the book and how we solved it. If you run a server with ispmanager, especially on CloudLinux, check each point on your own system: some of these problems stay invisible until you look in the right place.

Temporary measures before the patches

Until packages are available you cannot fully close the vulnerabilities, only cut off the known attack paths. The public exploits that appeared before the release used the file upload progress handler, which runs on any multipart/form-data request, even if the site has no upload form at all.

We did two things:

  1. Disabled session.upload_progress.enabled in all PHP versions. This is the PHP project’s own recommendation; almost nobody uses the feature, and sites are not affected. Important: the value must be set in php.ini or in the pool configuration, not via ini_set() or .user.ini, otherwise it applies too late.
  2. Blocked multipart at the nginx level for all sites. In ispmanager every vhost includes /etc/nginx/vhosts-includes/*.conf, so a single file covers the whole server:
if ($http_content_type ~* "multipart") {
    return 403;
}

The price of the second measure: file uploads through forms, webmail attachments and imports in phpMyAdmin stop working. So this is a measure for hours, not days.

Two places that are easy to miss:

  • The default server in /etc/nginx/nginx.conf. It catches requests by IP or with an unknown Host and, in ispmanager, proxies them to Apache, but it does not include vhosts-includes. Without a separate include there, an attack by IP bypasses the block.
  • Apache on a public address. If Apache listens on a public IP rather than 127.0.0.1, a request can be sent straight to it, bypassing nginx. Check: ss -ltnp | grep httpd.

The CageFS trap: the panel setting never reaches the sites

During the day we disabled session.upload_progress.enabled the standard way: “Web server settings → PHP → version → settings”. The panel showed the value as saved. In the evening, a check from inside the CageFS cage showed it was still enabled for the sites.

The reason is how alt-php works on CloudLinux:

  • ispmanager wrote the value into /opt/alt/phpXX/etc/php.d.all/session.ini, the ini file of the session extension;
  • in alt-php the session extension is built in and is not loaded through PHP Selector, so nobody inside the cage reads that ini file;
  • inside the cage PHP reads the main /opt/alt/phpXX/etc/php.ini and the user’s alt_php.ini from /opt/alt/phpXX/link/conf, which is a different directory from what root sees.

Hence the main lesson: check PHP settings as the user inside the cage, not as root:

su -s /bin/bash -c "/opt/alt/php83/usr/bin/php -r 'var_dump(ini_get(\"session.upload_progress.enabled\"));'" CLIENT_LOGIN

What worked:

  1. Append the directive to the end of the php.ini each version actually loads (the path is shown by php --ini, line Loaded Configuration File).
  2. Run cagefsctl --rebuild-alt-php-ini to rebuild the users’ alt_php.ini files.
  3. Run cagefsctl --update: the native PHP inside the cage has its own copy of /etc/php.ini in the CageFS skeleton, and without updating the skeleton the change never reaches the sites.
  4. Don’t forget the per-site php.ini files for CGI mode: ispmanager keeps them in /var/www/USER/data/php-bin*/php.ini.
  5. Restart httpd and FPM.

One more detail: that same night at 03:37 something rebuilt the php.ini of every alt-php version from a template. If your change lives only in php.ini, back it up with a cron job that checks and restores the line until the patches arrive. We did exactly that, and cron did restore it several times, for example after the alt-php packages were updated.

The multipart block breaks the panel login

A couple of hours after the block went in, a client wrote that they could not log in to the panel: the login request got a 403 and the interface showed a loading spinner forever. Nobody had blocked the client’s IP.

The ispmanager panel runs on its own web server, ihttpd, on port 1500, and when you log in directly on that port nginx is indeed not involved. But if the nginx_proxy module is enabled, the panel is also reachable over 443 at https://HOST/ispmgr, and the login form is sent as multipart/form-data. Our block answered 403 in nginx, and the panel frontend cannot display that error.

The module is included only in the vhost of the panel host (/etc/nginx/modules-includes/nginx_proxy/), and all its paths go to ihttpd, not to PHP. So it is safe to make an exception for the combination of host and path:

set $cve_mp 0;
if ($http_content_type ~* "multipart") { set $cve_mp 1; }
set $cve_hu "$host:$uri";
if ($cve_hu ~* "^panel\.example\.com:/(ispmgr|mancgi|manimg|long|shell|notify)(/|$)") { set $cve_mp 0; }
if ($cve_mp = 1) { return 403; }

An exception by path alone, without the host, would be a mistake: a request to client-site/ispmgr would go to Apache, WordPress would rewrite it to index.php, and PHP would parse the multipart body. On the panel host this path is guaranteed to go to ihttpd.

Take the list of paths from the module itself (grep location /etc/nginx/modules-includes/nginx_proxy/*.conf), not from memory. And don’t test right after reloading nginx: the first requests may still be served by an old worker with the old configuration.

The forgotten Roundcube and phpMyAdmin

When the alt-php patches came out, we updated the packages and removed the block. Only then did we remember that webmail and phpMyAdmin in ispmanager run not on the PHP version you selected for the sites. Updating alt-php does not touch them.

Both applications are included through vhosts-includes, which means they are reachable on every domain on the server (/roundcube, /webmail, /phpmyadmin or a path with a random prefix). Which PHP runs them is shown by fastcgi_pass in these files:

grep -E 'location|fastcgi_pass' /etc/nginx/vhosts-includes/*roundcube*.conf /etc/nginx/vhosts-includes/*phpmyadmin*.conf

We found several variants across our servers:

ApplicationVia nginxVia Apache
Roundcube /roundcubenative PHP-FPM (php-fpm.apache.sock) or isp-php74isp-php74 via its own socket
Roundcube /webmailnative PHP-FPMmod_php
phpMyAdminnative PHP-FPMmod_php

The second column matters as much as the first. Apache receives these requests in two cases:

  • a request by IP or with an unknown Host goes through the nginx default server straight to Apache, where Alias /webmail and /phpmyadmin are global;
  • the nginx configuration for /webmail and /phpmyadmin has error_page 404 @apache and error_page 502 = @apache. A URL with PATH_INFO such as /webmail/index.php/x does not match location ~ \.php$, gets a 404 and goes to Apache, where mod_php executes it.

On one of the servers the native PHP was 5.4 from CentOS 7, which will never receive fixes. While we were moving these applications to alt-php, the multipart block stayed only on their paths, and the sites already worked without restrictions:

if ($uri !~* "^/(roundcube|webmail|phpmyadmin)(/|$)") { set $cve_mp 0; }

During that time clients could not attach files in webmail, and they noticed almost immediately.

Why the version number doesn’t change on CloudLinux

CloudLinux released fixes for all alt-php branches at once, from 5.4 to 8.5, but not as 8.3.36 or 8.4.27. They are new builds of the existing versions: alt-php83-8.3.35-6, alt-php84-8.4.26-5, alt-php85-8.5.11-5 and so on. The patch is applied to the installed version, and only the package release number goes up.

So check scripts that compare PHP_VERSION with 8.3.36 will keep reporting “vulnerable” after the update. And clients who look at the panel will see the same numbers and ask why nothing was updated. There are two reliable indicators.

The package changelog. For the old branches CloudLinux additionally removed the upload progress handler entirely:

for p in $(rpm -qa --qf '%{NAME}\n' 'alt-php[0-9]*' | grep -E '^alt-php(5[4-9]|[78][0-9])$' | sort -V); do
  printf '%-10s %-16s ' $p "$(rpm -q --qf '%{VERSION}-%{RELEASE}' $p)"
  rpm -q --changelog $p | head -10 | grep -c 'CVE-2026-10961[89]'
done

Build Date in phpinfo(). The fixed builds show 21 October 2026, the previous ones earlier dates. This is what you can tell clients: anyone can check it without server access.

Native PHP has the same story from the other side. On RHEL 9 and its rebuilds the fixed 8.0 version is php-8.0.30-8.el9_8.1 (Red Hat advisory RHSA-2026:87151), and in the changelog the CVE numbers ended up attached to the last item of the list, which has a completely different description. Without the advisory it is easy to mistake this for a routine update.

The ispmanager packages (isp-phpXX) have a template changelog with a single 2019 entry. The indicators there are indirect: the build number (for us 1781 for 8.2-8.5, 1782 for 7.4, 1786 for 7.1) and a Build Date of 22 October.

Pitfalls of the update itself

dnf --best --allowerasing on an ispmanager server. On CloudLinux 9, dnf update printed a long list of conflicts: the repository contains native PHP 8.3.36 from a module stream, and dnf considers it the best candidate for the installed 8.0. But the ispmanager Apache module (isp-httpd-mod_php) strictly requires PHP 8.0.x, and coremanager-pkg-php and ispmanager-pkg-php, that is the panel itself, depend on it. The dnf hint to add --best --allowerasing is dangerous here: it would remove the panel packages. The conflict is harmless, and dnf ends with Nothing to do. To silence it until the 8.0 build arrives: dnf update --exclude='php,php-*'.

ispmanager has its own Apache PHP module. It is loaded from modules/isp-libphp8.so and belongs to the isp-httpd-mod_php package, not to the system php package. The fixes for these CVEs live in the PHP core, that is inside the module itself, and updating the php package does not change it. Check:

grep -rhE 'LoadModule\s+php' /etc/httpd/conf.modules.d/ /etc/httpd/conf.d/
rpm -qf /etc/httpd/modules/isp-libphp8.so
strings /etc/httpd/modules/isp-libphp8.so | grep -m1 -E '[A-Z][a-z]{2} [ 0-9][0-9] 20[0-9]{2}'

If the module was built before 21 October, every site in “Apache module” mode stays vulnerable. To find them: grep -lE 'SetHandler\s+application/x-httpd-php\s*$' /etc/httpd/conf/vhosts/*/*. We moved such sites to alt-php, and where that was impossible (an interface that needs access outside CageFS), we restricted access by IP.

Disabled PHP is worse than enabled PHP. Some former mod_php sites turned out to be static, so we disabled PHP for them. On one of them, next to the placeholder page, there were 61 files of an old site, and with PHP disabled their source code, including a config with the database password, was served as plain text. Before disabling PHP, check: find DOCROOT -name '*.php*' | wc -l.

SSH dropping in the middle of a transaction. Updating 160 alt-php packages took several minutes, and the connection dropped. Luckily the transaction completed, but you have to verify: dnf history list, dnf check (on CentOS 7: package-cleanup --problems, package-cleanup --dupes). Run long updates inside tmux.

Quiet ispmanager rebuilds. The fixed isp-php packages arrived one at a time over a day: first 8.2-8.5, then 7.4, then 7.1. For CentOS 7 the 7.4 build had not appeared at the time of writing. It makes sense to check dnf check-update 'isp-php*' several times a day.

How to move Roundcube and phpMyAdmin to alt-php

On the server with native PHP 5.4 we moved the service FPM pool apache to alt-php56 while keeping the same socket. That way the nginx configuration does not change, and rolling back means simply starting the old service. Choosing 5.6 over 7.4 was simple: Roundcube 1.4 and the old phpMyAdmin ran on 5.4, 5.6 is the closest, and CloudLinux released a backport for it.

Steps:

  1. A dedicated ini directory. Outside CageFS, alt-php run by root loads only a minimal set of extensions; the rest live in php.d.all. We built a single extensions.ini from the required modules (session, json, dom, xml*, mbstring, intl, gd, mcrypt, zip, pdo, nd_mysql*). The CloudLinux ini files pull in their own dependencies, so duplicate extension= lines have to be removed.
  2. An FPM config with an apache pool on /var/run/php-fpm.apache.sock, the same user, group and listen.owner, and an explicit session.save_path, because it was not set in the native php.ini.
  3. A check before switching: PHP_INI_SCAN_DIR=… php -m without errors and php-fpm -t -y … reporting test is successful.
  4. A systemd unit with Environment=PHP_INI_SCAN_DIR=… and ExecStart=… php-fpm --nodaemonize -y ….
  5. The switch: rename /etc/php-fpm.d/apache.conf, restart the native FPM (it keeps the www pool), start the new one. A few seconds of downtime.
  6. Point Apache to the same socket. In roundcube-webmail.conf and phpmyadmin-httpd.conf replace SetHandler application/x-httpd-php with SetHandler "proxy:unix:/var/run/php-fpm.apache.sock|fcgi://localhost/", and in roundcube-isp.conf replace the isp-php74 socket. Make sure SetHandler is inside <FilesMatch "\.php$">, otherwise static files will go to FPM too.

Removing duplicate extensions from step 1:

awk '/^[[:space:]]*(zend_)?extension[[:space:]]*=/ { k=$0; gsub(/[[:space:]]/,"",k); if (seen[k]++) next } { print }' $FILES > conf.d/extensions.ini

Checking which PHP actually runs on each path, including a direct request to Apache and PATH_INFO:

echo '<?php echo PHP_VERSION, " ", php_sapi_name();' > /usr/share/roundcubemail/_v.php
curl -s -H 'Host: nonexistent.invalid' http://127.0.0.1:8080/webmail/_v.php
curl -sk https://DOMAIN/webmail/_v.php/x
rm -f /usr/share/roundcubemail/_v.php

Every line should say 5.6.40 fpm-fcgi. After that the nginx block can be removed.

Two downsides of this approach: on the Apache path the open_basedir restrictions from the mod_php configs are lost, and roundcube-isp.conf is marked by ispmanager as overwritten on package updates. After panel updates, check that the sockets have not reverted and that /etc/php-fpm.d/apache.conf has not reappeared.

Checklist for an ispmanager server

If you run a server with ispmanager and are not yet sure you have fully closed PHP2Shell, go through this list:

  • All alt-php branches in use are updated, and the changelog mentions CVE-2026-109618/109619 or the Build Date is 21 October 2026 or later.
  • The isp-php* packages are updated and the php-fpm* services restarted (after a unit file change, run systemctl daemon-reload first).
  • The OS native PHP is updated or serves nothing (check the pools in /etc/php-fpm.d/ and who connects to their sockets).
  • The Apache module isp-libphp8.so was built after 21 October, or no site runs in “Apache module” mode.
  • Roundcube and phpMyAdmin run on patched PHP both via nginx and via Apache.
  • PHP settings were checked as the user inside CageFS, not as root.
  • The CageFS skeleton is updated (cagefsctl --update).
  • Temporary nginx blocks are removed, including the line in the default server in nginx.conf.
  • Sites with PHP disabled contain no .php files.
  • Clients know why the version number in the panel did not change.

The main takeaway from that night is simple: on a hosting server with a control panel, “update PHP” means not one package but five or six different PHP builds from three vendors (upstream via CloudLinux, ispmanager, the distribution), and some of them serve not the sites but the panel’s own applications. It pays to know in advance which PHP sits behind which path, before you need to find out at night.

Sources

Free plugin: restrict wp-admin by country

Hosting, News, Security

We’d like to share a useful tool for anyone running WordPress sites.

Protect your WordPress admin from logins outside your country

We built a free plugin that blocks access to the admin panel for IP addresses from countries not on your allowed list.

What the plugin does

The plugin blocks access to wp-admin and wp-login.php for IP addresses from countries not in the allowed list. Frontend visitors, online store customers, and members area users are not affected — only the admin panel is restricted.

Download

block-access-to-admin-by-country.zip

Installation

  1. Download the zip archive using the link above
  2. In your WordPress dashboard, go to Plugins → Add New → Upload Plugin
  3. Select the downloaded archive and click Install Now, then Activate
  4. Go to Settings → Admin Country Block and set your allowed countries

Settings

  • Allowed countries — country codes, one per line (e.g. EE, FI, LV). Only IPs from these countries will have access to the admin panel.
  • Exception IPs — IP addresses that always have access regardless of country. Add your own IP here to avoid locking yourself out.
  • Cache TTL — how long the lookup result is cached per IP address (default: 24 hours).

For Core Hosting customers

On Core Hosting servers, the plugin automatically uses a local MaxMind GeoLite2 database — no external requests, fast and reliable. The database is updated weekly. No additional configuration is needed.

For sites on other hosting providers

he plugin uses a free geolocation API (freeipapi.com). You can also specify any other compatible API in the API URL field. Results are cached, so the number of API requests stays minimal.

The plugin supports automatic updates — new versions will appear in the standard WordPress updates section.

The plugin is free and open to everyone. If you run into any issues during installation or have questions, feel free to contact our support team.

Big Upgrades at Core.Hosting: New Hosting Features and Prices

Hosting, News

At Core.Hosting, we are constantly working to provide you with the most modern, fast, and reliable hosting solutions. For the past few months, we’ve been working hard on a major upgrade to our infrastructure. Today, we’re excited to share news about improvements to our packages that will give you even more resources and opportunities for your projects to grow.

Why Are We Making These Changes?

Our goal is your success. To ensure it, we are investing in the future:

  1. New Technology Platform: We are migrating users to a new, more powerful web hosting environment. This means faster site speeds, improved security, and better stability.
  2. More Resources: We have significantly increased disk space limits and added new professional tools (like SSH access and Node.js support) to popular packages.
  3. Standardization and Transparency: We are updating and unifying our pricing policy to make it clearer and fairer for all clients. These changes also coincide with the planned VAT increase in Estonia from 22% to 24%.

What’s New in the Packages?

Our Simple, Basic, and Pro packages have become even more powerful. Here are the key improvements:

FeatureSimple (New)Basic (New)Pro (New)
NVMe Disk64 GB128 GB256 GB
Websites135
Email Accounts10UnlimitedUnlimited
DNS Service5 Domains10 Domains15 Domains
Cron Jobs2610
SSH Access–YesYes
Node.js, Python–YesYes
Priority Support––Yes

Updated Prices from July 1, 2025

The new prices reflect the increased value of the packages and the updated VAT rate.

PackageMonthly Price (€)Annual Plan Price (€/mo)
Simple7.505.63
Basic12.509.38
Pro19.5014.63
Developer69.5063.71

Prices are exclusive of 24% VAT.

What Does This Mean for Existing Clients?

  • Pricing: The new prices will take effect on July 1, 2025. If you are already on these prices, nothing will change for you. For all prepaid periods, the old prices will remain valid until they expire.
  • Migration: We will smoothly migrate all Simple, Basic, and Pro users to the new platform by May 2026. We will handle all the technical details to ensure the transition is seamless for you.

We are confident that these updates will help you reach new heights. Thank you for being with us!

The Core.Hosting Team

Why Choose Core.Hosting for Your Website and Email

Hosting, News

When choosing a hosting provider, it’s important to consider more than just the price. At Core.Hosting, we focus on flexibility, ease of use, and built-in security — all included in every plan.

✅ Flexibility Without Extra Fees

Some websites still rely on older PHP versions — and that’s totally fine. We support PHP from 5.2 to 8.4, with no extra charge. Perfect for legacy projects or gradual migrations.

🔒 Built-In Security

Every hosting package includes ImunifyAV+, an advanced malware scanner that automatically detects and cleans malicious code — no manual setup needed.

⚙️ One-Click Installation for Popular Apps

WordPress, Joomla, OpenCart, and many others — easily installed with just a few clicks via our app installer.

🧱 Site Builder Included

All plans include Site.pro, a drag-and-drop site builder. No coding required, no hidden fees.

🚚 Free Website and Email Migration

Switching hosts? We’ll move your website and email for free, making the transition smooth and worry-free.

👨‍💻 Real Support That Cares

Our support team is available daily from 9:00 to 19:00 and ready to help — no bots, no copy-paste answers.


Core.Hosting isn’t just about hosting — it’s about making your online presence easier to manage and more secure.

🔗 Learn more: https://core.eu/en/hosting/shared/

How to quickly deploy a website for your project?

Hosting

So, you already have an idea for your project. You bought a domain with a suitable name and are planning to create a website for the project in the near future.

We will tell you how to create your ideal web resource on CORE hosting.

The CORE Hosting control panel ISP Manager allows you to install popular CMS in a couple of clicks or create a website using the Site.pro page builder.

Convenience of Working with ISP Manager

User-Friendly Interface
ISP Manager is renowned for its simple and logical interface, making it accessible not only for experienced administrators but also for beginners. All functions are conveniently organized, allowing you to quickly find the necessary tools.

Multifunctionality
The control panel allows you to manage not only websites but also mailboxes, databases, domain names, and other resources. This makes ISP Manager a universal tool for administration.

Quick Installation of Popular CMS
ISP Manager simplifies working with the installation of various content management systems (CMS), including:

  • WordPress: An easy-to-use tool for creating blogs and websites.
  • Drupal: A powerful system for creating complex and multifunctional sites.
  • Joomla: Ideal for creating social networks and corporate portals.
  • PrestaShop and Magento: Great choices for building online stores with numerous features.

One can install these CMS with just a few clicks, thanks to built-in wizards and automatic configurations.

To install a CMS script for a site in ISP Manager:

  1. In the Main menu, select “Sites”.
  2. In the form that opens, select the site for which you want to install the script and click the “CMS” button.

You can install with default parameters (the “Quick Install” button) or configure the parameters yourself (the “Install” button).

 

Website Builder Site.pro

Now, let’s talk about the Site.pro website builder, which is an excellent addition to ISP Manager.

Ease of Use
Site.pro provides an intuitive drag-and-drop interface, allowing users without technical skills to create a professional website in a short time.

Templates and Designs
The builder offers numerous ready-made templates that can easily be customized to suit your needs. This significantly speeds up the website development process.

Mobile Responsiveness
All created websites automatically adapt to mobile devices, ensuring convenience for users.

Integration with Various Services
Site.pro supports integration with popular services and tools, including social networks, payment systems, and analytics tools.

Free Access
One of the main advantages is free access to the builder. You can start creating your site without any costs.

At Core.Hosting we offer all the tools you need for successful online project implementation regardless of your needs and skill level.