<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Can Türk</title>
    <description>The latest articles on DEV Community by Can Türk (@iamcanturk).</description>
    <link>https://dev.to/iamcanturk</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F436286%2F440b7486-be4d-43e2-bb6d-71066fbefb0f.jpeg</url>
      <title>DEV Community: Can Türk</title>
      <link>https://dev.to/iamcanturk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/iamcanturk"/>
    <language>en</language>
    <item>
      <title>Reverse Development in the Age of AI</title>
      <dc:creator>Can Türk</dc:creator>
      <pubDate>Thu, 22 Oct 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/iamcanturk/reverse-development-in-the-age-of-ai-1m3c</link>
      <guid>https://dev.to/iamcanturk/reverse-development-in-the-age-of-ai-1m3c</guid>
      <description>&lt;p&gt;After a long time, I sat down to write again, and within the first few minutes I noticed something strange: I can't think as well as I used to. Or rather, the thoughts are still there. There are dozens of them in my head, constantly fighting with each other, but I struggle to pull them together the way I once did and turn them into a few pages of writing. I got my coffee, sat down at the desk, and thought for a long while about what to write. I used to be able to rattle off pages about any topic that came to mind; these days, just gathering what comes to mind has become an effort in itself. Thoughts used to turn into sentences on their own. Now, before I can build a sentence, I first have to catch the thought.&lt;/p&gt;

&lt;p&gt;Then I started thinking about why. As someone who used to read books regularly, I tried to pin down what it was that had both derailed my reading habit and slowed down my writing. As I kept thinking, a few items actually surfaced in my mind. Here they are as an unordered, incomplete list: attention spans shrinking under fast social media; forgetfulness, lack of discipline, or the absence of reward; and finally, the reverse development that has come with the rise of AI.&lt;/p&gt;

&lt;p&gt;Maybe the problem is me. Or maybe we're all a little like this now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Attention spans shrinking under fast social media
&lt;/h2&gt;

&lt;p&gt;First, let me explain what I mean by "fast social media." This trend first entered our lives in 2013 with the Vine app. Back then, with this approach of watching video after video in a fast, endless loop, we didn't realize that short, vertical video creation would come to shape how media is perceived in the future. In 2014, an app called Musical.ly carried it forward. Then came TikTok, which would become the Hiroshima of social media, spreading in China in 2016 and around the world in 2017. TikTok became the single biggest force in carrying this trend to the whole world and to every age group.&lt;/p&gt;

&lt;p&gt;Of course, when Instagram and YouTube then copied this format for themselves, the direction of content creation and consumption changed irreversibly. Naturally, the users are happy: they have something to keep their minds busy, something that releases fake dopamine and lets them masturbate on happiness. The platforms are happy: they're increasing how long users stay in the app. The advertisers are happy: they've found a new, effective way to advertise. Even adult content companies, wanting their share of all this happiness, started making 7-second porn clips. Everyone is happy. Except us, losing hours of our lives without fully understanding what's going on.&lt;/p&gt;

&lt;p&gt;This new kind of media has done irreversible damage to the human mind. People who at first assumed that, since this was about watching short videos, it would eat up less of their time, started finding themselves caught in a spiral that lasted for hours. Humanity was now making time for short-form content on the bus, in traffic, in the elevator, even in the bathroom. Videos that are short on their own, once linked together in an endless chain, began taking up hours, and came to occupy more of people's lives than even sleep, one of our most basic needs.&lt;/p&gt;

&lt;p&gt;This consumption of short content back to back, and even exposure to several pieces of content at once, has seriously lowered people's threshold for attention and focus. As a result, people who created text-based content either moved to producing both text and video, or abandoned text-based content altogether. Because nobody reads a long piece of text anymore, and worse, nobody can find the energy to write one either. And this is where the transition to the second stage happens.&lt;/p&gt;

&lt;h2&gt;
  
  
  Forgetfulness, lack of discipline, or the absence of reward
&lt;/h2&gt;

&lt;p&gt;As I said, the human brain now moves very fast. And related to that, forgetfulness has reached its peak. We forget almost everything. The work we've done, the work we're going to do, and the promises we've made to ourselves. We're surrounded by millions of people who tell themselves every New Year, "This year I'm going to do this regularly," only to forget that promise a few weeks later. Along with this forgetfulness comes a lack of discipline. Or maybe what I think of as forgetfulness is just a lack of discipline itself. But one thing is certain: the two feed each other.&lt;/p&gt;

&lt;p&gt;Then there's the reward mechanism, which kicks in even for people who aren't forgetful and are disciplined. The new system no longer rewards you. Blogs don't make money the way they used to, and readership for written content has hit rock bottom. In a world where books are listened to rather than read, nobody reads text to learn something or to hear about a memory; they choose video instead, which appeals to the eye. I won't lie, that's mostly what I do too. And when I try not to, I can't find anyone who still keeps a blog regularly these days. Maybe that's my fault. When was the last time you read a blog? When did you last email a blog's author? When did you last leave a comment under a post and argue with the person who wrote it? It's rare.&lt;/p&gt;

&lt;p&gt;On the internet of the 2000s, you'd visit a blog. You'd step into someone's world. You'd read what they wrote, maybe leave a comment, maybe come back the next day. Maybe you'd add it to your RSS. Maybe you'd become friends with that person over the internet without ever meeting them. Now the algorithm decides who you get to see. And because algorithms favor visual content over written content, you can't even get in front of the people who would read you. Since the system doesn't reward you, no matter how disciplined you are, you start writing less and less often, and eventually you stop writing altogether.&lt;/p&gt;

&lt;p&gt;And even if you manage to keep going, the final blow is dealt by LLMs, the most powerful weapons of the AI age. Who's going to read a technical blog post when they could just learn the thing from an LLM?&lt;/p&gt;

&lt;h2&gt;
  
  
  The rise of AI and reverse development
&lt;/h2&gt;

&lt;p&gt;We've come to the last item, and in my view, the biggest danger. People have started using AI even for blog posts, which I believe should be completely personal and belong to humans alone. They give it a topic, say "Write it like this," and share content that is entirely AI-generated as if it were their own. It's like this everywhere: on video platforms, in text-based media, in social media content. At this point, where the dead internet theory is starting to come true, a blog post full of typos and clumsy, inverted sentences is a pearl in my eyes. In this boundless pollution of artificial data, I believe the natural, neuron-based mistakes made with emotion are what's valuable.&lt;/p&gt;

&lt;p&gt;AI has been a very important breakthrough. If you ask me, it's the biggest leap since the Industrial Revolution. But every revolution carries its own evil within it. People are drifting toward an era in which they won't be able to tell whether a piece of information is true or not. Let's keep up with the times, let's use AI, let's burn through millions of tokens, but let's not surrender our souls and our reality to it. For reading a summary of something, for writing programs, for generating images, AI is a huge blessing. But at that point, I think it should remain an assistant. We shouldn't put it in the place of a human.&lt;/p&gt;

&lt;p&gt;For example, there's this developer, someone I'd never heard of before, who declared himself a master once AI came along. The software he writes and the X posts he puts out (formerly known as tweets) are entirely AI-generated. He has surrendered himself completely; he's gone blind. I'm sure he even asks AI whether people's criticisms are valid, and what insults to throw back at them. I don't want to name him and embarrass him, but I hope he reads this post and starts remembering that he's human before he loses the last neuron he has left to think and question with.&lt;/p&gt;

&lt;p&gt;Because the issue isn't AI taking us over. The issue is us handing ourselves over to it of our own free will.&lt;/p&gt;

&lt;p&gt;If this post has somehow landed in front of you and you've read it all the way to the last sentence, please know that this content is entirely the product of a human brain. I'm deliberately not fixing my typos. Things that belong to humans are beautiful even with their mistakes.&lt;/p&gt;

&lt;p&gt;Maybe some of the sentences in this post are longer than they need to be. Maybe some of my thoughts are wrong. Maybe I'm being unfair on some points. Maybe a few years from now I'll believe the exact opposite of what I'm arguing today. But all of it is mine. And I think that's one of the most valuable things on the internet today. Let's use AI to generate images, but let our ideas remain our own.&lt;/p&gt;

&lt;p&gt;Hoping to keep writing, even if only now and then, I'll wrap up this post that carries the spirit of 2000s blogging. If you want these posts and thoughts to continue, remember that the system has to reward them. So whichever platform you're reading this on, please don't hesitate to follow me there, visit my personal site, and say hello.&lt;/p&gt;

&lt;p&gt;Because maybe the best part of blogging again is that you're not writing for an algorithm, but directly for another human being.&lt;/p&gt;

&lt;p&gt;Take care of yourselves.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://iamcanturk.dev/en/reverse-development-in-the-age-of-ai/" rel="noopener noreferrer"&gt;iamcanturk.dev&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>writing</category>
      <category>discuss</category>
    </item>
    <item>
      <title>October 21 Security Roundup: PHP2Shell's Backstory, Java, HTTP/3, Node, Railway and OVH</title>
      <dc:creator>Can Türk</dc:creator>
      <pubDate>Thu, 22 Oct 2026 11:04:32 +0000</pubDate>
      <link>https://dev.to/iamcanturk/october-21-security-roundup-php2shells-backstory-java-http3-node-railway-and-ovh-55m</link>
      <guid>https://dev.to/iamcanturk/october-21-security-roundup-php2shells-backstory-java-http3-node-railway-and-ovh-55m</guid>
      <description>&lt;p&gt;21 October 2026 was a long day for security teams. PHP patched two critical vulnerabilities, Oracle issued an out-of-band alert for Java, Node.js closed ten vulnerabilities and Railway disclosed access to customer secrets. The day before, OVHcloud's command-line tool had been shipped with malware.&lt;/p&gt;

&lt;p&gt;This post is a roundup of that day. Each section says what happened and what you should do. The technical deep dive on the PHP bugs is in a separate post: &lt;a href="https://iamcanturk.dev/en/php2shell-critical-php-rce/" rel="noopener noreferrer"&gt;Two Critical RCEs in PHP: CVE-2026-109618 and CVE-2026-109619&lt;/a&gt;. Video: &lt;a href="https://iamcanturk.dev/en/shorts/dunden-bugune/" rel="noopener noreferrer"&gt;Pixel Shorts ¬∑ Yesterday, in short&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  At a glance
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Topic&lt;/th&gt;
&lt;th&gt;Identifier&lt;/th&gt;
&lt;th&gt;What to do&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;PHP2Shell&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://www.cve.org/CVERecord?id=CVE-2026-109618" rel="noopener noreferrer"&gt;CVE-2026-109618&lt;/a&gt;, &lt;a href="https://www.cve.org/CVERecord?id=CVE-2026-109619" rel="noopener noreferrer"&gt;CVE-2026-109619&lt;/a&gt; ¬∑ CVSS v4.0 9.2&lt;/td&gt;
&lt;td&gt;Move to 8.5.12, 8.4.27, 8.3.36 or 8.2.35; restart PHP-FPM and Apache&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Java (JSSE)&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://openjdk.org/groups/vulnerability/advisories/2026-10-21" rel="noopener noreferrer"&gt;CVE-2026-91403&lt;/a&gt; ¬∑ CVSS 9.1&lt;/td&gt;
&lt;td&gt;Update the JDK or replace &lt;code&gt;blocked.certs&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP/3 QPACK&lt;/td&gt;
&lt;td&gt;CVE-2025-64702 (quic-go), CVE-2026-12523 (quiche)&lt;/td&gt;
&lt;td&gt;quic-go 0.57.0, quiche 0.29.3, lsquic 4.9.0; disable HTTP/3 on Bun&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node.js&lt;/td&gt;
&lt;td&gt;10 CVEs, worst is CVE-2026-111497 (Brotli, RCE)&lt;/td&gt;
&lt;td&gt;22.23.4, 24.22.1 or 26.12.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Railway&lt;/td&gt;
&lt;td&gt;&lt;a href="https://status.railway.com/incident/QH8L8B3E" rel="noopener noreferrer"&gt;Incident QH8L8B3E&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Rotate every environment variable and API token stored on Railway&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OVHcloud CLI&lt;/td&gt;
&lt;td&gt;0.11.0 ‚Äì 0.15.0 (19 October)&lt;/td&gt;
&lt;td&gt;If you installed it that day, rotate every secret on disk and use 0.16.0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  PHP2Shell: from 2024 to today
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2024: the first sign
&lt;/h3&gt;

&lt;p&gt;According to the &lt;a href="https://thephp.foundation/blog/2026/10/21/todays-php-security-release-and-how-were-strengthening-php-security/" rel="noopener noreferrer"&gt;PHP Foundation&lt;/a&gt;, the first signs appeared in 2024. A PHP core developer contracted by the Foundation noticed the out-of-memory (OOM) problem while fixing another issue from Quarkslab's 2024 audit. No concrete attack vector was found at the time, and issues with clear impact took priority.&lt;/p&gt;

&lt;p&gt;In the following months the security team drafted several fixes. As &lt;a href="https://thenextweb.com/news/php-foundation-structural-failure-2024-flaw-leak" rel="noopener noreferrer"&gt;The Next Web reports&lt;/a&gt;, one broke backward compatibility, one introduced a new DoS risk and one required changes across thousands of extensions. The small, consensus-driven team could not pick one. The Foundation called this a "structural failure" and says decisions will now be made by majority.&lt;/p&gt;

&lt;h3&gt;
  
  
  August 2026: rediscovered with AI
&lt;/h3&gt;

&lt;p&gt;This summer two teams independently found a working attack path:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Calif:&lt;/strong&gt; According to the Wall Street Journal, a Calif researcher found the flaw with &lt;strong&gt;GPT-5.6 Sol&lt;/strong&gt; as part of OpenAI's "Patch the Planet" program.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wiz Research:&lt;/strong&gt; According to &lt;a href="https://www.wiz.io/blog/php2shell-php-rce" rel="noopener noreferrer"&gt;Wiz&lt;/a&gt;, the first finding came on 19 August, unauthenticated RCE was confirmed against Drupal and WordPress on 20‚Äì21 August, and the reports went to PHP on 24 August. Wiz says it used Wiz Atlas, Gemini 4 Argon and GPT-5.6 Sol.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PHP acknowledged the reports on 21 September and started a coordinated fix.&lt;/p&gt;

&lt;h3&gt;
  
  
  17‚Äì21 October: the leak and the patch
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Date&lt;/th&gt;
&lt;th&gt;What happened&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;17 October&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://aws.amazon.com/blogs/security/amazon-threat-intelligence-identifies-php2shell-exploitation-prior-to-public-disclosure-in-madpot/" rel="noopener noreferrer"&gt;Amazon Threat Intelligence&lt;/a&gt; saw a PHP2Shell attempt in its MadPot honeypots, four days before disclosure. How the actor got the details is unknown.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;20 October&lt;/td&gt;
&lt;td&gt;The CVE IDs circulated on forums and social media with a wrong release time and a wrong score (10.0). PHP moved its pre-announcement to 19:30 UTC.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;20 October&lt;/td&gt;
&lt;td&gt;Calif mistakenly published a video of its working PoC. The Foundation says it revealed "limited additional details".&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;21 October 07:41 UTC&lt;/td&gt;
&lt;td&gt;Chainguard published patched images more than six hours early. The Foundation said this disregarded coordinated disclosure.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;21 October 14:00 UTC&lt;/td&gt;
&lt;td&gt;8.5.12, 8.4.27, 8.3.36 and 8.2.35 released.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;21 October&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://watchtowr.com/intelligence/php-cve-2026-109618-faq/" rel="noopener noreferrer"&gt;watchTowr&lt;/a&gt; saw exploitation attempts in its honeypots; Cloudflare saw attack traffic against customers and shipped WAF rules. No confirmed successful compromise has been reported.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Names of alleged leakers are circulating on social media. I could not find them in any primary source, so they are not here.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to apply the PHP fix correctly
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Check the PHP your site actually runs
&lt;/h3&gt;

&lt;p&gt;If a server has several PHP versions, &lt;code&gt;php -v&lt;/code&gt; in the terminal shows only the default CLI. The PHP-FPM pool or Apache module serving your site can be a different version.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php &lt;span class="nt"&gt;-v&lt;/span&gt;                 &lt;span class="c"&gt;# CLI PHP&lt;/span&gt;
php-fpm8.4 &lt;span class="nt"&gt;-v&lt;/span&gt;          &lt;span class="c"&gt;# the FPM your site uses (adjust the version)&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; /etc/php/           &lt;span class="c"&gt;# all installed versions (Debian/Ubuntu)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If unsure, put a temporary &lt;code&gt;phpinfo()&lt;/code&gt; page on the site, check "Server API" and the version line, then delete it.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Update the package
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Debian and Ubuntu (distribution packages):&lt;/strong&gt; Distributions usually backport security fixes into the old version number. If the number did not change, look for the CVE in the changelog.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--only-upgrade&lt;/span&gt; &lt;span class="s1"&gt;'php8.4*'&lt;/span&gt;
apt changelog php8.4-fpm | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s1"&gt;'109618|109619'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Ond≈ôej Sur√Ω's repository (deb.sury.org):&lt;/strong&gt; This repository follows PHP's upstream version numbers. It also has new packages for &lt;strong&gt;7.4, 8.0 and 8.1&lt;/strong&gt; dated 21 October. I checked their changelogs myself: the patch was written by PHP developers and carries the note "Minimal mitigation for EOL version". It buys time for 8.1 and older; the real fix is moving to 8.2 or later.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AlmaLinux:&lt;/strong&gt; Patched packages are in the &lt;a href="https://almalinux.org/blog/2026-10-21-php2shell-cve-2026-109618-cve-2026-109619/" rel="noopener noreferrer"&gt;AlmaLinux 8, 9 and 10&lt;/a&gt; repositories.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;dnf update &lt;span class="s1"&gt;'php*'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Docker:&lt;/strong&gt; Rebuild your image on the new version tag (e.g. &lt;code&gt;FROM php:8.4.27-fpm&lt;/code&gt;) and restart the containers. A &lt;code&gt;docker pull&lt;/code&gt; alone is not enough; containers started from the old image keep running old code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shared hosting and control panels:&lt;/strong&gt; Your provider applies the update. Ask in writing which version you are on.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Restart
&lt;/h3&gt;

&lt;p&gt;PHP-FPM workers and Apache processes run the code they loaded into memory. The fix is not live until they restart.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart php8.4-fpm
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart apache2      &lt;span class="c"&gt;# if you use mod_php&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Interim settings
&lt;/h3&gt;

&lt;p&gt;The interim settings php.net lists (&lt;code&gt;session.upload_progress.enabled = 0&lt;/code&gt;, &lt;code&gt;memory_limit = -1&lt;/code&gt;, a low &lt;code&gt;post_max_size&lt;/code&gt;, and &lt;code&gt;fatal_error_backtraces = 0&lt;/code&gt; on PHP 8.5) do not make a server safe; they close some paths. Details are in the &lt;a href="https://iamcanturk.dev/en/php2shell-critical-php-rce/" rel="noopener noreferrer"&gt;earlier post&lt;/a&gt;. If you don't use upload progress, keeping it off after patching does no harm; I left it off on my server.&lt;/p&gt;

&lt;h3&gt;
  
  
  On my own server
&lt;/h3&gt;

&lt;p&gt;I installed the builds that landed in the CloudPanel repository on the evening of 21 October: 8.5.12 (17:29) and 8.4.27 (18:56). The check on 22 October:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ php-fpm8.5 -v
PHP 8.5.12 (fpm-fcgi) (built: Oct 21 2026 07:08:08) (NTS)
$ php-fpm8.4 -v
PHP 8.4.27 (fpm-fcgi) (built: Oct 21 2026 07:08:08) (NTS)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Java: CVE-2026-91403
&lt;/h2&gt;

&lt;p&gt;According to &lt;a href="https://openjdk.org/groups/vulnerability/advisories/2026-10-21" rel="noopener noreferrer"&gt;OpenJDK's 21 October advisory&lt;/a&gt;, &lt;strong&gt;eight intermediate CA certificates&lt;/strong&gt; were compromised. The component is &lt;code&gt;security-libs/javax.net.ssl&lt;/code&gt; (JSSE), scored &lt;strong&gt;9.1&lt;/strong&gt; under CVSS 3.1. JDK 8, 11, 17, 21, 25 and 27 are affected; OpenJFX is not. Oracle issued it as a separate Security Alert, outside the regular October CPU.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Standalone JDK/JRE:&lt;/strong&gt; Update to the latest release.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If you can't update:&lt;/strong&gt; Drop in the new &lt;code&gt;$JDK_HOME/lib/security/blocked.certs&lt;/code&gt; (&lt;code&gt;blacklisted.certs&lt;/code&gt; on JDK 8; back up any entries you added), or enable revocation checking:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;-Dcom&lt;/span&gt;.sun.net.ssl.checkRevocation&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="nt"&gt;-Dcom&lt;/span&gt;.sun.security.enableCRLDP&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OS-provided OpenJDK:&lt;/strong&gt; On Debian, Ubuntu, Fedora, Red Hat and Arch, updating the system certificates is usually enough. Update FreeBSD and Homebrew packages directly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you don't know how many JDKs you have, count them first: CI agents, IDEs and runtimes bundled inside applications each need their own update.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTTP/3: QPACK memory amplification
&lt;/h2&gt;

&lt;p&gt;FoxIO published a class of memory amplification flaws in &lt;strong&gt;QPACK&lt;/strong&gt;, HTTP/3's header compression (&lt;a href="https://thehackernews.com/2026/10/new-qpack-flaws-can-crash-http3-servers.html" rel="noopener noreferrer"&gt;summary by The Hacker News&lt;/a&gt;). Affected stacks cap the compressed input but not the decoded header list, or apply the cap too late. Seven of the ten HTTP/3 stacks tested were affected. No authentication is needed; a small request can make the server allocate far more memory.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stack&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;quic-go (Caddy, Traefik, cloudflared)&lt;/td&gt;
&lt;td&gt;Fixed in 0.57.0 ¬∑ CVE-2025-64702&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloudflare quiche&lt;/td&gt;
&lt;td&gt;Fixed in 0.29.3 ¬∑ CVE-2026-12523&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;lsquic (LiteSpeed, OpenLiteSpeed)&lt;/td&gt;
&lt;td&gt;Fixed in 4.9.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wireshark (dissector)&lt;/td&gt;
&lt;td&gt;4.6.2 / 4.4.12 ¬∑ CVE-2025-13945&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bun, h3 (hyperium), aioquic/mitmproxy&lt;/td&gt;
&lt;td&gt;Unpatched at disclosure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IIS, Envoy, ngtcp2/nghttp3, Google quiche&lt;/td&gt;
&lt;td&gt;Not affected per FoxIO&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Interim mitigations for unpatched stacks: don't expose Bun's HTTP/3 server, run mitmproxy with &lt;code&gt;--set http3=false&lt;/code&gt;, and set a limit with &lt;code&gt;max_field_section_size&lt;/code&gt; in h3. No in-the-wild exploitation was reported at disclosure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Node.js: 21 October security releases
&lt;/h2&gt;

&lt;p&gt;On &lt;a href="https://nodejs.org/en/blog/vulnerability/october-2026-security-releases" rel="noopener noreferrer"&gt;21 October&lt;/a&gt; Node.js fixed &lt;strong&gt;10 CVEs&lt;/strong&gt; across the 22.x, 24.x and 26.x lines: 4 high, 3 medium, 3 low. The fixed releases are &lt;strong&gt;22.23.4, 24.22.1 and 26.12.1&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;High severity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CVE-2026-111497:&lt;/strong&gt; out-of-bounds write in the Brotli decoder that allows remote code execution (RCE).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CVE-2026-105483:&lt;/strong&gt; TLS certificate hostname check bypass when an IP address is written with fullwidth digits.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CVE-2026-106069:&lt;/strong&gt; TLS hostname check bypass when the host loosely resolves to an IP address.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CVE-2026-105482:&lt;/strong&gt; &lt;code&gt;dns.resolve&lt;/code&gt; truncates names containing a NUL character.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Among the medium ones, CVE-2026-106074 stores the entropy cache of &lt;code&gt;crypto.randomUUID()&lt;/code&gt; and &lt;code&gt;randomInt()&lt;/code&gt; in snapshots and SEAs, so processes started from the same snapshot can repeat values. Node.js 20 and 25 are end-of-life and got no fix; apps on those lines need a major upgrade.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Railway: access to environment variables
&lt;/h2&gt;

&lt;p&gt;On 21 October Railway detected anomalous activity in the systems that store customer environment variables. According to &lt;a href="https://blog.gitguardian.com/railway-october-2026-incident-environment-variables/" rel="noopener noreferrer"&gt;GitGuardian's summary&lt;/a&gt;, an unauthorized party may have accessed encrypted values and, for some, decrypted ones. Railway links it to a series of attacks on platform companies aimed at compromising AI inference providers.&lt;/p&gt;

&lt;p&gt;Per the &lt;a href="https://status.railway.com/incident/QH8L8B3E" rel="noopener noreferrer"&gt;status page&lt;/a&gt;, builds were paused platform-wide, OAuth sessions were invalidated, bucket credentials were rotated and on 22 October at 04:17 UTC &lt;strong&gt;all Railway API tokens were revoked&lt;/strong&gt;. On the morning of 22 October, Pro and Enterprise builds were running slowly and Hobby builds were not yet enabled.&lt;/p&gt;

&lt;p&gt;If you use Railway:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Rotate keys in the upstream services first (AWS, GCP, GitHub, AI providers), then update the values in Railway.&lt;/li&gt;
&lt;li&gt;Rotate sealed variables too; the disclosure doesn't say whether they were in scope.&lt;/li&gt;
&lt;li&gt;Rotate private registry credentials.&lt;/li&gt;
&lt;li&gt;Review the logs of services that use these credentials. Railway published guides for AWS, GCP and GitHub.&lt;/li&gt;
&lt;li&gt;Create a new Railway API token; the old ones no longer work.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Claims that crypto assets stored on Railway were also drained are circulating on social media; I could not confirm them from a primary source.&lt;/p&gt;

&lt;h2&gt;
  
  
  OVHcloud CLI: a supply-chain attack
&lt;/h2&gt;

&lt;p&gt;According to &lt;a href="https://www.bleepingcomputer.com/news/security/ovhcloud-cli-releases-backdoored-on-github-to-steal-developer-secrets/" rel="noopener noreferrer"&gt;BleepingComputer&lt;/a&gt;, attackers took over a developer's GitHub account and replaced files in existing OVHcloud CLI releases. Versions &lt;strong&gt;0.11.0 through 0.15.0&lt;/strong&gt; served malicious files on 19 October between roughly 14:47 and 16:21 (sources state the time zone differently; the window is about 94 minutes).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The malware is an infostealer that collects secrets from disk. It includes a hidden &lt;code&gt;preinstall.js&lt;/code&gt; loader and a second stage fetched through a Solana memo dead drop. OpenSourceMalware links it to an operation called GlassWorm.&lt;/li&gt;
&lt;li&gt;Affected platforms: macOS (Intel, ARM), Linux (x86_64, ARM64) and Windows x86-64. Builds from source and Docker images were not affected.&lt;/li&gt;
&lt;li&gt;The releases could be changed without passing CI/CD because GitHub's release immutability setting was off. OVHcloud has turned it on.&lt;/li&gt;
&lt;li&gt;0.10.0 and 0.16.0 are clean.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not a customer data breach; there are no reports of access to OVHcloud infrastructure or customer databases. But if you installed or updated the CLI in that window on 19 October, the advice from OVHcloud CEO Octave Klaba is clear: change every secret on that machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Today's checklist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] PHP: is your site's PHP-FPM on 8.5.12, 8.4.27, 8.3.36 or 8.2.35? If not, update, then restart PHP-FPM and Apache.&lt;/li&gt;
&lt;li&gt;[ ] PHP 8.1 and older: install the minimal patch and plan the move to 8.2 or later.&lt;/li&gt;
&lt;li&gt;[ ] Java: update every JDK/JRE or replace &lt;code&gt;blocked.certs&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;[ ] HTTP/3: check your quic-go, quiche and lsquic versions; disable HTTP/3 on Bun.&lt;/li&gt;
&lt;li&gt;[ ] Node.js: 22.23.4, 24.22.1 or 26.12.1.&lt;/li&gt;
&lt;li&gt;[ ] Railway: rotate every environment variable, registry credential and API token.&lt;/li&gt;
&lt;li&gt;[ ] OVHcloud CLI: if you installed 0.11‚Äì0.15 on 19 October, rotate your secrets and move to 0.16.0.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.php.net/" rel="noopener noreferrer"&gt;php.net ¬∑ 21 October security releases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thephp.foundation/blog/2026/10/21/todays-php-security-release-and-how-were-strengthening-php-security/" rel="noopener noreferrer"&gt;PHP Foundation ¬∑ Today's PHP Security Release, and How We're Strengthening PHP Security&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thenextweb.com/news/php-foundation-structural-failure-2024-flaw-leak" rel="noopener noreferrer"&gt;The Next Web ¬∑ PHP knew about one of the flaws in 2024 but could not agree a fix&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.wiz.io/blog/php2shell-php-rce" rel="noopener noreferrer"&gt;Wiz Research ¬∑ PHP2Shell&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/security/amazon-threat-intelligence-identifies-php2shell-exploitation-prior-to-public-disclosure-in-madpot/" rel="noopener noreferrer"&gt;AWS Security Blog ¬∑ PHP2Shell exploitation prior to public disclosure in MadPot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://watchtowr.com/intelligence/php-cve-2026-109618-faq/" rel="noopener noreferrer"&gt;watchTowr ¬∑ PHP2Shell FAQ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thehackernews.com/2026/10/php-issues-emergency-patches-for-two.html" rel="noopener noreferrer"&gt;The Hacker News ¬∑ PHP Issues Emergency Patches&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://almalinux.org/blog/2026-10-21-php2shell-cve-2026-109618-cve-2026-109619/" rel="noopener noreferrer"&gt;AlmaLinux ¬∑ Patched PHP packages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;packages.sury.org ¬∑ php7.4 7.4.33-31, php8.0 8.0.30-25, php8.1 8.1.34-9 (21 October builds, debian/changelog)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://openjdk.org/groups/vulnerability/advisories/2026-10-21" rel="noopener noreferrer"&gt;OpenJDK Vulnerability Advisory 2026/10/21&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thehackernews.com/2026/10/new-qpack-flaws-can-crash-http3-servers.html" rel="noopener noreferrer"&gt;The Hacker News ¬∑ New QPACK Flaws Can Crash HTTP/3 Servers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/en/blog/vulnerability/october-2026-security-releases" rel="noopener noreferrer"&gt;Node.js ¬∑ October 2026 Security Releases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://status.railway.com/incident/QH8L8B3E" rel="noopener noreferrer"&gt;Railway status ¬∑ QH8L8B3E&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.gitguardian.com/railway-october-2026-incident-environment-variables/" rel="noopener noreferrer"&gt;GitGuardian ¬∑ New Railway Incident&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bleepingcomputer.com/news/security/ovhcloud-cli-releases-backdoored-on-github-to-steal-developer-secrets/" rel="noopener noreferrer"&gt;BleepingComputer ¬∑ OVHcloud CLI releases backdoored on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://techcrunch.com/2026/10/21/the-internet-is-having-a-very-bad-cybersecurity-day/" rel="noopener noreferrer"&gt;TechCrunch ¬∑ The internet is having a very bad cybersecurity day&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://iamcanturk.dev/en/october-21-security-roundup-php2shell-java-node-railway-ovh/" rel="noopener noreferrer"&gt;iamcanturk.dev&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>php</category>
      <category>java</category>
      <category>node</category>
    </item>
    <item>
      <title>Two Critical RCEs in PHP: CVE-2026-109618 and CVE-2026-109619</title>
      <dc:creator>Can Türk</dc:creator>
      <pubDate>Wed, 21 Oct 2026 14:08:16 +0000</pubDate>
      <link>https://dev.to/iamcanturk/two-critical-rces-in-php-cve-2026-109618-and-cve-2026-109619-54h9</link>
      <guid>https://dev.to/iamcanturk/two-critical-rces-in-php-cve-2026-109618-and-cve-2026-109619-54h9</guid>
      <description>&lt;p&gt;On 21 October 2026 the PHP security team released versions that fix two critical vulnerabilities: &lt;strong&gt;8.5.12, 8.4.27, 8.3.36 and 8.2.35&lt;/strong&gt;. Both can allow unauthenticated remote code execution (RCE), and both are rated &lt;strong&gt;9.2&lt;/strong&gt; under CVSS v4.0. The release had been announced a day earlier; when details leaked the same day, the fix shipped slightly ahead of the planned time.&lt;/p&gt;

&lt;p&gt;This post explains both vulnerabilities based on the official advisories, sums up who is at risk and what helps until you can update, and ends with what I did on my own server, step by step. There are no attack instructions here; everything is written from the defender's side.&lt;/p&gt;

&lt;h2&gt;
  
  
  In short
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Vulnerabilities&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://www.cve.org/CVERecord?id=CVE-2026-109618" rel="noopener noreferrer"&gt;CVE-2026-109618&lt;/a&gt; (&lt;a href="https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w" rel="noopener noreferrer"&gt;GHSA-w8hw-w9fx-j79w&lt;/a&gt;): RCE via OOM corruption&lt;br&gt;&lt;a href="https://www.cve.org/CVERecord?id=CVE-2026-109619" rel="noopener noreferrer"&gt;CVE-2026-109619&lt;/a&gt; (&lt;a href="https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp" rel="noopener noreferrer"&gt;GHSA-6wmf-4rv5-p3rp&lt;/a&gt;): RCE via stale global state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CVSS v4.0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;9.2 (both) ¬∑ &lt;code&gt;AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CWE&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;CWE-416 (use after free), CWE-755, CWE-824, CWE-1325, CWE-1419&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Affected&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;All versions before 8.2.35, 8.3.36, 8.4.27 and 8.5.12&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Fixed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8.2.35 ¬∑ 8.3.36 ¬∑ 8.4.27 ¬∑ 8.5.12&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;At risk&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Every PHP installation serving web requests: PHP-FPM, Apache mod_php, php-cgi, FrankenPHP, LiteSpeed. Highest risk with mod_php.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Only complete fix&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Updating. Mitigations only close specific paths.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Timeline
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;When&lt;/th&gt;
&lt;th&gt;What happened&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;20 Oct&lt;/td&gt;
&lt;td&gt;php.net posted "Upcoming Critical PHP Security Release": two critical vulnerabilities, CVSS v4.0 9.2, release on 21 Oct at 14:00 UTC.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;20 Oct&lt;/td&gt;
&lt;td&gt;Details leaked. &lt;a href="https://sansec.io/research/php2shell" rel="noopener noreferrer"&gt;Sansec&lt;/a&gt; and &lt;a href="https://www.huntress.com/blog/php2shell-leaked-critical-php-vulnerabilities" rel="noopener noreferrer"&gt;Huntress&lt;/a&gt; published warnings the same day; the leak circulated as "php2shell".&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;21 Oct 13:34 UTC&lt;/td&gt;
&lt;td&gt;The two GitHub Security Advisories were published.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;21 Oct 13:48 UTC&lt;/td&gt;
&lt;td&gt;The PHP CNA published both CVE records.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;21 Oct&lt;/td&gt;
&lt;td&gt;8.5.12, 8.4.27, 8.3.36 and 8.2.35 were released. Linux distributions and LTS vendors received the patches in advance.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  CVE-2026-109618: request memory left half-initialized by OOM
&lt;/h2&gt;

&lt;p&gt;When PHP runs out of memory (OOM), it uses &lt;code&gt;longjmp()&lt;/code&gt; to leave the current context and abort the request. According to the &lt;a href="https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w" rel="noopener noreferrer"&gt;advisory&lt;/a&gt;, in some contexts request memory becomes reachable before it is fully initialized. If any allocation fails at that moment, PHP doesn't account for the early exit and leaves the request memory in an invalid state. The failed allocation doesn't even need to be related to that memory. The request shutdown procedure may then read or branch on the invalid data.&lt;/p&gt;

&lt;p&gt;The attacker's job is to push a request into OOM while it stays within PHP's apparent limits. The advisory lists several multipart parsing paths that make this possible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A multipart request without a usable &lt;code&gt;Content-Length&lt;/code&gt; can pass the initial &lt;code&gt;post_max_size&lt;/code&gt; check and keep supplying decoded body data.&lt;/li&gt;
&lt;li&gt;A multipart part can carry an unlimited number of headers, and their in-memory representation uses far more memory than their size on the wire.&lt;/li&gt;
&lt;li&gt;Empty file controls don't count toward &lt;code&gt;max_file_uploads&lt;/code&gt; but still create file metadata arrays, and nested field names multiply that work.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  It depends on the SAPI
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Apache mod_php:&lt;/strong&gt; shutdown always runs, even when request startup failed. Automatic body parsing can hit the memory limit at exactly that invalid moment, and all of this happens &lt;strong&gt;before any application code runs&lt;/strong&gt;. Full RCE was validated over HTTP against mod_php with default PHP input and memory limits.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PHP-FPM:&lt;/strong&gt; when startup fails, FPM exits the child, so the invalid state is never consumed. OOM can still be reached after normal startup, though. Source analysis supports FPM as susceptible; no complete FPM exploit has been demonstrated.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FrankenPHP:&lt;/strong&gt; like mod_php, it calls shutdown unconditionally, so it is likely open to application-independent attacks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LSAPI:&lt;/strong&gt; modeled on FPM; application-specific exploits are likely but unvalidated.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The patch removes the &lt;code&gt;longjmp()&lt;/code&gt; OOM exit. It is replaced by a graceful soft OOM at the next VM safe point, plus an immediate hard OOM via &lt;code&gt;_exit()&lt;/code&gt; if memory reaches a second, higher threshold.&lt;/p&gt;

&lt;h2&gt;
  
  
  CVE-2026-109619: stale state carried from one request to the next
&lt;/h2&gt;

&lt;p&gt;A PHP worker handles many requests in sequence. Some global state (error, session, object and extension state) stays in the worker but points to memory owned by one request. According to the &lt;a href="https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp" rel="noopener noreferrer"&gt;advisory&lt;/a&gt;, that state must be reset before the request memory is released. If it isn't, some operations that run before normal initialization of the next request touch freed memory: a classic use after free.&lt;/p&gt;

&lt;p&gt;Exploitation needs two pieces:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;A producer:&lt;/strong&gt; an operation that stores request-owned state globally and skips its reset because of a fatal error or OOM. Parse failures, uncaught errors, a failing &lt;code&gt;require&lt;/code&gt; and &lt;code&gt;Maximum execution time exceeded&lt;/code&gt; are examples of such interruptions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A consumer:&lt;/strong&gt; an operation in a later request on the same worker that reads the stale value before normal initialization.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The advisory confirms two consumers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;INI diagnostics before request initialization.&lt;/strong&gt; If an invalid or deprecated setting raises a warning during startup, the stale error state is used. The warning doesn't need to be displayed or logged, so &lt;code&gt;error_reporting&lt;/code&gt;, &lt;code&gt;@&lt;/code&gt; and &lt;code&gt;display_errors&lt;/code&gt; give no protection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Session upload progress.&lt;/strong&gt; Upload progress touches session handling before ordinary session initialization and can use session state left by an interrupted request.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two concrete cases are confirmed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;fatal_error_backtraces&lt;/code&gt; on PHP 8.5:&lt;/strong&gt; when enabled, fatal error reporting stores a request-owned backtrace that shutdown never resets. The confirmed mod_php exploit is built on this.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The session upload progress lifecycle:&lt;/strong&gt; with mod_php, the producer and the fatal error can both happen during multipart startup. On FPM the validated path is different: state is published while the application runs, a fatal error follows, and upload progress acts as the early consumer. It works on a normal dynamic FPM pool but depends on a suitable application operation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When is the INI path open on FPM?
&lt;/h3&gt;

&lt;p&gt;According to the advisory, &lt;code&gt;php.ini&lt;/code&gt; and FPM pool values are applied when a worker starts, and &lt;code&gt;.user.ini&lt;/code&gt; after normal initialization, so they don't provide an early consumer. But if nginx or Apache &lt;code&gt;mod_proxy_fcgi&lt;/code&gt; sends &lt;code&gt;PHP_VALUE&lt;/code&gt; / &lt;code&gt;PHP_ADMIN_VALUE&lt;/code&gt; parameters to FPM and those values raise a diagnostic before initialization, FPM is exposed through this path too.&lt;/p&gt;

&lt;p&gt;Panels like CloudPanel send &lt;code&gt;fastcgi_param PHP_VALUE&lt;/code&gt; to every site with values like &lt;code&gt;memory_limit&lt;/code&gt;, &lt;code&gt;post_max_size&lt;/code&gt; and &lt;code&gt;date.timezone&lt;/code&gt;. Valid values raise no diagnostic. A deprecated or invalid one raises the risk.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who is at risk?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Highest:&lt;/strong&gt; Apache mod_php and FrankenPHP. The attack can run before application code and independently of the application.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Moderate:&lt;/strong&gt; PHP-FPM and LSAPI. There are validated paths, but most depend on the application or configuration. That is not a reason to delay the update.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;8.1 and older:&lt;/strong&gt; the PHP project no longer ships updates for these. As an exception, minimal source backports were published for people building 7.4, 8.0 and 8.1 from source (&lt;a href="https://github.com/php/php-src/tree/PHP-7.4-CVE-2026-109618-109619" rel="noopener noreferrer"&gt;PHP-7.4&lt;/a&gt;, &lt;a href="https://github.com/php/php-src/tree/PHP-8.0-CVE-2026-109618-109619" rel="noopener noreferrer"&gt;PHP-8.0&lt;/a&gt;, &lt;a href="https://github.com/php/php-src/tree/PHP-8.1-CVE-2026-109618-109619" rel="noopener noreferrer"&gt;PHP-8.1&lt;/a&gt; branches). If you use distribution packages, ask your vendor or move to a supported version.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;8.2:&lt;/strong&gt; reaches end of life on 31 December 2026. Install this fix, then plan the upgrade.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The impact is code execution as the web worker account: an attacker could run commands on your server with the privileges of the user PHP runs as.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to check your server
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Installed versions and package versions (Debian/Ubuntu)&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; /etc/php/
php &lt;span class="nt"&gt;-v&lt;/span&gt;
dpkg &lt;span class="nt"&gt;-l&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s1"&gt;'^ii  php[0-9.]+-(fpm|cli|common) '&lt;/span&gt;

&lt;span class="c"&gt;# FPM services that are actually running&lt;/span&gt;
systemctl list-units &lt;span class="nt"&gt;--type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;service &lt;span class="s1"&gt;'php*-fpm*'&lt;/span&gt;

&lt;span class="c"&gt;# Is Apache mod_php loaded? (highest risk)&lt;/span&gt;
apache2ctl &lt;span class="nt"&gt;-M&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; php

&lt;span class="c"&gt;# Does the web server send PHP_VALUE to FPM?&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt; &lt;span class="s2"&gt;"PHP_VALUE&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;PHP_ADMIN_VALUE"&lt;/span&gt; /etc/nginx/ /etc/apache2/ 2&amp;gt;/dev/null

&lt;span class="c"&gt;# Is a fixed version in your repository yet?&lt;/span&gt;
apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-cache policy php8.4-fpm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CLI and FPM settings can differ. Use &lt;code&gt;php-fpm8.4 -i&lt;/code&gt; to see what FPM actually uses.&lt;/p&gt;

&lt;h2&gt;
  
  
  Updating
&lt;/h2&gt;

&lt;p&gt;Distributions and LTS vendors received the patches in advance, so distribution packages should arrive quickly. The advisory adds two notes: the volunteer-maintained &lt;strong&gt;rpms.remirepo.net repository will not have updates today&lt;/strong&gt;, so switch to distribution packages or build from source if you rely on it. Windows binaries are on the php.net downloads page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Record your sites' status first&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;d &lt;span class="k"&gt;in &lt;/span&gt;site1.com site2.com&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$d&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s1"&gt;'%{http_code}'&lt;/span&gt; https://&lt;span class="nv"&gt;$d&lt;/span&gt;/&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;done&lt;/span&gt;

&lt;span class="c"&gt;# Upgrade only the installed PHP packages, keep config files&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;span class="nb"&gt;sudo &lt;/span&gt;&lt;span class="nv"&gt;DEBIAN_FRONTEND&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;noninteractive apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--only-upgrade&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; Dpkg::Options::&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;--force-confold&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;dpkg &lt;span class="nt"&gt;-l&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'/^ii  php/{print $2}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Verify&lt;/span&gt;
php8.4 &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;php-fpm8.4 &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; systemctl is-active php8.4-fpm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Docker:&lt;/strong&gt; pin the official &lt;code&gt;php&lt;/code&gt; image to the fixed version (for example &lt;code&gt;php:8.4.27-fpm&lt;/code&gt;) and recreate the containers. Floating tags like &lt;code&gt;8.4-fpm&lt;/code&gt; only update after a &lt;code&gt;docker pull&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shared hosting:&lt;/strong&gt; if you have no server access, write to your provider today and ask which version you are on and when the fix will be installed.&lt;/p&gt;

&lt;h2&gt;
  
  
  If you can't update yet: the official mitigations
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://www.php.net/archive/2026.php#2026-10-21-5" rel="noopener noreferrer"&gt;php.net advisory&lt;/a&gt; is explicit: these only reduce exposure to specific attack paths and don't make an installation safe.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For CVE-2026-109618 (OOM):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set &lt;code&gt;memory_limit=-1&lt;/code&gt; and enforce it where applications can't override it, such as &lt;code&gt;php_admin_value&lt;/code&gt; in the FPM pool. Check that no pool, directory or application setting restores a finite limit. This removes the controllable OOM, but an underlying &lt;code&gt;mmap()&lt;/code&gt; failure can still reach the same path. Unlimited memory is also a denial of service risk on a shared server, so do it deliberately.&lt;/li&gt;
&lt;li&gt;Keep &lt;code&gt;post_max_size&lt;/code&gt; low: 8M for applications that don't take uploads, 32M if they do. Keep &lt;code&gt;upload_max_filesize&lt;/code&gt; below it.&lt;/li&gt;
&lt;li&gt;At the web server or proxy, limit decoded request size, input field count, multipart part count, header count and nesting depth, including requests without a usable &lt;code&gt;Content-Length&lt;/code&gt;. If your application doesn't use multipart forms, block them before they reach PHP.&lt;/li&gt;
&lt;li&gt;A container or cgroup memory limit can act as an availability boundary. &lt;strong&gt;Don't&lt;/strong&gt; use &lt;code&gt;RLIMIT_AS&lt;/code&gt; or &lt;code&gt;RLIMIT_DATA&lt;/code&gt;: they cause exactly the allocation failure that triggers the vulnerable path.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;For CVE-2026-109619 (stale state):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set &lt;code&gt;session.upload_progress.enabled=0&lt;/code&gt; and &lt;strong&gt;restart every worker&lt;/strong&gt;. Put it in php.ini, an FPM pool or server configuration applied before request parsing. &lt;code&gt;ini_set()&lt;/code&gt; and FPM &lt;code&gt;.user.ini&lt;/code&gt; don't work. This blocks the confirmed session paths, not other variants.&lt;/li&gt;
&lt;li&gt;On PHP 8.5, set &lt;code&gt;fatal_error_backtraces=0&lt;/code&gt; and restart every worker. This blocks only the confirmed backtrace path.&lt;/li&gt;
&lt;li&gt;Remove invalid or deprecated settings applied per request (&lt;code&gt;.htaccess&lt;/code&gt;, Apache &lt;code&gt;php_value&lt;/code&gt;, nginx &lt;code&gt;PHP_VALUE&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Fix fatal errors and execution timeouts an attacker can trigger, including in callbacks, upload or import processing and cleanup.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;; /etc/php/8.5/fpm/conf.d/99-mitigation.ini
&lt;/span&gt;&lt;span class="py"&gt;session.upload_progress.enabled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;0&lt;/span&gt;
&lt;span class="py"&gt;fatal_error_backtraces&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;0   ; PHP 8.5 only&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;php-fpm8.5 &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl reload php8.5-fpm
php-fpm8.5 &lt;span class="nt"&gt;-i&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s1"&gt;'^(session.upload_progress.enabled|fatal_error_backtraces)'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Does a Cloudflare rule help?
&lt;/h3&gt;

&lt;p&gt;A Cloudflare WAF rule shared after the leak blocks requests whose body carries a &lt;code&gt;PHP_SESSION_UPLOAD_PROGRESS&lt;/code&gt; field:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;any(http.request.body.form.names[*] == "PHP_SESSION_UPLOAD_PROGRESS")
or http.request.body.raw contains "PHP_SESSION_UPLOAD_PROGRESS"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Action: &lt;strong&gt;Block&lt;/strong&gt;. But it only targets the upload progress consumer; it doesn't cover the OOM vulnerability or the INI path. It has two more limits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cloudflare only inspects the first part of the request body. If the field comes later, the rule misses it.&lt;/li&gt;
&lt;li&gt;If your server can be reached directly by its IP address, the attacker never passes through Cloudflare.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I tested the second one on my own server, and every site, including my own, opened directly by IP. My main site looked closed at first because the server uses a self-signed certificate and &lt;code&gt;curl&lt;/code&gt; refused the connection. With &lt;code&gt;-k&lt;/code&gt; it returned 200. An attacker won't care about the certificate either:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sk&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s2"&gt;"%{http_code}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;--resolve&lt;/span&gt; yoursite.com:443:SERVER_IP https://yoursite.com/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If that returns 200, your origin is exposed. Accept only &lt;a href="https://www.cloudflare.com/ips/" rel="noopener noreferrer"&gt;Cloudflare's IP ranges&lt;/a&gt; on the server, or use Authenticated Origin Pulls.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I did on my own server
&lt;/h2&gt;

&lt;p&gt;My server runs CloudPanel on Ubuntu 26.04. Every site runs on PHP-FPM behind nginx; there is no Apache or mod_php.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Time (UTC+3)&lt;/th&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;11:26&lt;/td&gt;
&lt;td&gt;Inventory: ten versions installed, from 7.1 to 8.5, but only the 8.4 and 8.5 FPM services running. Versions 8.4.22 and 8.5.9.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11:26&lt;/td&gt;
&lt;td&gt;The real surprise: on 8.4 I was already three security releases behind before the emergency fix (8.4.23, 8.4.24, 8.4.26).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11:59&lt;/td&gt;
&lt;td&gt;Recorded the HTTP status of every site, then installed the latest available releases: 8.4.26 and 8.5.11 (188 packages, over half an hour). Every site answered the same as before.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12:01&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;session.upload_progress.enabled=0&lt;/code&gt; on 8.4 and 8.5, FPM reloaded.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16:48&lt;/td&gt;
&lt;td&gt;Read the advisories. nginx sends &lt;code&gt;PHP_VALUE&lt;/code&gt; to every site; all values are valid and there is no &lt;code&gt;open_basedir&lt;/code&gt;, so they raise no INI diagnostic.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16:48&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;fatal_error_backtraces&lt;/code&gt; was on in 8.5. Turned it off, reloaded FPM, checked the sites again.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pending&lt;/td&gt;
&lt;td&gt;CloudPanel's package repository doesn't have 8.4.27 and 8.5.12 yet. I'll install them the moment they land and update this post.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I didn't apply &lt;code&gt;memory_limit=-1&lt;/code&gt;. There are several sites on this server, and unlimited memory would let one bad request slow down all of them. No complete FPM exploit has been demonstrated and the package is close, so I decided against it. On mod_php I would have decided differently.&lt;/p&gt;

&lt;p&gt;I also covered this in a short video (in Turkish): &lt;a href="https://iamcanturk.dev/en/shorts/php-acil-yama/" rel="noopener noreferrer"&gt;Pixel Shorts ¬∑ Emergency patch for PHP&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Credits
&lt;/h2&gt;

&lt;p&gt;According to the advisories, the vulnerabilities were reported by lcfr-hax, sagitzadik-wiz, tomash-areion and amyb-oai. The fixes were developed by arnaud-lb, iluuu1994, bukka and ndossche.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.php.net/archive/2026.php#2026-10-21-5" rel="noopener noreferrer"&gt;php.net: Security advisory, critical remote code execution vulnerabilities (21 Oct 2026)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w" rel="noopener noreferrer"&gt;GHSA-w8hw-w9fx-j79w: RCE via OOM corruption (CVE-2026-109618)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp" rel="noopener noreferrer"&gt;GHSA-6wmf-4rv5-p3rp: RCE via stale global state (CVE-2026-109619)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.cve.org/CVERecord?id=CVE-2026-109618" rel="noopener noreferrer"&gt;CVE-2026-109618 record&lt;/a&gt; ¬∑ &lt;a href="https://www.cve.org/CVERecord?id=CVE-2026-109619" rel="noopener noreferrer"&gt;CVE-2026-109619 record&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.php.net/ChangeLog-8.php" rel="noopener noreferrer"&gt;PHP 8 ChangeLog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.php.net/archive/2026.php" rel="noopener noreferrer"&gt;php.net: Upcoming Critical PHP Security Release (20 Oct 2026)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://sansec.io/research/php2shell" rel="noopener noreferrer"&gt;Sansec: php2shell&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.huntress.com/blog/php2shell-leaked-critical-php-vulnerabilities" rel="noopener noreferrer"&gt;Huntress: php2shell, leaked critical PHP vulnerabilities&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/http.request.body.form.names/" rel="noopener noreferrer"&gt;Cloudflare Rules language: http.request.body.form.names&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://iamcanturk.dev/en/php2shell-critical-php-rce/" rel="noopener noreferrer"&gt;iamcanturk.dev&lt;/a&gt;. I wrote this post together with Claude Code.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>php</category>
      <category>webdev</category>
      <category>devops</category>
    </item>
    <item>
      <title>I Turned My Personal Site Into a Building</title>
      <dc:creator>Can Türk</dc:creator>
      <pubDate>Tue, 20 Oct 2026 20:17:10 +0000</pubDate>
      <link>https://dev.to/iamcanturk/i-turned-my-personal-site-into-a-building-4goi</link>
      <guid>https://dev.to/iamcanturk/i-turned-my-personal-site-into-a-building-4goi</guid>
      <description>&lt;p&gt;My old site was a WordPress theme. It did the job, but it didn't feel like me. When I sat down to rebuild it, I asked myself one question: what should someone feel in the first three seconds?&lt;/p&gt;

&lt;p&gt;The answer was simple: that they had &lt;em&gt;walked into&lt;/em&gt; somewhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  The idea: a building you can see inside
&lt;/h2&gt;

&lt;p&gt;The homepage is now a menu and, below it, six rooms that fill the screen. The notebook is a library, Pixel Shorts is a studio, my projects live in a workshop, my security research sits in a SOC, the about page is my own room, and contact is a café.&lt;/p&gt;

&lt;p&gt;Click a room and a pixel version of me walks over to it. If it's on another floor, he takes the elevator on the right. When he arrives, the screen dissolves into pixels and the page opens, with the same room as its header, so you really feel like you stepped inside.&lt;/p&gt;

&lt;p&gt;It didn't start this way. The first version was a tall building, and the scrolling never ended. The second fit the building on one screen, but the text I put next to it made everything feel crowded. What survived is the simplest version: a menu, the rooms, a footer. Nothing else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Small details I love
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Day and night.&lt;/strong&gt; In dark mode the rooms are dim, and on your first visit the lights switch on one by one. Flip to light mode and the whole building turns to day in place, with sunlight pouring through the windows. The mascot waits in the room I'm &lt;em&gt;probably&lt;/em&gt; in right now, based on the time in Bursa: the SOC in the afternoon, the studio in the evening, the library late at night.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rooms that are alive.&lt;/strong&gt; The library lamp flickers, rain runs down the café window, the espresso machine steams, and the dots on the SOC's world map blink. Every effect is pinned to the illustration's own coordinates, so even when a room is cropped to fit your screen, the lamp glow stays on the lamp.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The studio TV.&lt;/strong&gt; It shows the poster of the latest Pixel Shorts episode. What comes next stays a surprise until it airs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bugs on the SOC floor.&lt;/strong&gt; Click them and they get squashed. A security person's site needed this.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;In a hurry?&lt;/strong&gt; Click again while the mascot is walking and you go straight there. With reduced motion turned on, there's no animation at all.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Under the hood
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Astro, fully static.&lt;/strong&gt; No database, no admin panel, no code running on the server. Posts are Markdown files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tiny5 for headings.&lt;/strong&gt; In most pixel fonts I tried, the "C" read like an "O". Tiny5 didn't, so I subset it down to the characters I actually use (4.6 KB).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Two languages.&lt;/strong&gt; Turkish at the root, English under &lt;code&gt;/en/&lt;/code&gt;. Visitors from outside Turkey land on the English homepage; if they switch languages themselves, that choice is remembered.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Friendly to AI.&lt;/strong&gt; Add &lt;code&gt;.md&lt;/code&gt; to the end of any page and you get a plain-text version. There's an &lt;code&gt;llms.txt&lt;/code&gt; summary, and AI crawlers are welcome.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploys.&lt;/strong&gt; My own VPS behind Cloudflare. Every ten minutes the server checks the repo; if there's a new commit, or a Pixel Shorts episode whose time has come, it rebuilds the site and pings search engines through IndexNow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;And a trap.&lt;/strong&gt; Bots probing addresses like &lt;code&gt;/wp-admin&lt;/code&gt; get a fake login page instead. Nobody gets banned; they just get mocked, and I keep a log.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The illustrations and AI
&lt;/h2&gt;

&lt;p&gt;The mascot, the rooms and the walk cycle were generated with AI (gpt-image), then cleaned up and cut by hand. The concept, the interactions and the code are mine; I wrote the code together with Claude Code. I don't see a reason to hide that: this site is about software, security and AI in the first place.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;Pixel Shorts starts on October 20th, and after that a new episode will land on the studio TV every day. The episodes are in Turkish, but every one has an English transcript on the site. The building may get new rooms, too. If you have an idea, drop by the café.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://iamcanturk.dev/en/i-turned-my-site-into-a-building/" rel="noopener noreferrer"&gt;iamcanturk.dev&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>astro</category>
      <category>pixelart</category>
      <category>showdev</category>
    </item>
    <item>
      <title>I Wrote a Doctor for My Docker</title>
      <dc:creator>Can Türk</dc:creator>
      <pubDate>Fri, 14 Aug 2026 20:20:52 +0000</pubDate>
      <link>https://dev.to/iamcanturk/i-wrote-a-doctor-for-my-docker-2o9k</link>
      <guid>https://dev.to/iamcanturk/i-wrote-a-doctor-for-my-docker-2o9k</guid>
      <description>&lt;p&gt;&lt;em&gt;Because for months I didn't really know what was running on my machine.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;One evening, at the end of a long day, I typed &lt;code&gt;docker ps&lt;/code&gt; and just stared at the output for a while. Twenty-six containers. I remembered what some of them were for; the rest were things I'd spun up months ago with a quick "let me just try this" and then forgotten. Then I typed &lt;code&gt;docker images&lt;/code&gt;: thirteen gigabytes. Layers nobody pulls anymore, images that had long since stopped mattering.&lt;/p&gt;

&lt;p&gt;That was the moment I admitted something uncomfortable: I used Docker every day, but I didn't actually know what was running inside it.&lt;/p&gt;

&lt;p&gt;Docker is a strange tool that way. It makes running something extraordinarily easy, and noticing what you're running just as hard. Six months into a project, the average developer's machine has quietly accumulated the same things: a container with the Docker socket mounted into it, a couple of databases published to &lt;code&gt;0.0.0.0&lt;/code&gt;, a dozen services running as root, and gigabytes of images nothing references. None of it sets off an alarm — not until something breaks, or someone decides to scan you.&lt;/p&gt;

&lt;h2&gt;
  
  
  The existing tools don't fill this gap
&lt;/h2&gt;

&lt;p&gt;Don't get me wrong, there are good tools. Trivy and Grype find CVEs in your images perfectly well. But they need a vulnerability database, and therefore a network, and what they look at is the packages &lt;em&gt;inside&lt;/em&gt; the image. That wasn't my problem. My problem was the &lt;strong&gt;configuration layer&lt;/strong&gt;: how I was running the container. &lt;code&gt;docker system df&lt;/code&gt; tells you disk usage but has no opinion about it; it won't say "nothing touches this volume anymore."&lt;/p&gt;

&lt;p&gt;What I wanted was a tool that answered one question: &lt;strong&gt;what is wrong with this Docker environment right now, and what should I do about it?&lt;/strong&gt; I couldn't find it, so I wrote it.&lt;/p&gt;

&lt;h2&gt;
  
  
  DoctorDock
&lt;/h2&gt;

&lt;p&gt;DoctorDock is a small command-line tool that scans your local Docker environment — with a native macOS menubar app alongside it. It finds the security problems, the misconfigurations, and the reclaimable disk, and leaves you with a health score out of 100. I wrote it in Go; single binary, no account, MIT license.&lt;/p&gt;

&lt;p&gt;To be concrete about speed: on my machine, a full scan of roughly 26 containers, 29 images, 29 volumes, and 12 networks takes about 550 ms. That's less time than it takes to read the output of &lt;code&gt;docker ps&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three decisions I made
&lt;/h2&gt;

&lt;p&gt;I decided three things up front while writing this. All three might look like missing features. I'd argue it's the opposite.&lt;/p&gt;

&lt;h3&gt;
  
  
  No AI
&lt;/h3&gt;

&lt;p&gt;I could have made this an "AI-powered security product." I didn't. Every finding is deterministic Go you can read; the same environment always produces the same output. If you wonder why a rule flagged something, you can go read the source. I don't want a security tool telling me "this might be insecure" — either it is, or it isn't.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fully offline
&lt;/h3&gt;

&lt;p&gt;Zero network calls. No telemetry, no account, no update check. DoctorDock opens exactly one local socket — Docker's — and nothing else. It runs the same on an air-gapped machine and in a locked-down CI runner. What you scan stays with you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Secrets stay put
&lt;/h3&gt;

&lt;p&gt;I read container environment variables as key &lt;strong&gt;names&lt;/strong&gt; only; their values never enter memory in a form that could reach a report. You'll see that a key called &lt;code&gt;DATABASE_PASSWORD&lt;/code&gt; exists — never its value. That's what makes it safe to point at production, which for a security tool should be the default, not a selling point.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it looks like
&lt;/h2&gt;

&lt;p&gt;There's nothing to do but install it and scan:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;iamcanturk/tap/doctordock
doctordock scan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output gives your environment a score and lists the findings worst-first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HEALTH SCORE  37/100  poor

  1 CRITICAL · 17 HIGH · 6 MEDIUM · 22 LOW

  DD005  CRITICAL  Docker socket mounted into a container
  DD001  HIGH      Container runs as root
  DD006  MEDIUM    Database port published on 0.0.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see 37/100, don't panic; most developer machines start somewhere around there on the first scan. What matters is that the list is finally visible. And every rule explains itself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;doctordock explain DD005
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That prints what the rule looks for, why it matters, a worked attack scenario, a copy-pasteable fix, and an honest note on when it's fine to ignore. It doesn't stop at "there's a problem here" — it teaches you how to close it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp4zik3kmk1981rulenqn.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp4zik3kmk1981rulenqn.gif" alt="DoctorDock in the terminal: the command list, then doctordock explain DD005" width="800" height="556"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The part I worried about most: cleanup
&lt;/h2&gt;

&lt;p&gt;Honestly, cleanup is the part I was most nervous about while writing this — because one wrong command can wipe out someone's month of data. So DoctorDock deletes nothing by default:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;doctordock cleanup            &lt;span class="c"&gt;# dry run: only shows what it would remove&lt;/span&gt;
doctordock cleanup &lt;span class="nt"&gt;--apply&lt;/span&gt;    &lt;span class="c"&gt;# actually removes it&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And no flag except &lt;code&gt;--volumes&lt;/code&gt; can select a volume — not even &lt;code&gt;--all&lt;/code&gt;. You can re-pull an image and re-create a network; but when the data in a volume is gone, it's gone. So volumes only ever enter the picture when you ask for them explicitly, on their own. Nothing is deleted by accident.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;DoctorDock isn't a big product; it's a small, honest tool. It puts the things your Docker environment quietly accumulated over months in front of you in under a second, without leaking any of it. Like a doctor: it looks, it diagnoses, it tells you what to do — and it leaves the decision to you.&lt;/p&gt;

&lt;p&gt;If you're curious, run a scan and see what your machine actually scores. It'll probably come out lower than you think — but for the first time, you'll know exactly what to do about it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code: &lt;a href="https://github.com/iamcanturk/DoctorDock" rel="noopener noreferrer"&gt;github.com/iamcanturk/DoctorDock&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Download and details: &lt;a href="https://doctordock.iamcanturk.dev" rel="noopener noreferrer"&gt;doctordock.iamcanturk.dev&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>go</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
