On 21 October 2026 the PHP project published two critical vulnerabilities, CVE-2026-109618 and CVE-2026-109619, that can allow remote code execution on a web server without logging in. We wrote more about the incident on our website here: https://www.smseagle.eu/security-advisory/security-advisory-critical-vulnerabilities-in-php-cve-2026-109618-cve-2026-109619/
This article explains how to change the configuration of your SMSEagle gateway to reduce that risk until the gateway receives an updated PHP package.
The only complete fix for CVE-2026-109618 and CVE-2026-109619 is an updated PHP package. SMSEagle software 7.0.2 and newer includes updated PHP packages with the fix, so the recommended solution is to update your gateway to version 7.0.2 or newer.
The changes described in this article are an interim measure for gateways that cannot be updated to 7.0.2 yet. They close the attack paths confirmed by the PHP project and make the remaining ones harder to use, but they do not remove the vulnerabilities from PHP itself.
The changes affect only the PHP, Apache and systemd configuration. They do not change any SMSEagle data or settings. A copy of every changed file is kept, so the changes can be undone at any time.
What changes for users
- Requests larger than 32 MB are rejected. Uploads of voice models, patches, backups and firmware still accept up to 300 MB.
- The web interface and the API restart once, for a few seconds.
Before you start
- You need SSH access to the gateway as root.
- Each grey box contains one command. Copy and run them one by one, in order, in the same terminal session. Step 1 stores the backup location in a variable that later steps use.
- Do not apply the changes while a backup is being restored or a report is being exported. The restart in step 6 interrupts them.
- Instead of running the commands yourself, you can install the patch file
patch-20261021-php.binin the web interface. It makes exactly the same changes. See Optional: install the patch file instead. Use only one of the two methods.
Apply the changes manually
Step 1. Back up the files that will change
Copies the original PHP, Apache and systemd configuration files into a new folder under /etc, keeping their full paths. The last command prints the folder name. Write it down: you need it if you ever want to undo the changes.
shopt -s nullglob
BACKUP=/etc/patch-20261021-php-backup-$(date +%Y%m%d-%H%M%S)
mkdir -p "$BACKUP"
cp -a --parents /etc/php/*/fpm/php.ini /etc/php/*/apache2/php.ini /etc/php/*/cgi/php.ini /etc/php/*/fpm/pool.d/*.conf /etc/systemd/system/php*-fpm.service.d/override.conf /etc/apache2/apache2.conf "$BACKUP/"
echo "$BACKUP"
Step 2. Change the PHP settings
Sets three values in every php.ini used by the web interface, replacing the existing or commented-out line in place:
-
session.upload_progress.enabled = 0switches off the session upload progress feature, the confirmed attack path of CVE-2026-109619. The SMSEagle web interface does not use it. -
memory_limit = -1removes the PHP memory limit, so that a request cannot hit the out-of-memory error behind CVE-2026-109618. Step 5 adds a memory cap for the whole service instead. -
max_input_nesting_level = 32limits how deeply nested form field names can be (default 64). SMSEagle forms use at most 5 levels.
for f in /etc/php/*/fpm/php.ini /etc/php/*/apache2/php.ini /etc/php/*/cgi/php.ini; do sed -i -e 's/^;\?\s*session\.upload_progress\.enabled\s*=.*/session.upload_progress.enabled = 0/' -e 's/^;\?\s*memory_limit\s*=.*/memory_limit = -1/' -e 's/^;\?\s*max_input_nesting_level\s*=.*/max_input_nesting_level = 32/' "$f"; echo "updated $f"; done
Step 3. Lock the settings in the PHP-FPM pools
Applies only to gateways where PHP runs as PHP-FPM. To check, run:
systemctl list-units 'php*-fpm.service' --no-legend
If it prints a line such as php8.1-fpm.service loaded active running, the gateway uses PHP-FPM: run the commands below. If it prints nothing, PHP runs inside Apache and you can skip to step 4. Running the commands below on such a gateway is also safe: they print nothing and change nothing.
The commands add the same three settings to every PHP-FPM pool as php_admin values, which the application cannot change at run time. The API pool also gets a 32 MB request size limit, because the API does not accept file uploads.
for f in /etc/php/*/fpm/pool.d/*.conf; do printf '%s\n' "php_admin_flag[session.upload_progress.enabled] = off" "php_admin_value[memory_limit] = -1" "php_admin_value[max_input_nesting_level] = 32" >>"$f"; echo "updated $f"; done
for f in /etc/php/*/fpm/pool.d/api.conf; do printf '%s\n' "php_admin_value[post_max_size] = 32M" "php_admin_value[upload_max_filesize] = 30M" >>"$f"; done
Step 4. Limit the request size in Apache
Adds these lines to the end of /etc/apache2/apache2.conf (each quoted part of the command becomes one line in the file):
- A request that declares a body larger than 32 MB is rejected by Apache with HTTP 403 before PHP receives it. This is the
<If>block, and it is what protects gateways where PHP runs as PHP-FPM. -
LimitRequestBodyapplies the same 32 MB limit where Apache reads the request itself (static files, and PHP running inside Apache). It rejects larger requests with HTTP 413. - The upload pages for voice models, patches, backup restore and firmware accept up to 300 MB.
- On gateways where PHP runs inside Apache (mod_php), the memory limit is locked so the application cannot change it.
printf '%s\n' 'LimitRequestBody 33554432' '<LocationMatch "^/(index\.php/)?(settings/calls/voices/upload|system/patches/upload|system/backup/restore|calls/upload_voice|kalkun/upload/patch|kalkun/upload/update|kalkun/restore_backup)(/.*)?$">' 'LimitRequestBody 314572800' '</LocationMatch>' '<If "%{HTTP:Content-Length} -gt 33554432 && ! %{REQUEST_URI} =~ m#^/(index\.php/)?(settings/calls/voices/upload|system/patches/upload|system/backup/restore|calls/upload_voice|kalkun/upload/patch|kalkun/upload/update|kalkun/restore_backup)(/.*)?$#">' 'Require all denied' '</If>' '<IfModule php7_module>' 'php_admin_value memory_limit -1' '</IfModule>' '<IfModule php_module>' 'php_admin_value memory_limit -1' '</IfModule>' >>/etc/apache2/apache2.confStep 5. Cap the memory used by PHP
Because step 2 removes the PHP memory limit, this step limits all PHP-FPM processes and all Apache processes to half of the gateway's memory. If one request uses too much memory, the system stops only that process and the web interface keeps running. OOMPolicy=continue keeps the service running after such an event. Older systems (systemd before version 243) ignore that line, which is harmless.
MEM=MemoryLimit
[ "$(stat -fc %T /sys/fs/cgroup)" = "cgroup2fs" ] && MEM=MemoryMax
for f in /etc/systemd/system/php*-fpm.service.d/override.conf; do printf '%s\n' "$MEM=50%" "OOMPolicy=continue" >>"$f"; done
mkdir -p /etc/systemd/system/apache2.service.d
printf '%s\n' "[Service]" "$MEM=50%" "OOMPolicy=continue" >/etc/systemd/system/apache2.service.d/override.conf
Step 6. Check the configuration and restart
The first command must print Syntax OK. If it prints an error, do not run the next commands. Restore the backup as described in How to undo the changes. The restart interrupts the web interface and the API for a few seconds.
apache2ctl -t
systemctl daemon-reload
systemctl try-restart 'php*-fpm.service' apache2.service
Continue with Verify the changes.
Optional: install the patch file instead
The patch file patch-20261021-php.bin makes exactly the same changes as the manual steps above, including the backup. Use it instead of the manual steps, not in addition to them.
- Download
patch-20261021-php.binand save it on your computer. Do not unpack or rename it. - Log in to the gateway web interface as an administrator and open the patches page:
- Software 7.0.0 and newer: System > Patches in the menu.
-
Software older than 7.0.0: the page is not in the menu. Type its address in the browser:
https://<gateway address>/patches, for examplehttps://192.168.1.101/patches.
- In Patch file for manual install select
patch-20261021-php.binand click Upload. - Click Install now and confirm with Install. The page shows the installation output line by line. Do not power off or unplug the gateway during the install. The output ends with
Patch applied, original files saved in /etc/patch-20261021-php-backup-…. Write down that folder name: you need it if you ever want to undo the changes. - About 10 seconds after the install, the web server and PHP restart and the page stops responding for a moment. The page does not reload by itself. Wait about 30 seconds, refresh the page and log in again.
Verify the changes
Run these commands over SSH:
head -c 40M /dev/zero | curl -sk -o /dev/null -w '%{http_code}\n' --data-binary @- https://127.0.0.1/tail -n 1 /var/log/apache2/error.log
systemctl is-active apache2 'php*-fpm'
- The first command sends a 40 MB request to the gateway. It must print
403or413. - The second command shows the last Apache error log entry. It must contain
client denied by server configuration. Together with the first result, this shows that Apache rejected the request before PHP received it. A403without that log entry comes from the web application, which means the limit is not active. - The third command must print
activefor Apache and, if present, for PHP-FPM.
Then open the web interface and log in to confirm it works.
How to undo the changes
This works for both methods and needs SSH access as root. Use the backup folder name you wrote down: the patch prints it at the end of the install, and the manual procedure prints it in step 1. After the patch install the folder also contains a README.txt that lists every file and where it belongs.
Replace YYYYMMDD-HHMMSS below with the date and time from the folder name. The commands remove the file that step 5 created, copy the original files back and restart the gateway.
cd /etc/patch-20261021-php-backup-YYYYMMDD-HHMMSS
rm -f /etc/systemd/system/apache2.service.d/override.conf
cp -a etc/. /etc/
reboot