[{"data":1,"prerenderedAt":1675},["ShallowReactive",2],{"\u002Fblog\u002Fphp2shell-php-vulnerability":3},{"id":4,"title":5,"author":6,"body":7,"date":1664,"description":1665,"extension":1666,"meta":1667,"navigation":1668,"path":1669,"readingTime":1670,"seo":1671,"stem":1672,"tag":1673,"updated":1664,"__hash__":1674},"blog\u002Fblog\u002Fphp2shell-php-vulnerability.md","PHP2Shell: the PHP vulnerability and how to fix your server","Madhumita S",{"type":8,"value":9,"toc":1651},"minimark",[10,22,25,28,31,77,82,85,101,110,125,129,132,237,258,273,276,280,286,344,347,377,381,386,402,429,432,462,465,469,472,989,1006,1010,1013,1033,1036,1080,1083,1091,1095,1098,1110,1143,1173,1176,1253,1285,1288,1292,1301,1332,1338,1342,1345,1352,1360,1365,1393,1414,1439,1446,1454,1458,1477,1480,1601,1604,1613,1617,1620,1629,1632,1639,1647],[11,12,13,14,21],"p",{},"PHP2Shell is a pair of critical bugs in PHP itself, CVE-2026-109618 and CVE-2026-109619, that can let an attacker with no account run code on a server that uses PHP to answer web requests. The fix is PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35, released on October 21, 2026, or your Linux distribution's patched package, followed by a restart of every PHP process. Attackers were probing for the bugs before the patches were out, and on October 26 CISA added both to its ",[15,16,20],"a",{"href":17,"rel":18},"https:\u002F\u002Fwww.cisa.gov\u002Fknown-exploited-vulnerabilities-catalog",[19],"nofollow","catalog of known exploited vulnerabilities",".",[11,23,24],{},"Updating WordPress, Laravel or a plugin won't fix it, because the bugs are in the PHP runtime underneath them.",[11,26,27],{},"This guide is for whoever looks after a PHP server: a developer, a small team's part-time sysadmin, or the owner of a WordPress site on a VPS. We checked every fact in it against PHP's advisories and the original research on October 30, 2026. The story is still moving, so the linked sources are worth a look if you're reading this later.",[11,29,30],{},"The short version:",[32,33,34,47,54,61,71],"ol",{},[35,36,37,41,42,46],"li",{},[15,38,40],{"href":39},"#step-1-find-the-php-that-actually-serves-your-site","Find the PHP version that actually serves each site",", not the one ",[43,44,45],"code",{},"php -v"," reports.",[35,48,49,53],{},[15,50,52],{"href":51},"#step-2-install-the-fixed-php-from-wherever-yours-came-from","Install 8.5.12, 8.4.27, 8.3.36 or 8.2.35",", or your distribution's fixed package.",[35,55,56,60],{},[15,57,59],{"href":58},"#step-3-restart-every-php-process-then-check-again","Restart every PHP process"," and check the version again.",[35,62,63,70],{},[15,64,66,67],{"href":65},"#if-you-cant-update-today-the-stopgaps-and-their-limits","Turn off ",[43,68,69],{},"session.upload_progress"," unless a site uses it.",[35,72,73,21],{},[15,74,76],{"href":75},"#check-whether-anyone-got-in-before-you-patched","Check your logs from October 17 onward",[78,79,81],"h2",{"id":80},"what-php2shell-is","What PHP2Shell is",[11,83,84],{},"Both bugs come from the same place: what PHP does when a request is interrupted part-way through.",[11,86,87,88,93,94,97,98,21],{},"The first, CVE-2026-109618, is in out-of-memory handling. When PHP runs out of memory, it jumps straight out of whatever it was doing. ",[15,89,92],{"href":90,"rel":91},"https:\u002F\u002Fgithub.com\u002Fphp\u002Fphp-src\u002Fsecurity\u002Fadvisories\u002FGHSA-w8hw-w9fx-j79w",[19],"PHP's advisory"," explains that at some points, for example while PHP is still parsing an uploaded form, that jump leaves the request's internal data half-built, and the cleanup that runs afterwards treats it as valid. An attacker can cause this on purpose. Each part of a multipart upload can carry any number of headers, and those take far more memory inside PHP than on the wire, so a request well under ",[43,95,96],{},"post_max_size"," can still exhaust ",[43,99,100],{},"memory_limit",[11,102,103,104,109],{},"The second, CVE-2026-109619, is about state that outlives its request. A PHP worker handles one request after another, and some of its internal error, session and extension state can point into memory owned by the previous request. If a request dies before that state is reset, ",[15,105,108],{"href":106,"rel":107},"https:\u002F\u002Fgithub.com\u002Fphp\u002Fphp-src\u002Fsecurity\u002Fadvisories\u002FGHSA-6wmf-4rv5-p3rp",[19],"the next request on the same worker can use it"," after the memory has been freed. With a carefully arranged heap, that leads to running code, and on the way it can leak memory contents to the attacker.",[11,111,112,113,118,119,124],{},"PHP rates both 9.2 out of 10 on CVSS v4. The 10.0 that circulated before the release was wrong, ",[15,114,117],{"href":115,"rel":116},"https:\u002F\u002Fthephp.foundation\u002Fblog\u002F2026\u002F10\u002F21\u002Ftodays-php-security-release-and-how-were-strengthening-php-security\u002F",[19],"according to the PHP Foundation",". Calif, the security firm that reported the first bug on August 11, says ",[15,120,123],{"href":121,"rel":122},"https:\u002F\u002Fcalif.io\u002Fphp2shell\u002F",[19],"the earliest affected code dates back to PHP 5.4.0",". Wiz reported another attack path on August 24 and OpenAI reported more on September 18.",[78,126,128],{"id":127},"how-the-release-went-and-how-worried-to-be","How the release went, and how worried to be",[11,130,131],{},"The fix was meant to ship on October 22. It came a day early because details started leaking:",[133,134,135,148],"table",{},[136,137,138],"thead",{},[139,140,141,145],"tr",{},[142,143,144],"th",{},"Date (2026, UTC)",[142,146,147],{},"What happened",[149,150,151,160,174,188,196,209,221,229],"tbody",{},[139,152,153,157],{},[154,155,156],"td",{},"August 11",[154,158,159],{},"Calif reports the first bug to PHP.",[139,161,162,165],{},[154,163,164],{},"October 17",[154,166,167,168,173],{},"Amazon's honeypots log the ",[15,169,172],{"href":170,"rel":171},"https:\u002F\u002Faws.amazon.com\u002Fblogs\u002Fsecurity\u002Famazon-threat-intelligence-identifies-php2shell-exploitation-prior-to-public-disclosure-in-madpot\u002F",[19],"first exploit attempt",", four days before disclosure.",[139,175,176,179],{},[154,177,178],{},"October 20, ~15:00",[154,180,181,182,187],{},"The two CVE numbers circulate on forums and social media. PHP posts its ",[15,183,186],{"href":184,"rel":185},"https:\u002F\u002Fwww.php.net\u002Farchive\u002F2026.php#2026-10-20-1",[19],"advance notice"," at 19:30.",[139,189,190,193],{},[154,191,192],{},"October 21, 07:41",[154,194,195],{},"Chainguard publishes patched images, six hours before the coordinated release.",[139,197,198,201],{},[154,199,200],{},"October 21, 14:00",[154,202,203,204,21],{},"PHP releases ",[15,205,208],{"href":206,"rel":207},"https:\u002F\u002Fwww.php.net\u002Farchive\u002F2026.php#2026-10-21-5",[19],"8.5.12, 8.4.27, 8.3.36 and 8.2.35",[139,210,211,214],{},[154,212,213],{},"October 23",[154,215,216,217,21],{},"PHP warns of a third, unpatched issue, ",[15,218,220],{"href":219},"#cve-2026-115560-the-october-releases-dont-fix-this-one","CVE-2026-115560",[139,222,223,226],{},[154,224,225],{},"October 24",[154,227,228],{},"A researcher confirms 35 successful attacks on deliberately weak honeypots.",[139,230,231,234],{},[154,232,233],{},"October 26",[154,235,236],{},"CISA lists both CVEs as exploited; US federal civilian agencies had until October 29 to act.",[11,238,239,240,245,246,251,252,257],{},"So far there are far more attempts than confirmed break-ins. Fastly counted ",[15,241,244],{"href":242,"rel":243},"https:\u002F\u002Fwww.fastly.com\u002Fblog\u002Fhow-fastly-detected-and-built-a-coordinated-response-to-php2shell",[19],"about 250,000 requests"," from PHP2Shell tools, from about 3,200 IP addresses, by midday on October 22. Wordfence, which protects more than 5 million WordPress sites, logged about 77,600 related requests from over 2,000 addresses between October 23 and 27. As of October 28 it ",[15,247,250],{"href":248,"rel":249},"https:\u002F\u002Fwww.wordfence.com\u002Fblog\u002F2026\u002F10\u002Fphp2shell-update-still-no-confirmed-wordpress-compromises-and-answers-to-the-questions-were-hearing-most\u002F",[19],"knew of no WordPress site compromised"," this way. Sophos ",[15,253,256],{"href":254,"rel":255},"https:\u002F\u002Fwww.sophos.com\u002Fen-us\u002Fblog\u002Fproof-of-concept-exploit-released-for-php-vulnerabilities-109618-109619",[19],"claimed one successful attack on October 22 and retracted it"," the same evening.",[11,259,260,261,266,267,272],{},"The confirmed successes are narrower. Researcher Adel Karimi ",[15,262,265],{"href":263,"rel":264},"https:\u002F\u002Fgithub.com\u002F0x4D31\u002Fhoneypot-data\u002Fblob\u002Fmain\u002Freports\u002Fphp2shell\u002F2026-10-24-confirmed-rce.md",[19],"recorded 35 shells started by Apache"," on honeypots running PHP 8.4.26 under single-worker mod_php, a setup he describes as \"intentionally favorable\". Palo Alto Networks reports ",[15,268,271],{"href":269,"rel":270},"https:\u002F\u002Fsecurity.paloaltonetworks.com\u002FCVE-2026-109618",[19],"active exploitation of PAN-OS firewalls"," whose management interface is exposed to the internet. On October 26, Dream reported a chained attack using a tailored PHP2Shell exploit and a Linux kernel flaw to compromise 24 internet-facing firewalls and an internal management server; on October 28, Morphisec reported code execution on a customer Windows\u002FIIS server running PHP-CGI. Neither report publishes enough technical detail to verify independently, and neither involves WordPress.",[11,274,275],{},"Our read: a reliable exploit is hard to build. Wordfence says the public exploit code it, Wiz and Hacktron reviewed \"generally needed changes for the server being targeted\". That buys you days, not safety. Exploits get better, and on mod_php the attack doesn't depend on your application at all. Treat this as a job for today.",[78,277,279],{"id":278},"which-setups-are-most-exposed","Which setups are most exposed",[11,281,282,285],{},[15,283,92],{"href":206,"rel":284},[19]," covers every installation that serves web requests, and the two GitHub advisories go further, setup by setup:",[133,287,288,298],{},[136,289,290],{},[139,291,292,295],{},[142,293,294],{},"How PHP runs",[142,296,297],{},"What PHP's advisories say",[149,299,300,308,320,328,336],{},[139,301,302,305],{},[154,303,304],{},"Apache with mod_php",[154,306,307],{},"Highest risk. Unauthenticated code execution was demonstrated over HTTP with default limits, before any application code runs.",[139,309,310,317],{},[154,311,312,313,316],{},"PHP-FPM (Nginx, or Apache with ",[43,314,315],{},"proxy_fcgi",")",[154,318,319],{},"FPM ends a worker whose startup fails, which blocks the pre-application path. Code execution through session upload progress (CVE-2026-109619) was still demonstrated, and Calif shows a working exploit against Nginx with PHP-FPM.",[139,321,322,325],{},[154,323,324],{},"FrankenPHP",[154,326,327],{},"Likely open to the attack that doesn't need application code, judging from PHP's reading of the source.",[139,329,330,333],{},[154,331,332],{},"LiteSpeed (LSAPI)",[154,334,335],{},"Built like FPM. Exploitation through application code is likely but unproven.",[139,337,338,341],{},[154,339,340],{},"php-cgi",[154,342,343],{},"Listed as at risk; no separate analysis.",[11,345,346],{},"Two groups of people can't fix this on their own servers:",[348,349,350,365],"ul",{},[35,351,352,356,357,360,361,364],{},[353,354,355],"strong",{},"Shared and managed hosting."," Your host controls PHP, and you can't apply the stopgaps below yourself, because ",[43,358,359],{},".user.ini"," and ",[43,362,363],{},"ini_set()"," take effect too late. Wordfence suggests asking your host exactly this: \"Is the PHP service serving my site patched for CVE-2026-109618 and CVE-2026-109619, and has PHP been restarted?\" In WordPress, Tools › Site Health › Info › Server shows the PHP version your site really runs.",[35,366,367,370,371,376],{},[353,368,369],{},"Appliances with PHP inside."," Firewalls and gateways often run PHP behind their web interface. Cisco lists ",[15,372,375],{"href":373,"rel":374},"https:\u002F\u002Fsec.cloudapps.cisco.com\u002Fsecurity\u002Fcenter\u002Fcontent\u002FCiscoSecurityAdvisory\u002Fcisco-sa-php-october26-Jj384Daq",[19],"five affected product rows",", including Expressway and Duo Access Gateway, and Palo Alto lists PAN-OS. Those need the vendor's update, not a PHP package, so check the advisories for anything you run that has a web admin panel.",[78,378,380],{"id":379},"step-1-find-the-php-that-actually-serves-your-site","Step 1: find the PHP that actually serves your site",[11,382,383,385],{},[43,384,45],{}," tells you about the command-line PHP. The web server can be running a different one: a separate FPM package, an older version kept for one site, a container image, or a copy bundled with a control panel. Ask the web server instead. Put a file with a random name in the site's web root:",[387,388,393],"pre",{"className":389,"code":390,"language":391,"meta":392,"style":392},"language-php shiki shiki-themes github-light github-dark","\u003C?php echo PHP_VERSION, ' ', PHP_SAPI;\n","php","",[43,394,395],{"__ignoreMap":392},[396,397,400],"span",{"class":398,"line":399},"line",1,[396,401,390],{},[11,403,404,405,408,409,412,413,416,417,420,421,424,425,428],{},"Open it in a browser, note the result, and delete the file. ",[43,406,407],{},"PHP_SAPI"," tells you how PHP runs: ",[43,410,411],{},"apache2handler"," is mod_php, ",[43,414,415],{},"fpm-fcgi"," is PHP-FPM, ",[43,418,419],{},"litespeed"," is LSAPI, ",[43,422,423],{},"frankenphp"," is FrankenPHP and ",[43,426,427],{},"cgi-fcgi"," is CGI or FastCGI.",[11,430,431],{},"One server can run several PHP versions, so check every site. From a shell, these list what's installed and running:",[387,433,437],{"className":434,"code":435,"language":436,"meta":392,"style":392},"language-sh shiki shiki-themes github-light github-dark","ps -eo user,args | grep -E '[p]hp-fpm|[l]sphp|[f]rankenphp'  # PHP processes\napachectl -M 2>\u002Fdev\u002Fnull | grep -i php                      # mod_php loaded?\ndpkg -l 'php*' | grep '^ii'                                 # Debian, Ubuntu\nrpm -qa 'php*'                                              # RHEL, AlmaLinux, Rocky\n","sh",[43,438,439,444,450,456],{"__ignoreMap":392},[396,440,441],{"class":398,"line":399},[396,442,443],{},"ps -eo user,args | grep -E '[p]hp-fpm|[l]sphp|[f]rankenphp'  # PHP processes\n",[396,445,447],{"class":398,"line":446},2,[396,448,449],{},"apachectl -M 2>\u002Fdev\u002Fnull | grep -i php                      # mod_php loaded?\n",[396,451,453],{"class":398,"line":452},3,[396,454,455],{},"dpkg -l 'php*' | grep '^ii'                                 # Debian, Ubuntu\n",[396,457,459],{"class":398,"line":458},4,[396,460,461],{},"rpm -qa 'php*'                                              # RHEL, AlmaLinux, Rocky\n",[11,463,464],{},"One catch: distributions keep the old version number. Debian, Ubuntu and Red Hat patch the PHP version they originally shipped, so a fully patched system can still print an older number. On those systems, compare the package version against your distribution's advisory in the table below, not the number PHP prints.",[78,466,468],{"id":467},"step-2-install-the-fixed-php-from-wherever-yours-came-from","Step 2: install the fixed PHP from wherever yours came from",[11,470,471],{},"The version in the table is the minimum fixed package for the release named. If your package manager offers a later build, take it. If PHP came from a third-party repo, a control panel such as cPanel or Plesk, or a vendor container, the distribution row does not apply: wait for that vendor's fixed build, or move to the distribution or upstream build. Do not assume an old-looking version is safe just because it has a recent build date.",[133,473,474,487],{},[136,475,476],{},[139,477,478,481,484],{},[142,479,480],{},"Where PHP came from",[142,482,483],{},"Minimum fixed package version",[142,485,486],{},"Advisory and update",[149,488,489,510,528,547,564,581,598,627,664,691,716,736,756,773,790,807,825,845,868,911,931,971],{},[139,490,491,494,499],{},[154,492,493],{},"Debian 13 (trixie)",[154,495,496],{},[43,497,498],{},"php8.4 8.4.27-1~deb13u1",[154,500,501,506,507],{},[15,502,505],{"href":503,"rel":504},"https:\u002F\u002Fsecurity-tracker.debian.org\u002Ftracker\u002FCVE-2026-109618",[19],"DSA-6574-1","; ",[43,508,509],{},"sudo apt update && sudo apt full-upgrade",[139,511,512,515,520],{},[154,513,514],{},"Debian 12 (bookworm)",[154,516,517],{},[43,518,519],{},"php8.2 8.2.35-1~deb12u1",[154,521,522,506,526],{},[15,523,525],{"href":503,"rel":524},[19],"DLA-4848-1",[43,527,509],{},[139,529,530,533,538],{},[154,531,532],{},"Ubuntu 26.10",[154,534,535],{},[43,536,537],{},"php8.5 8.5.9-0ubuntu2.1",[154,539,540,506,545],{},[15,541,544],{"href":542,"rel":543},"https:\u002F\u002Fubuntu.com\u002Fsecurity\u002Fnotices\u002FUSN-8948-1",[19],"USN-8948-1",[43,546,509],{},[139,548,549,552,557],{},[154,550,551],{},"Ubuntu 26.04 LTS",[154,553,554],{},[43,555,556],{},"php8.5 8.5.4-0ubuntu1.5",[154,558,559,506,562],{},[15,560,544],{"href":542,"rel":561},[19],[43,563,509],{},[139,565,566,569,574],{},[154,567,568],{},"Ubuntu 24.04 LTS",[154,570,571],{},[43,572,573],{},"php8.3 8.3.6-0ubuntu0.24.04.13",[154,575,576,506,579],{},[15,577,544],{"href":542,"rel":578},[19],[43,580,509],{},[139,582,583,586,591],{},[154,584,585],{},"Ubuntu 22.04 LTS",[154,587,588],{},[43,589,590],{},"php8.1 8.1.2-1ubuntu2.28",[154,592,593,506,596],{},[15,594,544],{"href":542,"rel":595},[19],[43,597,509],{},[139,599,600,603,611],{},[154,601,602],{},"RHEL 10",[154,604,605,360,608],{},[43,606,607],{},"php 8.3.36-1.el10_2",[43,609,610],{},"php8.4 8.4.27-1.el10_2",[154,612,613,618,619,506,624],{},[15,614,617],{"href":615,"rel":616},"https:\u002F\u002Faccess.redhat.com\u002Ferrata\u002FRHSA-2026:87070",[19],"RHSA-2026:87070",", ",[15,620,623],{"href":621,"rel":622},"https:\u002F\u002Faccess.redhat.com\u002Ferrata\u002FRHSA-2026:87071",[19],"RHSA-2026:87071",[43,625,626],{},"sudo dnf update --security",[139,628,629,632,645],{},[154,630,631],{},"RHEL 9",[154,633,634,506,637,640,641,644],{},[43,635,636],{},"php 8.0.30-8.el9_8.1",[43,638,639],{},"php:8.2"," stream at 8.2.35; ",[43,642,643],{},"php:8.3"," stream at 8.3.36",[154,646,647,618,652,618,657,506,662],{},[15,648,651],{"href":649,"rel":650},"https:\u002F\u002Faccess.redhat.com\u002Ferrata\u002FRHSA-2026:87151",[19],"RHSA-2026:87151",[15,653,656],{"href":654,"rel":655},"https:\u002F\u002Faccess.redhat.com\u002Ferrata\u002FRHSA-2026:87072",[19],"RHSA-2026:87072",[15,658,661],{"href":659,"rel":660},"https:\u002F\u002Faccess.redhat.com\u002Ferrata\u002FRHSA-2026:87079",[19],"RHSA-2026:87079",[43,663,626],{},[139,665,666,669,677],{},[154,667,668],{},"RHEL 8",[154,670,671,640,673,676],{},[43,672,639],{},[43,674,675],{},"php:7.4"," stream at 7.4.33-8",[154,678,679,618,684,506,689],{},[15,680,683],{"href":681,"rel":682},"https:\u002F\u002Faccess.redhat.com\u002Ferrata\u002FRHSA-2026:87073",[19],"RHSA-2026:87073",[15,685,688],{"href":686,"rel":687},"https:\u002F\u002Faccess.redhat.com\u002Ferrata\u002FRHSA-2026:87080",[19],"RHSA-2026:87080",[43,690,626],{},[139,692,693,696,699],{},[154,694,695],{},"AlmaLinux and Rocky Linux 8, 9 and 10",[154,697,698],{},"The matching RHEL rebuild packages, including the module streams above",[154,700,701,702,707,708,713,714],{},"Check the rebuild's ",[15,703,706],{"href":704,"rel":705},"https:\u002F\u002Ferrata.almalinux.org\u002F",[19],"AlmaLinux errata"," or ",[15,709,712],{"href":710,"rel":711},"https:\u002F\u002Ferrata.rockylinux.org\u002F",[19],"Rocky Linux errata"," for the ALSA\u002FRLSA that carries the same fixes; ",[43,715,626],{},[139,717,718,721,726],{},[154,719,720],{},"Fedora 43",[154,722,723],{},[43,724,725],{},"php 8.4.27-2.fc43",[154,727,728,506,733],{},[15,729,732],{"href":730,"rel":731},"https:\u002F\u002Fbodhi.fedoraproject.org\u002Fupdates\u002FFEDORA-2026-d5f8446449",[19],"FEDORA-2026-d5f8446449",[43,734,735],{},"sudo dnf upgrade --security",[139,737,738,741,746],{},[154,739,740],{},"SUSE Linux Enterprise 16.1",[154,742,743],{},[43,744,745],{},"php8 8.5.12-160100.1.1",[154,747,748,506,753],{},[15,749,752],{"href":750,"rel":751},"https:\u002F\u002Fwww.suse.com\u002Fsecurity\u002Fcve\u002FCVE-2026-109618.html",[19],"SUSE CVE-2026-109618",[43,754,755],{},"sudo zypper patch",[139,757,758,761,766],{},[154,759,760],{},"SUSE Linux Enterprise 16.0 and openSUSE Leap 16.0",[154,762,763],{},[43,764,765],{},"php8 8.4.27-160000.1.1",[154,767,768,506,771],{},[15,769,752],{"href":750,"rel":770},[19],[43,772,755],{},[139,774,775,778,783],{},[154,776,777],{},"SUSE Linux Enterprise 15 SP7",[154,779,780],{},[43,781,782],{},"php8 8.3.36-150700.3.24.1",[154,784,785,506,788],{},[15,786,752],{"href":750,"rel":787},[19],[43,789,755],{},[139,791,792,795,800],{},[154,793,794],{},"SUSE Linux Enterprise 15 SP6",[154,796,797],{},[43,798,799],{},"php8 8.2.35-150600.3.39.1",[154,801,802,506,805],{},[15,803,752],{"href":750,"rel":804},[19],[43,806,755],{},[139,808,809,812,817],{},[154,810,811],{},"openSUSE Tumbleweed",[154,813,814],{},[43,815,816],{},"php8 8.5.12-1.1",[154,818,819,506,822],{},[15,820,752],{"href":750,"rel":821},[19],[43,823,824],{},"sudo zypper dup",[139,826,827,830,835],{},[154,828,829],{},"Alpine Linux 3.22",[154,831,832],{},[43,833,834],{},"php82 8.2.35-r0",[154,836,837,506,842],{},[15,838,841],{"href":839,"rel":840},"https:\u002F\u002Fsecurity.alpinelinux.org\u002Fvuln\u002FCVE-2026-109618",[19],"Alpine CVE-2026-109618",[43,843,844],{},"sudo apk upgrade",[139,846,847,850,861],{},[154,848,849],{},"Alpine Linux 3.23 and 3.24",[154,851,852,618,855,360,858],{},[43,853,854],{},"php83 8.3.36-r0",[43,856,857],{},"php84 8.4.27-r0",[43,859,860],{},"php85 8.5.12-r0",[154,862,863,506,866],{},[15,864,841],{"href":839,"rel":865},[19],[43,867,844],{},[139,869,870,873,887],{},[154,871,872],{},"Amazon Linux 2023",[154,874,875,618,878,618,881,618,884],{},[43,876,877],{},"php8.2 8.2.35-1.amzn2023.0.1",[43,879,880],{},"php8.3 8.3.36-1.amzn2023.0.1",[43,882,883],{},"php8.4 8.4.27-1.amzn2023.0.1",[43,885,886],{},"php8.5 8.5.12-1.amzn2023.0.1",[154,888,889,618,894,618,899,618,904,506,909],{},[15,890,893],{"href":891,"rel":892},"https:\u002F\u002Falas.aws.amazon.com\u002FAL2023\u002FALAS2023-2026-3301.html",[19],"ALAS2023-2026-3301",[15,895,898],{"href":896,"rel":897},"https:\u002F\u002Falas.aws.amazon.com\u002FAL2023\u002FALAS2023-2026-3302.html",[19],"-3302",[15,900,903],{"href":901,"rel":902},"https:\u002F\u002Falas.aws.amazon.com\u002FAL2023\u002FALAS2023-2026-3303.html",[19],"-3303",[15,905,908],{"href":906,"rel":907},"https:\u002F\u002Falas.aws.amazon.com\u002FAL2023\u002FALAS2023-2026-3304.html",[19],"-3304",[43,910,626],{},[139,912,913,916,921],{},[154,914,915],{},"Amazon Linux 2, PHP 8.2 Extra",[154,917,918],{},[43,919,920],{},"php 8.2.35-1.amzn2.0.1",[154,922,923,506,928],{},[15,924,927],{"href":925,"rel":926},"https:\u002F\u002Falas.aws.amazon.com\u002FAL2\u002FALAS2PHP8.2-2026-015.html",[19],"ALAS2PHP8.2-2026-015",[43,929,930],{},"sudo yum update --security",[139,932,933,936,961],{},[154,934,935],{},"Official Docker images",[154,937,938,618,941,618,944,707,947,950,951,618,954,360,957,960],{},[43,939,940],{},"php:8.5.12",[43,942,943],{},"php:8.4.27",[43,945,946],{},"php:8.3.36",[43,948,949],{},"php:8.2.35"," (also the ",[43,952,953],{},"-apache",[43,955,956],{},"-fpm",[43,958,959],{},"-cli"," variants)",[154,962,963,964,707,967,970],{},"Rebuild with ",[43,965,966],{},"docker build --pull",[43,968,969],{},"docker compose build --pull",", then recreate the containers",[139,972,973,976,983],{},[154,974,975],{},"Source builds and Windows binaries",[154,977,978,979,982],{},"PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35; Windows builds carry a ",[43,980,981],{},"-1"," suffix",[154,984,985],{},[15,986,988],{"href":206,"rel":987},[19],"PHP release archive",[11,990,991,992,994,995,998,999,360,1002,1005],{},"For an unfamiliar package source, look up the CVE in that vendor's security tracker before you trust ",[43,993,45],{},". On Debian and Ubuntu, ",[43,996,997],{},"dpkg-query -W -f='${Package} ${Version}\\n' 'php*'"," confirms what is actually installed. On the RPM family, ",[43,1000,1001],{},"rpm -q php php-fpm php-cli",[43,1003,1004],{},"dnf module list php"," show the package and stream in use.",[78,1007,1009],{"id":1008},"step-3-restart-every-php-process-then-check-again","Step 3: restart every PHP process, then check again",[11,1011,1012],{},"A package update replaces files on disk. PHP processes that are already running keep the old code in memory until they're replaced, so a server with the new package installed and the old processes running is still vulnerable.",[387,1014,1016],{"className":434,"code":1015,"language":436,"meta":392,"style":392},"sudo systemctl restart php8.3-fpm   # Debian, Ubuntu: one service per installed version\nsudo systemctl restart php-fpm      # RHEL, AlmaLinux, Rocky\nsudo systemctl restart apache2      # mod_php (the service is httpd on RHEL)\n",[43,1017,1018,1023,1028],{"__ignoreMap":392},[396,1019,1020],{"class":398,"line":399},[396,1021,1022],{},"sudo systemctl restart php8.3-fpm   # Debian, Ubuntu: one service per installed version\n",[396,1024,1025],{"class":398,"line":446},[396,1026,1027],{},"sudo systemctl restart php-fpm      # RHEL, AlmaLinux, Rocky\n",[396,1029,1030],{"class":398,"line":452},[396,1031,1032],{},"sudo systemctl restart apache2      # mod_php (the service is httpd on RHEL)\n",[11,1034,1035],{},"Some PHP processes survive a web server restart, or never get one:",[348,1037,1038,1058,1074],{},[35,1039,1040,1043,1044,1049,1050,1053,1054,1057],{},[353,1041,1042],{},"LiteSpeed"," runs PHP in detached mode, where PHP processes ",[15,1045,1048],{"href":1046,"rel":1047},"https:\u002F\u002Fdocs.openlitespeed.org\u002Fconfig\u002Fphp\u002Fdetached\u002F",[19],"\"continue running independently, even when OpenLiteSpeed restarts\"",". ",[43,1051,1052],{},"touch \u002Fusr\u002Flocal\u002Flsws\u002Fadmin\u002Ftmp\u002F.lsphp_restart.txt"," restarts them the next time they're needed, and ",[43,1055,1056],{},"killall -9 lsphp"," stops them at once.",[35,1059,1060,1063,1064,1066,1067,1069,1070,1073],{},[353,1061,1062],{},"Containers"," restart from the image they were built from. Rebuild with ",[43,1065,966],{}," (or ",[43,1068,969],{},"), then recreate the containers. Check that the Dockerfile's ",[43,1071,1072],{},"FROM"," line doesn't pin an older patch release.",[35,1075,1076,1079],{},[353,1077,1078],{},"Long-running PHP applications"," (Laravel Octane, RoadRunner, Swoole, FrankenPHP's worker mode, queue workers under Supervisor) keep running until something stops them. Restart those too.",[11,1081,1082],{},"Then run the Step 1 check again. If the version hasn't changed, something is still running the old build.",[11,1084,1085,1086,1090],{},"The fix also changes how PHP behaves when a script runs out of memory. It now stops the script at the next safe point instead of jumping out at once. If memory use keeps climbing past a second, higher threshold, ",[15,1087,1089],{"href":90,"rel":1088},[19],"the process exits immediately",", so shutdown functions and error handlers don't run. A memory-hungry import job may fail differently than it used to.",[78,1092,1094],{"id":1093},"if-you-cant-update-today-the-stopgaps-and-their-limits","If you can't update today: the stopgaps and their limits",[11,1096,1097],{},"PHP's advisory lists stopgaps. Each one closes a known attack path, and in PHP's words they \"do not make an installation safe\". Use them for hours or days while you get the update in.",[11,1099,1100,1101,1104,1105,360,1107,1109],{},"They only work where PHP reads them before it parses a request: ",[43,1102,1103],{},"php.ini",", the FPM pool, or the Apache configuration. ",[43,1106,359],{},[43,1108,363],{}," are too late.",[387,1111,1115],{"className":1112,"code":1113,"language":1114,"meta":392,"style":392},"language-ini shiki shiki-themes github-light github-dark","; php.ini\nsession.upload_progress.enabled = 0\npost_max_size = 8M           ; 32M if the site takes uploads; keep upload_max_filesize below it\nfatal_error_backtraces = 0   ; PHP 8.5 only\nmemory_limit = -1            ; only with a container or cgroup memory cap, see below\n","ini",[43,1116,1117,1122,1127,1132,1137],{"__ignoreMap":392},[396,1118,1119],{"class":398,"line":399},[396,1120,1121],{},"; php.ini\n",[396,1123,1124],{"class":398,"line":446},[396,1125,1126],{},"session.upload_progress.enabled = 0\n",[396,1128,1129],{"class":398,"line":452},[396,1130,1131],{},"post_max_size = 8M           ; 32M if the site takes uploads; keep upload_max_filesize below it\n",[396,1133,1134],{"class":398,"line":458},[396,1135,1136],{},"fatal_error_backtraces = 0   ; PHP 8.5 only\n",[396,1138,1140],{"class":398,"line":1139},5,[396,1141,1142],{},"memory_limit = -1            ; only with a container or cgroup memory cap, see below\n",[11,1144,1145,1146,360,1149,1152,1153,360,1156,1159,1160,1172],{},"In an FPM pool the same settings look like ",[43,1147,1148],{},"php_admin_flag[session.upload_progress.enabled] = off",[43,1150,1151],{},"php_admin_value[memory_limit] = -1",". Under mod_php, use ",[43,1154,1155],{},"php_admin_flag",[43,1157,1158],{},"php_admin_value"," in the Apache configuration, which ",[15,1161,1164,1165,1168,1169,1171],{"href":1162,"rel":1163},"https:\u002F\u002Fwww.php.net\u002Fmanual\u002Fen\u002Fconfiguration.changes.php",[19],"neither ",[43,1166,1167],{},".htaccess"," nor ",[43,1170,363],{}," can override",". Restart every worker afterwards.",[11,1174,1175],{},"Here's what each one does, and what it costs:",[348,1177,1178,1186,1208,1225,1233],{},[35,1179,1180,1185],{},[353,1181,1182],{},[43,1183,1184],{},"session.upload_progress.enabled = 0"," blocks the confirmed session paths of CVE-2026-109619 and also covers CVE-2026-115560. Few sites use upload progress, and PHP suggests leaving it off after patching if you don't need it. This is the one we'd keep.",[35,1187,1188,1193,1194,1197,1198,360,1201,1204,1205,1207],{},[353,1189,1190],{},[43,1191,1192],{},"memory_limit = -1"," removes the memory limit the CVE-2026-109618 exploit relies on. A lower-level allocation failure can still reach the bug, and a runaway script can now eat all of the server's memory. Pair it with a container or cgroup memory limit, and know that a cgroup kill can take down the FPM master and every worker unless each worker has its own group. Don't use ",[43,1195,1196],{},"ulimit -v"," or other ",[43,1199,1200],{},"RLIMIT_AS",[43,1202,1203],{},"RLIMIT_DATA"," limits: they make allocations fail, which is exactly what the exploit needs. Put a finite ",[43,1206,100],{}," back once you've patched.",[35,1209,1210,1213,1214,1216,1217,1220,1221,1224],{},[353,1211,1212],{},"Small request limits"," (",[43,1215,96],{},", plus size limits at the web server or proxy) reduce how much memory one request can make PHP use. The limits must also cover chunked requests, which have no ",[43,1218,1219],{},"Content-Length",". If a site never accepts ",[43,1222,1223],{},"multipart\u002Fform-data"," posts, block them at the front end.",[35,1226,1227,1232],{},[353,1228,1229],{},[43,1230,1231],{},"pm.max_requests = 1"," in an FPM pool gives every request a fresh worker, so no state carries over. It costs throughput.",[35,1234,1235,1238,1239,1242,1243,360,1246,1249,1250,1252],{},[353,1236,1237],{},"Hiding errors does nothing."," The ",[43,1240,1241],{},"@"," operator, ",[43,1244,1245],{},"display_errors",[43,1247,1248],{},"error_reporting"," act after the vulnerable code has run. Remove deprecated or invalid PHP settings applied per request (in ",[43,1251,1167],{},", for example), because the warnings they raise early are one of the confirmed paths.",[11,1254,1255,1256,1261,1262,1265,1266,360,1269,1272,1273,1278,1279,1284],{},"A web application firewall helps, with caveats. Cloudflare has ",[15,1257,1260],{"href":1258,"rel":1259},"https:\u002F\u002Fblog.cloudflare.com\u002Fphp-vulnerabilities-waf-protection\u002F",[19],"blocked known exploit patterns"," since 03:02 UTC on October 21 on every plan with its WAF, including Free. Paid plans should confirm the rules are in block mode, and sites that changed ",[43,1263,1264],{},"session.upload_progress.name"," aren't covered. AWS added ",[43,1267,1268],{},"PHP2Shell_BODY",[43,1270,1271],{},"PHP2Shell_BODY_Extended"," rules to its ",[15,1274,1277],{"href":1275,"rel":1276},"https:\u002F\u002Fdocs.aws.amazon.com\u002Fwaf\u002Flatest\u002Fdeveloperguide\u002Faws-managed-rule-groups-use-case.html",[19],"PHP managed rule group",", but behind an Application Load Balancer they inspect only the first 8 KB of the request body. The exploit requests Karimi captured were 279 KB to 33 MB. ",[15,1280,1283],{"href":1281,"rel":1282},"https:\u002F\u002Fwww.akamai.com\u002Fblog\u002Fsecurity-research\u002Fcritical-remote-code-execution-vulnerabilities-php-core",[19],"Akamai"," and Fastly have rules as well, and Fastly customers have to opt in to its protection.",[11,1286,1287],{},"All of these vendors say to patch anyway. And a WAF only sees the traffic that goes through it. If your server's own IP address answers web requests, an attacker can go around the WAF, so let the server accept web traffic only from your CDN's address ranges.",[78,1289,1291],{"id":1290},"cve-2026-115560-the-october-releases-dont-fix-this-one","CVE-2026-115560: the October releases don't fix this one",[11,1293,1294,1295,1300],{},"On October 23, PHP published an ",[15,1296,1299],{"href":1297,"rel":1298},"https:\u002F\u002Fwww.php.net\u002Farchive\u002F2026.php#2026-10-23-1",[19],"informational advisory"," about a third path to running code. It only applies when all of these are true:",[348,1302,1303,1317,1329],{},[35,1304,1305,1306,1309,1310,707,1313,1316],{},"the configuration sets ",[43,1307,1308],{},"session.serialize_handler"," to ",[43,1311,1312],{},"php_binary",[43,1314,1315],{},"php_serialize",";",[35,1318,1319,1320,1322,1323,1325,1326,1316],{},"the application switches it to ",[43,1321,391],{}," with ",[43,1324,363],{}," before calling ",[43,1327,1328],{},"session_start()",[35,1330,1331],{},"session upload progress is still enabled.",[11,1333,1334,1335,1337],{},"PHP calls the combination unusual and will fix it in the next regular release, with a full advisory then. Until that release, the fix is the same setting as above: ",[43,1336,1184],{},". If you already set it for CVE-2026-109619, you're done.",[78,1339,1341],{"id":1340},"check-whether-anyone-got-in-before-you-patched","Check whether anyone got in before you patched",[11,1343,1344],{},"If you think a server may already be compromised, snapshot its disk before you change anything, if your host makes that easy. Restarting and updating destroys evidence you may want later.",[11,1346,1347,1348,1351],{},"Then look at the PHP and web server error logs from October 17 onward. These are the kinds of entries worth searching for. The first three appear in the honeypot report or PHP's advisory; ",[43,1349,1350],{},"zend_mm_heap corrupted"," is another PHP heap-corruption signature.",[387,1353,1358],{"className":1354,"code":1356,"language":1357,"meta":392},[1355],"language-text","Allowed memory size of 134217728 bytes exhausted (tried to allocate 4096 bytes) in Unknown on line 0\nPHP Request Startup: Session ID is too long or contains illegal characters\nAH00052: child pid 4321 exit signal Segmentation fault (11)\nzend_mm_heap corrupted\n","text",[43,1359,1356],{"__ignoreMap":392},[11,1361,1362,1363,21],{},"\"Unknown on line 0\" means PHP ran out of memory before any script started, which a normal page load almost never does. 134217728 bytes is the default 128 MB limit, so on your server the number matches your own ",[43,1364,100],{},[11,1366,1367,1368,707,1371,1374,1375,1378,1379,1382,1383,1386,1387,1392],{},"In the access log, look for multipart POST requests to ",[43,1369,1370],{},"\u002F",[43,1372,1373],{},"\u002Findex.php"," with no ",[43,1376,1377],{},"User-Agent",", very large bodies and a ",[43,1380,1381],{},"PHP_SESSION_UPLOAD_PROGRESS"," field. Some scanners announce themselves as ",[43,1384,1385],{},"php2shell-scan\u002F109618",". CISA has published a ",[15,1388,1391],{"href":1389,"rel":1390},"https:\u002F\u002Fgithub.com\u002Fcisagov\u002FSIGMA_Rules\u002Fblob\u002Fdevelop\u002FCISA_SIGMA_261429_CVE_2026_109618-109619_PHP2Shell_TLP_CLEAR.yaml",[19],"Sigma detection rule"," if you run a log platform that reads them.",[11,1394,1395,1396,707,1399,1402,1403,1406,1407,360,1410,1413],{},"On the server itself, the signs of a successful attack are the web server's user starting a shell, ",[43,1397,1398],{},"curl",[43,1400,1401],{},"wget",", and new PHP files in upload, plugin or theme folders. Wordfence saw attackers try to write a file called ",[43,1404,1405],{},"wp2s.php"," and read ",[43,1408,1409],{},".env",[43,1411,1412],{},"wp-config.php",". A first pass:",[387,1415,1417],{"className":434,"code":1416,"language":436,"meta":392,"style":392},"sudo grep -rIh \"Unknown on line 0\" \u002Fvar\u002Flog | tail -n 20\nsudo find \u002Fvar\u002Fwww -name '*.php' -newermt 2026-10-17 -ls\nps -u www-data -o pid,ppid,lstart,args   # the user is apache or nginx on RHEL\nsudo crontab -l -u www-data\n",[43,1418,1419,1424,1429,1434],{"__ignoreMap":392},[396,1420,1421],{"class":398,"line":399},[396,1422,1423],{},"sudo grep -rIh \"Unknown on line 0\" \u002Fvar\u002Flog | tail -n 20\n",[396,1425,1426],{"class":398,"line":446},[396,1427,1428],{},"sudo find \u002Fvar\u002Fwww -name '*.php' -newermt 2026-10-17 -ls\n",[396,1430,1431],{"class":398,"line":452},[396,1432,1433],{},"ps -u www-data -o pid,ppid,lstart,args   # the user is apache or nginx on RHEL\n",[396,1435,1436],{"class":398,"line":458},[396,1437,1438],{},"sudo crontab -l -u www-data\n",[11,1440,1441,1442,1445],{},"Deploys change files too, and attackers can reset timestamps, so ",[43,1443,1444],{},"find"," gives you a list to review, not a verdict. A clean log isn't proof either; PHP's advisory says so directly.",[11,1447,1448,1449,707,1451,1453],{},"If you find signs of a break-in, rebuild the server from a clean source rather than cleaning it in place. Then rotate every secret the web server's user could read: database passwords, API keys in ",[43,1450,1409],{},[43,1452,1412],{},", application keys and WordPress salts. We'd rotate those even without finding a shell if an unpatched mod_php server shows the attack pattern in its logs, because the exploit chain leaks memory to the attacker before it runs any code.",[78,1455,1457],{"id":1456},"running-php-81-or-older","Running PHP 8.1 or older",[11,1459,1460,1461,618,1466,360,1471,1476],{},"The PHP project no longer updates 8.1 and older. Given the severity, its security team made an exception and published minimal source patches for ",[15,1462,1465],{"href":1463,"rel":1464},"https:\u002F\u002Fgithub.com\u002Fphp\u002Fphp-src\u002Ftree\u002FPHP-7.4-CVE-2026-109618-109619",[19],"7.4",[15,1467,1470],{"href":1468,"rel":1469},"https:\u002F\u002Fgithub.com\u002Fphp\u002Fphp-src\u002Ftree\u002FPHP-8.0-CVE-2026-109618-109619",[19],"8.0",[15,1472,1475],{"href":1473,"rel":1474},"https:\u002F\u002Fgithub.com\u002Fphp\u002Fphp-src\u002Ftree\u002FPHP-8.1-CVE-2026-109618-109619",[19],"8.1",", for people who build PHP from source. Older versions get nothing from PHP, though some distributions and paid long-term support vendors backport fixes.",[11,1478,1479],{},"Those branches are source trees, not new official releases or binary packages. Build the branch you need, rebuild your extensions against it, and install it in place of the old build while keeping the old extension API in mind. If you don't build PHP, use a vendor backport:",[133,1481,1482,1492],{},[136,1483,1484],{},[139,1485,1486,1489],{},[142,1487,1488],{},"Old branch",[142,1490,1491],{},"Fixed options as of October 30, 2026",[149,1493,1494,1531,1554,1570],{},[139,1495,1496,1499],{},[154,1497,1498],{},"PHP 7.4",[154,1500,1501,1502,1505,1506,1512,1513,1523,1524,21],{},"Build the ",[43,1503,1504],{},"PHP-7.4-CVE-2026-109618-109619"," branch; or use RHEL 8 ",[15,1507,1509],{"href":686,"rel":1508},[19],[43,1510,1511],{},"php:7.4 7.4.33-8",", SUSE ",[15,1514,1516,1519,1520],{"href":750,"rel":1515},[19],[43,1517,1518],{},"php74 7.4.33-1.74.1"," \u002F ",[43,1521,1522],{},"php7 7.4.33-150400.4.81.1",", or Ubuntu Pro 20.04 ",[15,1525,1528],{"href":1526,"rel":1527},"https:\u002F\u002Fubuntu.com\u002Fsecurity\u002Fnotices\u002FUSN-8948-2",[19],[43,1529,1530],{},"php7.4 7.4.3-4ubuntu2.29+esm5",[139,1532,1533,1536],{},[154,1534,1535],{},"PHP 8.0",[154,1537,1501,1538,1541,1542,1547,1548,21],{},[43,1539,1540],{},"PHP-8.0-CVE-2026-109618-109619"," branch; or use RHEL 9 ",[15,1543,1545],{"href":649,"rel":1544},[19],[43,1546,636],{}," or SUSE ",[15,1549,1551],{"href":750,"rel":1550},[19],[43,1552,1553],{},"php8 8.0.30-150400.4.80.1",[139,1555,1556,1559],{},[154,1557,1558],{},"PHP 8.1",[154,1560,1501,1561,1564,1565,21],{},[43,1562,1563],{},"PHP-8.1-CVE-2026-109618-109619"," branch; or use Ubuntu 22.04 ",[15,1566,1568],{"href":542,"rel":1567},[19],[43,1569,590],{},[139,1571,1572,1575],{},[154,1573,1574],{},"PHP 5.4–7.3",[154,1576,1577,1578,1582,1583,1586,1587,1590,1591,1594,1595,1600],{},"No fix from the PHP project. Some paid LTS offerings still carry fixes: ",[15,1579,1581],{"href":1526,"rel":1580},[19],"Ubuntu Pro has"," ",[43,1584,1585],{},"php5 5.5.9+dfsg-1ubuntu4.29+esm18"," on 14.04, ",[43,1588,1589],{},"php7.0 7.0.33-0ubuntu0.16.04.16+esm22"," on 16.04, and ",[43,1592,1593],{},"php7.2 7.2.24-0ubuntu0.18.04.17+esm14"," on 18.04. Red Hat lists a ",[15,1596,1599],{"href":1597,"rel":1598},"https:\u002F\u002Faccess.redhat.com\u002Ferrata\u002FRHSA-2026:88693",[19],"RHEL 7 Extended Lifecycle Support fix"," for CVE-2026-109619; check the vendor advisory for the exact coverage before relying on it.",[11,1602,1603],{},"Whichever route you choose, verify that the installed build contains both fixes, not merely a newer package date. A vendor-patched branch can still print an old PHP version.",[11,1605,1606,1607,1612],{},"Don't combine the emergency patch with a version upgrade. Patch within your current branch today, then plan the move as a normal project. PHP 8.2 gets its ",[15,1608,1611],{"href":1609,"rel":1610},"https:\u002F\u002Fwww.php.net\u002Fsupported-versions.php",[19],"last security fixes on December 31, 2026",", so if that's where you are, aim for 8.4 (supported to the end of 2028) or 8.5 (to the end of 2029).",[78,1614,1616],{"id":1615},"what-wed-change-so-the-next-one-hurts-less","What we'd change so the next one hurts less",[11,1618,1619],{},"Most of the work this week was finding out what ran where. Keep a list of every server and site that runs PHP, with its version and how PHP runs, and include staging and the old server nobody has switched off.",[11,1621,1622,1623,1628],{},"Make sure whatever installs your updates also restarts PHP. An installed fix that isn't running protects nothing. Subscribe to PHP's ",[15,1624,1627],{"href":1625,"rel":1626},"https:\u002F\u002Fwww.php.net\u002Ffeed.atom",[19],"release announcements"," and your distribution's security list; the advance notice arrived a day before the release.",[11,1630,1631],{},"For new servers, choose PHP-FPM over mod_php. This time it was the difference between an attack that runs before your code and one that needs more help from the application. FPM also lets each site run as its own user. And switch off PHP features you don't use, starting with session upload progress.",[11,1633,1634,1635,21],{},"None of this is specific to PHP. Security patches are most of what maintenance means after launch, which we cover in ",[15,1636,1638],{"href":1637},"\u002Fblog\u002Fsoftware-development#maintenance-the-longest-and-most-expensive-stage","our guide to software development",[11,1640,1641,1642,1646],{},"If you do one thing today, run the Step 1 check on every site you're responsible for. If you'd rather someone else kept track of patching and monitoring, it's part of our ",[15,1643,1645],{"href":1644},"\u002Fservices#devops","DevOps and cloud infrastructure"," work.",[1648,1649,1650],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":392,"searchDepth":446,"depth":446,"links":1652},[1653,1654,1655,1656,1657,1658,1659,1660,1661,1662,1663],{"id":80,"depth":446,"text":81},{"id":127,"depth":446,"text":128},{"id":278,"depth":446,"text":279},{"id":379,"depth":446,"text":380},{"id":467,"depth":446,"text":468},{"id":1008,"depth":446,"text":1009},{"id":1093,"depth":446,"text":1094},{"id":1290,"depth":446,"text":1291},{"id":1340,"depth":446,"text":1341},{"id":1456,"depth":446,"text":1457},{"id":1615,"depth":446,"text":1616},"2026-10-30","PHP2Shell (CVE-2026-109618, CVE-2026-109619) lets attackers run code on PHP servers. How to tell if you're exposed, patch properly and check your logs.","md",{},true,"\u002Fblog\u002Fphp2shell-php-vulnerability",19,{"title":5,"description":1665},"blog\u002Fphp2shell-php-vulnerability","Security","wrgUnmYJ8qh4wVE4a9tcMrpOHvUT0yeREddrM43B2EQ",1793347146847]