NCSC-NL

Activity

Stars and mentions · Last 30 days, Oct 6 – Nov 4

GitHub stars194
Mentions24
011223344Oct 6Oct 20Nov 4
UTC days · repositories NCSC-NL owns3 repositories

Top repositories

NCSC-NL’s repositories ranked by new stars, as on trending.

Loading

Contributes to

Repositories outside NCSC-NL’s account where NCSC-NL opened or reviewed pull requests in the past 365 days.

Who noticed NCSC-NL

Everyone who starred or forked NCSC-NL’s repositories since the archive began in 2011.

Notable accounts

Ordered by the stars their own repositories have received.

Biggest fans

Accounts that starred the most of these repositories.

Breakout weeks

Each repository’s best week of new stars, with the release published around it.

Mentions

24posts
Nov 50 posts
  1. PHP2Shell, Explained: What the Critical PHP Vulnerability Means for Your Servers If you run anything on PHP, the last couple of weeks have been noisy. On 21 October the PHP project shipped emergency fixes for two critical bugs, nicknamed PHP2Shell, and the reaction has swung between "this is Log4Shell for the web" and "relax, the public exploits don't even work." Both camps have a point. I'm Adnan Shakir, Head of Technical Development at Grafdom, a web agency in Dubai. This is my attempt to separate what's confirmed from what's hype, explain how the bugs actually work, and give you something practical to run on your own servers. Everything below is accurate as of 4 November 2026, and the sources are linked at the end. TL;DR - PHP2Shell is two flaws in PHP itself, CVE-2026-109618 and CVE-2026-109619. Both are rated 9.2 (CVSS v4.0) and can allow unauthenticated remote code execution (RCE). - The fixed versions are PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35, released on 21 October 2026. PHP 8.1 and older get no official release, though the PHP team published minimal source backports for 7.4, 8.0 and 8.1. - It's a runtime problem. Updating WordPress, a plugin or a theme won't fix it. WordPress.org said no WordPress update is required or planned. - Exploitation is real: CISA added both CVEs to its Known Exploited Vulnerabilities (KEV) catalogue on 26 October. But turning the bugs into reliable attacks on a random public site is hard, and a lot of the proof-of-concept code floating around doesn't work. - Only patching fixes it. Config flags and WAF rules are stopgaps. - In the UAE, Censys flagged 4,691 internet-facing hosts as potentially exposed on 25 October. The timeline, short version - 17 October: Amazon's honeypots log the first exploitation attempt, four days before disclosure. - 20 October: The CVE IDs leak online, with a wrong release date and an inflated severity score. PHP announces an emergency release. - 21 October: Cloudflare reports early attacks (07:43 UTC). PHP ships 8.5.12, 8.4.27, 8.3.36 and 8.2.35. Researchers from Calif, Wiz and OpenAI disclose. - 24 October: Perplexity's Adel Karimi reports the first confirmed code execution against honeypot servers. - 26 October: CISA adds both CVEs to the KEV catalogue. Five days earlier it had said it hadn't seen exploitation. - 27 October: TU Delft's threat intelligence lab reports 50,000+ exploitation requests from 600+ IP addresses in 70 countries. - 29 October onward: Palo Alto Networks warns of active exploitation against internet-exposed PAN-OS management interfaces. Singapore's CSA issues an advisory on 3 November. The two bugs, in plain technical English This is a simplified version of the root-cause analysis in Datadog's write-up, which is worth reading in full. CVE-2026-109618: out-of-memory corruption. PHP parses the incoming request before any of your code runs. While it builds the $_POST array, it bumps the hash table's element counters before it allocates the new key. If that allocation pushes past memory_limit, PHP throws a fatal error and leaves behind a bucket that's counted but never initialised. At request shutdown PHP destroys the array and trusts that bucket. With the right leftover heap bytes, an attacker can turn it into a fake array with a destructor callback pointed at something like system(). The catch for attackers: they have to size a field name so the memory limit is blown at exactly the right moment, groom the heap, and defeat ASLR. Wiz described a memory-disclosure trick using the PHPSESSID cookie to leak addresses. CVE-2026-109619: stale state across requests. Some worker-wide fields point at memory that belongs to a single request. If that memory is freed without clearing the pointer (because a fatal error interrupted the reset, or a late diagnostic recreated state after cleanup), the next request handled by the same worker can follow a stale pointer. That's a use-after-free. Researchers confirmed two paths: - Fatal-error backtraces (PHP 8.5 only), confirmed on mod_php. - Upload processing, confirmed on mod_php and PHP-FPM. On FPM the application also has to perform a suitable operation after startup. Session upload progress is enabled by default and runs even if your app never calls session_start(), which is why session.upload_progress.enabled keeps showing up in mitigation advice. This bug also needs the attacker's requests to land on the same worker, so a bigger worker pool lowers the odds per attempt without removing the flaw. Why it's nasty. The vulnerable code runs before your application does. Authentication, nonces and custom hardening never get a chance. A tightly locked-down custom app is exactly as exposed as a default WordPress install running the same PHP. It probably isn't the last one. The authors describe the root cause as a pattern: a memory error interrupts an operation, then cleanup trusts half-built state. They expect more instances, including possible unpatched variants on older branches. AI found it. Researchers at Wiz, Calif and OpenAI used AI tools in the discovery. Wiz's take is that the flaws had sat in the code for years, and frontier AI models lowered the barrier to proving they were exploitable. Whether that's a one-off or the new normal, patch windows are getting shorter: remember that Amazon logged the first attempt four days before disclosure. Who's actually exposed - Any PHP runtime that serves web requests. PHP's advisory names PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed. mod_php is rated highest risk because an unauthenticated request can trigger the bug before application code runs. Containers and apps that bundle their own interpreter count too, and php -v on the command line can differ from what your web server actually runs. - Affected releases go back to PHP 5.4. The fixes are in 8.2.35, 8.3.36, 8.4.27 and 8.5.12. PHP 8.1 and older get no official release. The PHP team published minimal source backports for 7.4, 8.0 and 8.1, and many vendors ship their own backports, sometimes without changing the version number. - Appliances and bundled PHP. If a vendor product embeds PHP, you may not be able to patch it yourself. The Dutch NCSC's operational inventory tracked 757 products as of 28 October: 144 fixed, 218 vulnerable, 354 still under investigation. Singapore's CSA lists PAN-OS, some Cisco, Citrix NetScaler, F5 BIG-IP and Siemens RUGGEDCOM products among the affected. - WordPress, Drupal, Joomla, Magento, Laravel. They all run on PHP, so they're all exposed if the runtime underneath is vulnerable. WordPress.org was explicit: no WordPress update is required or planned, the fix is the PHP update. Big hosts moved fast (GoDaddy patched managed WordPress on 21 October and standard web hosting on 22 October), but GoDaddy also warned that your PHP version number may not change after the fix. Ask your host for confirmation rather than eyeballing the number. Is it actually being exploited? Yes, but not like the headlines say What's confirmed - Attempts began before the fix. Amazon's honeypots logged the first one on 17 October, and Cloudflare reported early attacks on 21 October, hours before release. - Working exploitation exists. Perplexity's Adel Karimi reported code execution against honeypots on 24 October. His findings were consistent with CVE-2026-109618, with no evidence the second bug was involved. CISA then added both CVEs to KEV on 26 October. - The volume is high. TU Delft's team counted 50,000+ exploitation requests from 600+ IPs across 70 countries. - Real products are being hit. Palo Alto Networks warned of active exploitation against internet-exposed PAN-OS management interfaces. Dream Research reported a campaign that chained PHP2Shell with a Linux kernel privilege-escalation flaw (CVE-2026-46300) to root 25 servers in the US, Japan, Taiwan and South Korea. Note the chain: PHP2Shell was the door, the kernel bug was the second step. What's shakier - Unit 42 walked back a headline. On 23 October it reported an AI-agent-assisted intrusion at a European government agency. On 25 October it retracted that, saying it couldn't confirm initial access was tied to PHP2Shell. - "AI-powered attacks" is unproven so far. Dream found AI tooling in the attacker's infrastructure but says it has no direct evidence that AI wrote the exploit. - Botnet attempts. As of 23 October, Sophos had seen attempts to install a Mirai-derived botnet through PHP2Shell, all unsuccessful. The reality check - Sansec said on 22 October that mass exploitation looked less likely than feared, because attacks need specific knowledge of the target server and the public exploits didn't work against a default PHP install. - Intigriti reported on 2 November that across 24 bug bounty programs it received 37 PHP2Shell reports, accepted 3, and none of the accepted ones included a working proof of concept showing RCE or access to sensitive data. It also noted that many public GitHub PoCs were AI-generated or fake. (Intigriti sells recon tooling, so weigh the framing, but the counts are theirs.) My bottom line is patch, don't panic. "Hard to exploit reliably" is not the same as "safe", and a KEV listing means someone is doing it. The UAE picture Censys counted 4,691 internet-facing hosts in the UAE as potentially exposed as of 25 October, which is 79.5% of the country's hosts where a PHP version could be identified (Khaleej Times). Treat that as a ceiling, not a body count. Censys infers exposure from detected version numbers, so a host patched through a vendor backport (version unchanged) can look vulnerable, and a host that hides its version doesn't appear in the count at all. Globally, Censys data showed around 32.5 million services still on vulnerable versions about a week after disclosure, with the same caveats. Local hosting providers and firms were patching and advising customers to check their runtimes, and Tenable put PHP2Shell in its highest "Vulnerability of Concern" tier. How to check your own stack Here's the quick audit I'd run on any PHP server. Adjust package names for your distro. # Which PHP is the web server really running? (the CLI can differ) php -v php-fpm -v # PHP-FPM; binary name varies, e.g. php-fpm8.3 apachectl -M | grep -i php # is mod_php loaded? (apache2ctl on Debian/Ubuntu) # Vendor backports: the version number alone may not tell you apt changelog <php-package> | grep -E "CVE-2026-10961[89]" # Debian/Ubuntu rpm -q --changelog <php-package> | grep -E "CVE-2026-10961[89]" # RHEL family If your distro's changelog doesn't list the CVE IDs, check the vendor's security advisory instead of guessing from the version string. - Restart or replace every worker still running old code. Installing the package isn't enough if PHP-FPM or Apache is still running the old binary in memory. - Containers: rebuild images from a patched base and redeploy. Don't just restart the old container. - Bundled interpreters and dev stacks (XAMPP, Laravel Herd and similar), plus vendor appliances: check each vendor's advisory. - Hunt for forgotten servers: old staging sites, abandoned subdomains, test containers someone spun up "just for a week" two years ago. - Still on PHP 8.1 or older? Get a vendor-backported build (CloudLinux, for example, published patched builds for older branches) or put the upgrade on the calendar. What helps and what doesn't while you wait for a patch PHP's own team says no mitigation fully blocks these bugs. Treat the list below as stopgaps, and mind the trade-offs. - session.upload_progress.enabled=0 mitigates the upload path of CVE-2026-109619. PHP's team suggests keeping it off after patching unless your app needs the feature. - fatal_error_backtraces=0 (PHP 8.5 only) blocks the backtrace path of CVE-2026-109619. It has to be loaded before request parsing, and workers need a restart. - memory_limit=-1 blocks the known path for CVE-2026-109618 but doesn't remove the risk of allocation failures, and it lets a runaway script eat your RAM. If you go this route, pair it with request-size limits at the proxy and memory limits at the container level. - Don't use RLIMIT_AS or RLIMIT_DATA. They can trigger the very allocation failures the bug depends on. - A WAF or reverse proxy can block requests before they reach the vulnerable parser, but verify it sees the full body, every field and chunked data. Cloudflare shipped rules before disclosure. Partial protection, not a fix. - Hiding errors does nothing. The stale state is still there. How to spot trouble in your logs No single signal is conclusive, so correlate requests, logs and processes (this follows Datadog's detection guidance). - Requests: multipart POSTs with PHPSESSID or PHP_SESSION_UPLOAD_PROGRESS fields on routes that don't normally use them; unusually many parts per request or deep bracket nesting (machine-generated names like files[R00001][a][a][a]); urlencoded bodies with a single multi-megabyte field name; uploads that declare a large Content-Length and then stall; a Set-Cookie: PHPSESSID= with an unusually long, percent-encoded or binary value. - Error logs: "Allowed memory size ... exhausted" with Unknown on line 0 (the failure hit during request initialisation, before any script ran), Apache AH00052 ... Segmentation fault (11), or a short burst of two to four memory-exhaustion errors on one worker followed by silence. - Processes (the strongest evidence): a web worker such as apache2 running as www-data spawning sh, bash, download tools or recon commands, followed by outbound connections. Baseline what your web user normally executes so deviations stand out. - Don't rely on status codes or crashes alone. A successful exploit can return HTTP 200 and leave the worker running. # Starting points (adjust log paths for your setup) grep -E "Allowed memory size .* exhausted.*Unknown on line 0" /var/log/apache2/error.log grep -E "AH00052.*Segmentation fault" /var/log/apache2/error.log Patching closes the hole. It doesn't remove anything an attacker already planted, so if your server was exposed between 17 October and your patch date, review that window. Beyond patching: what I'd change - Keep an inventory. You can't patch what you can't find. List every PHP runtime (web, containers, bundled, staging) with its owner, version and update path. - Mind the end-of-life dates. Per Patchstack, PHP 8.2 gets security fixes only until 31 December 2026 and PHP 8.3 until 31 December 2027, so aim for 8.4 or 8.5. - Plan for shorter windows. The first attempt came four days before disclosure. A monthly patch cycle doesn't cover that. - Limit the blast radius. None of this replaces the patch, but run PHP as an unprivileged user, restrict what the web user can execute, restrict outbound connections from web servers, and alert when a web worker spawns a shell. - Rotate secrets if you can't rule out exposure. One of the flaws can also leak process memory, which may hold credentials and API keys. If you can't be sure, rotate database passwords, API keys and session secrets. What we did at Grafdom Since the fix landed, we've updated and checked over a dozen client websites across Dubai and Abu Dhabi. If your own servers need the same check, our team can help: grafdom.com. FAQ What is PHP2Shell? The nickname for two critical PHP flaws, CVE-2026-109618 and CVE-2026-109619, that can allow unauthenticated remote code execution. PHP released fixes on 21 October 2026. Is WordPress affected by PHP2Shell? Indirectly, yes. WordPress runs on PHP, so a WordPress site on a vulnerable PHP runtime is exposed. The flaw isn't in WordPress itself, and no WordPress update is planned. The fix is the server's PHP update. Does updating WordPress, plugins or themes fix it? No. The vulnerable code runs inside PHP, below the application layer. Which PHP versions fix it? PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35, or a vendor-backported build that includes the fix. Are PHP 7.4 and 8.1 affected? Yes. Affected releases go back to PHP 5.4. There's no official release for 8.1 and older, but PHP published minimal source backports for 7.4, 8.0 and 8.1, and some vendors ship their own. Does a WordPress security plugin protect me? Not against this. The bug triggers while PHP is parsing the request, before plugin code runs. A WAF in front of the server can block known attack patterns, but PHP's team says no mitigation fully blocks these bugs. Is PHP2Shell being exploited in the wild? Yes. CISA lists both CVEs as known exploited, and researchers have confirmed code execution on honeypots and attacks on exposed PAN-OS management interfaces. Reliable exploitation of arbitrary sites is much harder than the headline numbers suggest. Is my UAE website at risk? If it runs PHP, the real question is whether the runtime underneath has been patched. Censys flagged 4,691 UAE hosts as potentially exposed on 25 October, though that number can include hosts patched through backports. Should I take my site offline? The US NSA urged organisations to take affected sites offline if they couldn't fix the flaws immediately. Sansec's view on 22 October was that a typical store doesn't need to go offline, but should update anyway. My take: if you can patch today, patch. If you can't (end-of-life PHP, a vendor appliance), restrict exposure behind a WAF or VPN, or take it down until you can. How do I know if I was compromised? Check your logs back to 17 October, when the first attempts were recorded. Look for unfamiliar admin accounts, new files you didn't add, and web processes spawning shells. Patching doesn't remove anything planted earlier. What about Python sites? PHP2Shell only affects PHP. Python apps aren't affected by it. A separate, unrelated supply-chain attack hit the LiteLLM Python package on 21 October (version 1.107.0 on PyPI, live for about two hours). About the author Adnan Shakir is Head of Technical Development at Grafdom, an award-winning digital media agency in Dubai, UAE. Established in 2005, Grafdom designs, develops and maintains websites for enterprise organisations, multinational companies and government departments across Dubai and Abu Dhabi. With two decades of expertise, it has become a trusted technology partner & advisor to senior leadership teams throughout the Middle East. Grafdom has earned a reputation as the agency of choice for the largest real estate companies, education institutions and banking businesses in the Gulf. Sources - Datadog Security Labs: PHP2Shell technical analysis and detection - Wiz Research: PHP2Shell - NCSC-NL: operational information and product inventory - Sansec: PHP2Shell research - Intigriti: PHP2Shell revisited - Singapore CSA: alert AL-2026-157 - The Register: CISA confirms PHP2Shell under attack - BleepingComputer: CISA confirms PHP2Shell exploited - The Hacker News: attackers exploit PHP2Shell in Palo Alto management interfaces - The Hacker News: PHP2Shell attack roots 25 servers - The Hacker News: Unit 42 retraction - SecurityWeek: first exploitation attempts hit sensors - SecurityWeek: Mirai botnet operators join PHP2Shell attacks - Khaleej Times: UAE firms race to patch AI-discovered PHP flaw - Cybernews: Censys data on vulnerable PHP services - Codeable: PHP security release and WordPress - GoDaddy: PHP security update for website owners - Patchstack: PHP vulnerability alert and support dates - Bolt: PHP and WordPress share of websites (W3Techs data) - The Hacker News: LiteLLM supply-chain compromise

  2. Docker Security Dispatch — Issue 8: Two Shells, 17,000 CVEs, and No Time to Patch 🐚 In December 2021, Log4Shell gave the security industry a shocking Christmas present. Five years later, the security scene makes Log4Shell look like a relaxing afternoon. October 2026 brought us PHP2Shell, Node2Shell, and a poisoned LiteLLM release. Well, also a GitLab CVE, and an NGINX CVE, and an OpenCode CVE—you get the picture. Actually, we had more high and critical CVEs in October 2026 than we had in the whole of 2021. !Docker Security Dispatch 8 Welcome to Docker Security Dispatch 8, reviewing October 2026. This month: two shells, a compromised release pipeline, the growing gap between exploitation and patching, and some Docker commands to help us survive the next security apocalypse. Plus, some discount codes for books, a meetup in the Black Forest, my adventures at BaselOne, and a trip to J-Fall! 🐳 Key takeaways - October brought 17,013 CVEs, including 8,059 High and Critical findings. - Patch PHP and Node.js; investigate and rotate exposed credentials after LiteLLM compromise. - Rebuild, redeploy, verify—and limit what a compromised workload can reach. In This Issue - Book discounts - The CVE avalanche - Time to patch - Two shells - LiteLLM - Docker news - Practical defenses - Community spotlight - Recent work * 🎁 Discounts: Books Before the Bugs Time to get some security books? - 20% off Packt books: Use code AIDOCKER20 at Packt. - 50% off the Docker and Kubernetes Security ebook: Use code DSD8DKS, or [open the checkout with the discount applied](buy.containersecurity.dev[discount_code]=DSD8DKS). Prefer paper? Docker and Kubernetes Security is also available in paperback on Amazon. !Books in the woods of the Black Forest Unfortunately, purchasing a security book does not automatically patch your production containers. I've checked. 😅 * 🌋 The CVE Avalanche: October 2026 vs. 2021 Remember Log4Shell? CVE-2021-44228 affected Apache Log4j, a widely used Java logging library, and could allow remote code execution (RCE). It wasn't just about patching one library. Organizations had to find Log4j buried inside applications, dependencies, and products they didn't even realize contained it. Then people started to talk about SBOMs. And Docker added the docker sbom command. The command has since been removed and replaced with: docker scout sbom --format list <image> Now, consider October 2026. !CVE publication trends According to CRACI's CVE publication statistics, the numbers were:[^1] | Period | Published CVEs | High + Critical CVEs | | ---------------- | -------------: | -------------------: | | Entire 2021 | 19,862 | 4,324 | | October 2025 | 4,235 | 1,706 | | October 2026 | 17,013 | 8,059 | Of October's findings, 6,536 were High and 1,523 were Critical, for a combined 8,059. That's nearly twice as many High and Critical CVEs as in all of 2021, using CRACI's recorded severity scores. Many older records lack scores, so this isn't a like-for-like measure of risk. Every time a CVE is published, the defenders are notified as well as the attackers. Then it's a race. * ⏱️ Time to Patch: A Race Against Time How long does it take to patch a vulnerability? A patch has to travel a long way before it protects production: identify the affected application, update its dependencies, rebuild, test, deploy, and verify. For example, with PHP2Shell, first update the PHP base image:[^2] FROM dhi.io/php:8.4.27-fpm Then rebuild and redeploy (assuming you use Compose): docker compose build --pull --no-cache docker compose up -d --force-recreate Then verify: docker compose exec <service> php -v # or docker scout sbom <image> --format list | grep -i php Each step takes time. An attacker only needs a reachable weakness. Time to patch measures the defender's remediation work. Time to exploit measures when attackers start exploiting a vulnerability relative to patch availability. Google's M-Trends 2026 research shows how far that window has shifted: | Year | Mean time to exploit | | ---- | ----------------------: | | 2018 | 63 days | | 2024 | −1 day | | 2025 | −7 days (estimated) | A negative value means exploitation began, on average, before a patch was released, for the vulnerabilities studied.[^3] Even immediate patching can leave us behind. Prepare to contain an attacker as well as patch the bug. * 🐚 PHP2Shell and Node2Shell: Two Shells in One Day The 21st of October was a particularly interesting Wednesday for software engineers. We had RCE risks in two different ecosystems. These RCE exploits were not the first and will not be the last. And, as the trend suggests, we will see more of these nice CVEs in the near future. And, as the time to exploit suggests, we are already vulnerable before there is a published patch. So, what to do? We can try and reduce the blast radius with minimal images, rootless execution, and fewer tools. No shell doesn't mean no RCE; the runtime still needs its patch. If you still have not patched your PHP, check this walkthrough: how-to-fix-php2shell For Node2Shell, update the Node.js runtime too. On the 24.x branch, the fix released on the 21st of October was 24.22.1: FROM node:24.22.1 Rebuild the image with no cache, redeploy, and check the version:[^4] docker compose exec <service> node --version We will get back to reducing the blast radius. * ☠️ LiteLLM: When the Release Pipeline Is the Attacker On the 21st of October, LiteLLM's release pipeline shipped credential-stealing malware in litellm==1.107.0 and official images tagged v1.107.0, latest, main-latest, and main-stable.[^5] Remember Issue 6's malicious package with valid provenance? Here we go again. If affected code ran: isolate, investigate, revoke or rotate accessible credentials, and rebuild from verified clean inputs. Work from a clean environment: starting Python or pip in the affected one could retrigger the malware. Check digests and exposure windows in the full incident report; cached artifacts remain dangerous after registry removal.[^6] * 🐳 Docker News - Sandboxes, v0.48–v0.50.1: Kits v3 gained capability groups, bundled skills, Git identity and SSH signing; later releases added persistent kit volumes, configurable host mounts, cloud inspection, and tighter host/credential protections.[^7] v0.50.1 fixes sandbox startup.[^8] Even the sandbox needs maintenance. - Desktop security: 4.97.0 fixes CVE-2026-99999, where malformed IPv4 checksum metadata could corrupt the VM network stack, and CVE-2026-114409, which exposed third-party credentials in logs/diagnostics. Update and sanitize retained diagnostic copies.[^9] - eMudhra: Compromised CA keys could enable service impersonation. Docker refreshed sandbox templates, but updating sbx alone doesn't fix existing sandboxes: refresh their images or CA stores and restart applications.[^10] - DHI's busy week: Following PHP2Shell/eMudhra, Docker ran 16,567 package and image builds in 48 hours. The rebuild report explains the trust-store updates.[^11] That's a lot of coffee for a build system. * 🛡️ What Can We Actually Do? Big Picture. We cannot manually review 17,000 CVEs every month. Fortunately, we don't need to. Start with what your application actually ships and what attackers can reach. 1. Find the Actionable CVEs Docker Scout can narrow the vulnerability list to fixable High and Critical findings:[^12] docker scout cves \ --only-fixed \ --only-severity critical,high \ <image> To look specifically for vulnerabilities listed in CISA's Known Exploited Vulnerabilities catalog: docker scout cves \ --only-cisa-kev \ <image> The first view hides findings without fixes; the second highlights known exploitation. Neither is your complete risk inventory. 2. Rebuild, Don't Just Update the Dockerfile After updating your vulnerable dependencies and base image: docker build --pull --no-cache \ -t <image> . Then scan the resulting image, run your tests, deploy it, and verify the runtime in production. A patched Dockerfile sitting in Git does nothing for an old container still running in production. 3. Reduce the Damage Before the Next CVE My Security Immediate Plan (SIP) covers agent isolation, dependency cooldowns, hardened builds, attestations, and vulnerability gates. For prevention, run your coding agent in a sandbox: sbx policy init deny-all sbx policy ls sbx run --clone opencode . Sandboxing keeps the AI agent and malicious packages away from your host files, except for the ones you mounted into it. Secrets are injected into the requests without the agent having access to them. And exfiltration of the secrets can be blocked using network policies. * 🐳 Community Spotlight The Docker community has been very busy over the past month as well. I think we owe it to the awesome Mexican food: Faeka Ansari shares her first Docker Captains Summit experience in Mexico: handwritten welcome letters, community connections, and why agent permissions belong outside the agent. Come for the Caribbean sunrise, stay for the security boundaries. Check if you can spot my face in the article. Docker Captains Summit: Mexico 2026 Faeka Ansari — Community connections and agent security lessons from her first summit. Nick Janetakis takes us through Docker Captain's Summit in Mexico, with friendships, behind-the-scenes moments, and enough group photos to test a camera's horizontal scaling. Docker Captain's Summit in Mexico Nick Janetakis — Friends, behind-the-scenes moments, and a very busy camera. Back at the terminal, Ajeet Raina at Collabnix walks through What's New in Docker Sandboxes Kits v3 (v0.48.0), building a mixin with bundled skills, Git identity, and scoped SSH signing. Even the agent needs to learn that borrowing your keys doesn't mean borrowing the whole house. What's New in Docker Sandboxes Kits v3 (v0.48.0) Ajeet Raina · Collabnix — A hands-on mixin with skills, Git identity, and scoped SSH signing. And Matteo Bisi brings an OVHcloud CLI Supply Chain Compromise user playbook: check exposure, isolate, rotate credentials, and verify what you rebuild. The source was clean; the release binaries weren't. Apparently, reading the recipe doesn't tell you who poisoned the coffee. OVHcloud CLI Supply Chain Compromise: A User Playbook Matteo Bisi — Check exposure, rotate credentials, and recover from poisoned release binaries. Docker's The CVE That Did Not Exist, by Ajeet Singh Raina and Pratik Singh, follows a review bot inventing a vulnerability and recommending drastic remediation. We already have 17,000 CVEs. Please stop generating DLC. Coding Agent Horror Stories: The CVE That Did Not Exist Ajeet Singh Raina and Pratik Singh · Docker — A review bot invents a vulnerability and a dangerous response. Çiğdem Kadakoğlu explores Docker Sandboxes: Local vs Cloud, explaining where your agents run, what sbx move actually transfers, and why your secrets and network policies don't automatically follow. Well, this article is in Turkish, but we're working on an English piece on sbx cloud, and it's only fitting since she was writing on the plane. ✈️ Docker Sandboxes: Local vs Cloud Çiğdem Kadakoğlu — Where agents run and what moves between local and cloud sandboxes. In Turkish. Written something the Docker security community should read? Send it my way for DSD 9. Practical lessons, experiments, and stories welcome. Bonus points if the coffee survives. ☕ * 🎙️ Recent Work ☕ SIP for Java: Coming to JAVAPRO I teamed up with Catherine Edelveis to write SIP: Security Immediate Plan for Java, a collaborative piece that will be published in JAVAPRO. Five practical controls, from AI agents and Maven/Gradle inputs to hardened images and release checks—with a Spring Boot example. sip-for-java 🐳 Hackdockerfest in Freiburg: Worms, Python, and AI Agents On the 27th of October, Docker Freiburg and Black Forest teamed up with the Python User Group Freiburg for Hackdockerfest at JobRad. I helped organize the evening and presented the Security Immediate Plan for Python. Docker Captain Marco Franzon covered SBX and AI Agent Activity Tracking and shared his token-consumption tracking resources. Check the resources here. !A group selfie with smiling attendees seated on wooden tiers at JobRad. 🇨🇭 BaselOne: Securing Java in Asgard On the 15th of October at BaselOne, the Commandos defended Java in Asgard—here's the practical Spring Boot companion article. 🇳🇱 Coming Up: J-Fall 2026! I'll be at J-Fall in Ede, the 11th–12th of November as a room host—find the red fedora and say hello! 🎩 * Until Next Time Two shells, a poisoned release, and 17,000 CVEs. Hopefully, we won't get a third shell in November; otherwise we will have to learn how to use the three seashells! Also, remember, remember: tomorrow is the 5th of November, so harden your images before that Guy gets into your containers. * [^1]: CRACI. CVE Publication Trends. Publication-date statistics, October 2026. [^2]: NCSC-NL. PHP2Shell Operational Information. [^3]: Google Cloud. FinOps for SecOps: How to Optimize the Agentic SOC for Value. Cites M-Trends 2026 mean time-to-exploit figures; the 2025 figure is an estimate. [^4]: Node.js Project. Security releases of the 21st of October 2026. [^5]: LiteLLM. The Attack Chain Behind the v1.107.0 Release. [^6]: LiteLLM. Incident report for the 21st of October 2026. Affected artifacts, exposure windows, and remediation guidance. [^7]: Docker Docs. Docker Sandboxes Release Notes. [^8]: Docker. Sandboxes v0.50.1 Release. [^9]: Docker Docs. Docker Desktop 4.97.0 Release Notes. [^10]: Docker Docs. Docker Sandboxes Response to eMudhra CA Compromise. [^11]: Docker. PHP2Shell and eMudhra Patched. [^12]: Docker Docs. Docker Scout CVE Command Reference. <!-- devto-source: containersecurity.dev --> <!-- devto-content: 93f9e5d81eccc638ac5d253c2d1c2e322767e4bb2d1f40a086347fe59235c225 -->

    5 reactions
  3. php2shell、製品ベースの統計だと今日時点でまだ2割ぐらいしか完了してないのか。こりゃマズイね。 NCSC-NL/php2shell t.co

    2 likes · 154 views
  4. Le Nationaal Cber Security Centrum (NCSC-NL) consolident dans un dépôt Github des infos sur les mises à jour de produits embarquant PHP. (Source ANSSI). NCSC-NL/php2shell

  5. PHP2Shell - high-impact computer vulnerabilities concerning memory safety flaws that allow remote code execution (RCE) by a potential malicious user to gain remote control of the website host. wiki- en.wikipedia.org github - NCSC-NL/php2shell t.co

    14 views
  6. YouTube · · YouTube description · MakSim-IT · NCSC-NL/php2shell

    Топ-9 GitHub за 3 дня: reylo и 3d-model-anything Обзор: топ-9 новых репозиториев GitHub за 20–23 октября 2026 — новые проекты GitHub и open source, которые быстрее всех набрали звёзды. В выпуске: типизированный импорт .sql в TypeScript, скан комнаты на iPhone в сцену Three.js и сканер уязвимости PHP. 1. colinhacks/reylo — Импорт .sql-файлов в TypeScript с типами из схемы БД, без кодогенерации. (Rust, +753 ★) 2. wesbos/3d-model-anything — iPhone-приложение и навык для агента: скан комнаты → сцена Three.js. (Swift, +606 ★) 3. assetnote/php2shell-scanner — Консольный сканер уязвимостей CVE-2026-109618 и CVE-2026-109619 в PHP. (Python, +343 ★) 4. zita-ch/supermimic_vibed — Неофициальное воспроизведение SuperMimic: управление гуманоидом G1 в Isaac Lab 3. (Python, +327 ★) 5. rossark0/rossark-motion-skill — Навык для Claude Code: оживляет нарисованное — персонажей, сцены, иконки. (Swift, +322 ★) 6. raymondchins/Bridgeplay — Windows-игры из Steam на Mac с Apple Silicon, установка в один клик. (Scala, +272 ★) 7. NCSC-NL/php2shell — Сводка NCSC-NL по уязвимостям PHP CVE-2026-109618 и CVE-2026-109619. (Python, +236 ★) 8. helloianneo/ian-xhs-carousel — Навык Claude Code: статья или заметка → серия картинок 3:4 для Xiaohongshu. (HTML, +232 ★) 9. qianshuixia/shrimpreel — Шаблон сайта «одно фото → ИИ-видео по вирусному шаблону» на Cloudflare. (TypeScript, +219 ★) Источник: GitHub Search API, репозитории созданы с 2026-10-20, отсортированы по звёздам. Лидер: colinhacks/reylo Остальные: wesbos/3d-model-anything, assetnote/php2shell-scanner, zita-ch/supermimic_vibed, rossark0/rossark-motion-skill, raymondchins/Bridgeplay, NCSC-NL/php2shell, helloianneo/ian-xhs-carousel, qianshuixia/shrimpreel #GitHub #opensource #программирование Каждые 3 дня — 10 новых open-source проектов GitHub, быстрее всех набравших звёзды. Подписывайся, чтобы не пропустить следующий выпуск.

    1 like · 48 views
  7. If anyone needs a growing list of vendors affected by php2shell. The Netherlands National Cybersecurity Center is so kind to publish their list on GitHub. You can ctrl +f the .md list on Github. github.com/NCSC-NL/php2shell/blob/main/software/c…

    1 like · 63 views
  8. No, sorry. Full stop. The php vulnerabilities are real. GitHub is nonaligned, & run by geeks who know their stuff. php2shell vulnerabilities (CVE-2026-109618, CVE-2026-109619) NCSC-NL/php2shell

    1 like
  9. Testing the AWS WAF Mitigations for PHP2Shell on Both CloudFront and an ALB --- title: Testing the AWS WAF Mitigations for PHP2Shell on Both CloudFront and an ALB published: true description: 'I deployed the AWS WAF rules published for PHP2Shell (CVE-2026-109618 / 109619) on CloudFront (64 KB body inspection) and on an ALB (fixed 8 KB) with AWS CDK and measured inspection boundaries, false positives, per-layer thresholds and origin bypass.' tags: 'aws, security, cdk, php' cover_image: null organization_id: 2794 id: 4897722 date: '2026-10-22T16:10:45Z' --- Introduction On 2026-10-21 the PHP project disclosed PHP2Shell (CVE-2026-109618 / CVE-2026-109619): CVSS v4.0 9.2, unauthenticated remote code execution (PHP security advisory, CERT-EU Security Advisory 2026-018). As a stopgap until PHP can be upgraded, an AWS Security Blog post published four AWS WAF custom rules: PHP2Shell, Block-Multipart-FormData, Block-Oversize-Body and RateLimit-Posts. The AWS Security Bulletin also points to SizeRestrictions_BODY in AWSManagedRulesCommonRuleSet and to the PHP managed rule group (version 2.3, now the default), which adds protection for CVE-2026-109619. Classmethod has already tested the AWS Security Blog rules thoroughly on an ALB, including the fact that PHP_SESSION_UPLOAD_PROGRESS placed after the first 8 KB of the body goes through. This article reproduces that test on both CloudFront and an ALB and verifies what was still open: - How far does raising CloudFront's body inspection limit (16 KB default, 64 KB max) get you? - How does the ALB's Web ACL behind CloudFront affect the result? - What changes when the origin only accepts traffic through CloudFront? - How long does the rate-based rule take to react once the threshold is crossed? 📁 Code: waf-php2shell-mitigation (part of AWS CDK Reference Architectures). > Note > AWS WAF is a mitigation, not a fix. Upgrading to PHP 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12 or later is the only complete remediation. PHP 8.1 and older are also affected but are end-of-life, so there is no official fixed release (the PHP team published minimal source backports, and some distributions and LTS vendors provide backported packages). Move to a supported version. TL;DR The AWS Security Blog rules are a stopgap until PHP is upgraded; the AWS Security Blog post itself states that the real fix is upgrading PHP. As a stopgap, the rules behaved as specified on both CloudFront and the ALB. AWS WAF, however, inspects a request body only from the start up to a size limit: 8 KB on an ALB (fixed), 16 KB by default on CloudFront, up to 64 KB (AWS WAF documentation). On the ALB, a string ending at byte 8,192 was blocked; shifting it by one byte let it through. The Block-Oversize-Body rule from the same post (a size limit meant for CVE-2026-109618), when set to BLOCK, also stops requests whose bodies go past that limit. How to configure that rule depends on your setup: - If you use CloudFront, raise the inspection limit to 64 KB and block bodies larger than 64 KB with Block-Oversize-Body. The whole body is then inspected, and legitimate requests up to 64 KB still pass. - With CloudFront + ALB + WAF, set the ALB's "block bodies over 8 KB" rule to COUNT and let the ALB accept traffic from CloudFront only. Left in BLOCK, the ALB stops legitimate requests that CloudFront already allowed. If the ALB Web ACL includes AWSManagedRulesCommonRuleSet, override its SizeRestrictions_BODY (blocks bodies over 8 KB) to COUNT for the same reason. - If you expose only an ALB, blocking bodies over 8 KB is the baseline. According to the AWS Security Blog post, both CVEs sit on the multipart/form-data processing path, so an app that takes no file uploads and only accepts JSON over 8 KB could block Block-Multipart-FormData instead of using the size limit (not verified in this article). An app that accepts file uploads over 8 KB cannot be fully protected by WAF, so prioritize the PHP upgrade. If your app changes session.name or session.upload_progress.name from the defaults, rewrite the rule strings to the actual names. Matching is case-sensitive, so this also applies when only the letter case differs. Architecture !Architecture Client ─▶ CloudFront + Web ACL (us-east-1, 64 KB body inspection) ─▶ ALB + Web ACL (ap-northeast-1, fixed 8 KB) ─▶ Lambda container (nginx + PHP-FPM 8.4.27 + Lambda Web Adapter) Client ─────────▶ ALB direct (comparison only, allow-listed IP) A WAF decision does not depend on the PHP version behind it, so the origin runs a patched PHP 8.4.27 as a Lambda container image. On the PHP side, it applies these server-side mitigations from the AWS Security Blog post: ; php.ini session.upload_progress.enabled = 0 memory_limit = -1 ; the real ceiling is the Lambda memory size post_max_size = 8M ; PHP-FPM pool pm = static pm.max_children = 1 pm.max_requests = 1 ; replace the worker after every request Telling which WAF and which rule acted, from HTTP headers With WAF on both CloudFront and the ALB, a bare 403 does not tell you which layer answered. Every rule therefore names itself: const ruleAction = (ruleName: string, action: RuleAction): wafv2.CfnWebACL.RuleActionProperty => action === 'BLOCK' ? { block: { customResponse: { responseCode: 403, responseHeaders: [{ name: 'x-php2shell-blocked-by', value: `${label}:${ruleName}` }] } } } : { count: { customRequestHandling: { insertHeaders: [{ name: `php2shell-${label}-${ruleName.toLowerCase()}`, value: 'counted' }] } } }; BLOCK returns x-php2shell-blocked-by: cloudfront:PHP2Shell; COUNT inserts x-amzn-waf-php2shell-alb-oversize: counted into the origin request, and the PHP app echoes it back. Headers inserted by the CloudFront Web ACL travel through the ALB to the origin, and the BLOCK response header keeps its own name (no x-amzn-waf- prefix). Note that clients can also send headers starting with x-amzn-waf-. If your application changes its behavior based on these headers in production, add a rule that blocks x-amzn-waf- headers arriving from outside, as the AWS WAF documentation describes. Result 1: rule conditions (reproducing the ALB test on both layers) | Request | via CloudFront | ALB direct | |---------|----------------|------------| | POST, cookie PHPSESSID + PHP_SESSION_UPLOAD_PROGRESS in body | 403 | 403 | | POST, both strings in body | 403 | 403 | | POST, PROGRESS only / cookie only | 200 | 200 | | PUT, both strings in body | 200 | 200 | | multipart PROGRESS field + cookie | 403 | 403 | | lowercase cookie key phpsessid | 200 | 200 | | lowercase php_session_upload_progress in body | 200 | 200 | | JSON or text/plain containing both strings (false positive) | 403 | 403 | The rule uses TextTransformation: NONE, so it only matches PHP's default names. If your app renames the session cookie or the upload progress field, change the rule strings too. Result 2: string position vs inspection limit Cookie PHPSESSID, with PHP_SESSION_UPLOAD_PROGRESS ending at byte N (oversize rule in COUNT): | N | ALB direct | CloudFront KB_16 | CloudFront KB_64 | |---|-----------|--------------------|--------------------| | 8,192 | 403 | 403 | 403 | | 8,193 | 200 | 403 | 403 | | 16,385 | 200 | 200 | 403 | | 65,536 | 200 | 200 | 403 | | 65,537 | 200 | 200 | 200 | WAF logs agree: requestBodySizeInspectedByWAF is 8192 on the ALB and 65536 on CloudFront KB_64, and larger bodies carry oversizeFields: ["REQUEST_BODY"]. Result 3: oversize rule in BLOCK (8,192 bytes) Everything from 8,193 bytes is blocked regardless of position. So is a legitimate ~19 KB JSON POST with no rule string at all. An API that accepts JSON over 8 KB cannot use this as is. Result 4: with WAF on both CloudFront and the ALB, the ALB blocks legitimate requests CloudFront can inspect the first 64 KB of the body, so I raised CloudFront's Block-Oversize-Body threshold to 65,536 bytes. CloudFront then passes legitimate requests up to 64 KB and blocks bodies too large to inspect in full. The ALB's Web ACL is where this goes wrong. Putting CloudFront in front of an ALB that already had WAF, or adding the same rules to both layers as defense in depth, is common. Even when the origin only accepts CloudFront, requests through CloudFront are evaluated again by the ALB Web ACL. | ALB Block-Oversize-Body (8,192 bytes) | Legit 19 KB JSON | PROGRESS at byte 65,537 | |-----------------------------------------|------------------|-------------------------| | BLOCK | 403 alb:Oversize | 403 cloudfront:Oversize | | COUNT | 200 | 403 cloudfront:Oversize | (Both through CloudFront; CloudFront blocks above 65,536 bytes.) At first I thought raising CloudFront's limit would be enough. With the ALB rule in BLOCK, though, the ALB's 8 KB rule stops the 19 KB JSON that CloudFront inspected and allowed. To benefit from CloudFront's setting, the ALB size rule has to be COUNT. Result 5: restricting ALB access to CloudFront COUNT on the ALB opens a different problem: a request sent straight to the ALB skips CloudFront, and the ALB inspects only 8 KB. A request with PROGRESS ending at byte 8,193, sent directly, was 403 with the ALB rule in BLOCK and 200 with it in COUNT. If you follow the AWS best practice and restrict the ALB to traffic from CloudFront, the Result 4 fix (COUNT on the ALB) is not a problem. Setting it to COUNT while the ALB is still directly reachable, however, is dangerous. As the documentation describes, I combined a security group and a custom header. The security group admits only the CloudFront origin-facing managed prefix list (com.amazonaws.global.cloudfront.origin-facing). That list is shared by every CloudFront distribution, so on its own it also lets other distributions in. I therefore set an X-Origin-Verify origin custom header on CloudFront, and the ALB listener rule forwards only requests whose header value matches (default action 403). const cloudFrontPrefixList = ec2.PrefixList.fromLookup(this, 'CloudFrontOriginFacing', { prefixListName: 'com.amazonaws.global.cloudfront.origin-facing', }); albSecurityGroup.addIngressRule(ec2.Peer.prefixList(cloudFrontPrefixList.prefixListId), ec2.Port.tcp(80)); listener.addAction('FromCloudFront', { priority: 10, conditions: [elbv2.ListenerCondition.httpHeader('X-Origin-Verify', [originVerifyValue])], action: elbv2.ListenerAction.forward([targetGroup]), }); This approach relies on keeping the header name and value secret. For this verification CloudFront talks to the ALB over HTTP (port 80); the documentation recommends HTTPS and rotating the header regularly. Another option is to keep the ALB off the internet and connect an internal ALB to CloudFront as a VPC origin. For Results 1–4, I had added an exception that let my own IP address reach the ALB directly, for comparison. After removing that exception and redeploying, a direct curl to the ALB got no response at all, not even a 403, and timed out: the security group drops the traffic before it reaches the ALB. Through CloudFront, requests still returned 200, and requests with the PHP2Shell pattern were still blocked with 403. Other observations | Check | Result | |-------|--------| | RateLimit-Posts (100 per 60 s, COUNT) at ~2.4 req/s | first match on request #138, 57 s in | | 1,100,000-byte body, ALB → Lambda | 413 (1 MB Lambda target limit), not in the ALB WAF log | | WCU | CloudFront 50 / ALB 45 (AWSManagedRulesCommonRuleSet alone is 700) | | pm.max_requests=1 | FPM worker PID changes on every request | | Lambda container cold start | 3.2 s first, 0.2 s after; ~48 MB memory | The rate-based rule first matched on request #138 (in COUNT; in BLOCK, blocking would start there). The threshold is 100 per 60 seconds, so about 16 seconds and 38 requests went through after it was crossed. If you set the threshold to exactly the number you can tolerate, requests that arrive while detection lags go through on top of it. The overshoot is roughly "request rate × lag": here, 2.4 req/s × ~16 s ≈ 38. Faster attacks overshoot more, so set the threshold below what you can tolerate. The AWS WAF documentation also says rate-based rules are not meant for precise rate limiting, and that the detection lag is usually under 30 seconds but can stretch to minutes. Cost About $40/month if left running (ALB ~$18, two Web ACLs $10, eight rules $8, plus requests). With KB_64, only requests whose bodies exceed 16 KB pay an extra $0.30 per million per additional 16 KB. The verification itself, deploy to destroy within a few hours, cost under $1. Wrap-up The AWS Security Blog rules behave as specified on both CloudFront and the ALB, but only for strings within the inspected part of the body. Even with CloudFront's limit raised to 64 KB, an 8 KB rule left on the ALB blocks legitimate requests, and a directly reachable ALB lets requests through with everything past 8 KB uninspected. Configure WAF for the whole request path rather than for CloudFront and the ALB separately. That said, every measure verified here is a mitigation. Upgrade PHP first. References - Using AWS WAF to apply mitigations for PHP2Shell RCE vulnerabilities (AWS Security Blog) - PHP security advisory (2026-10-21) - PHP security advisory GHSA-w8hw-w9fx-j79w (CVE-2026-109618) - PHP security advisory GHSA-6wmf-4rv5-p3rp (CVE-2026-109619) - CERT-EU Security Advisory 2026-018: Critical Vulnerabilities in PHP - NCSC-NL php2shell operational information - Amazon Threat Intelligence identifies PHP2Shell exploitation prior to public disclosure in MadPot - AWS Security Bulletin 2026-143-AWS - Classmethod: Trying the AWS WAF rules from the AWS Security Bulletin (2026-143-AWS) and the AWS Security Blog to mitigate PHP2Shell - Restrict access to Application Load Balancers (CloudFront Developer Guide) - AWS WAF: Considerations for managing body inspection - AWS WAF: Rate-based rule caveats - AWS WAF pricing

    1 reaction
  10. A common question regarding #php2shell (CVE-2026-109618 & CVE-2026-109619) in #php is; "what's vulnerable?" The awesome people at NCSC-NL have provided the answer. If it's on this list, it's vulnerable. (It's a very long list in alphabetical order) NCSC-NL/php2shell

    1 like · 1 repost

Achievements

Awards earned by the repositories NCSC-NL owns. Select an award to embed its badge.

Gold
01st place finishes
Silver
32nd place finishes
Bronze
13rd place finishes
Awarded repositories
1Owned by NCSC-NL now

Repositories

Ordered by gold, then silver, then bronze.

  1. log4shellBest: 2nd by PR authors, 264 PR authors031

Every award

Top-three finishes of these repositories in completed trending days and weeks, newest first.

  1. log4shell
  2. log4shell
  3. log4shell
  4. log4shell

A repository earns an award for finishing first, second or third in a completed trending day or week, ranked by new stars, new forks or pull request authors. Awards follow a repository through renames and transfers and count toward its current owner. Weeks run Monday to Sunday, UTC.