{"id":49639,"date":"2026-10-22T19:26:17","date_gmt":"2026-10-22T13:56:17","guid":{"rendered":"https:\/\/www.getastra.com\/blog\/?p=49639"},"modified":"2026-10-22T19:42:51","modified_gmt":"2026-10-22T14:12:51","slug":"modern-incident-response","status":"publish","type":"post","link":"https:\/\/www.getastra.com\/blog\/security-advisory\/modern-incident-response\/","title":{"rendered":"When Foundations Fail: Lessons in Modern Incident Response\u00a0"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><em>A day-two guide for security leaders: what to do now, today and this week, which controls would have broken each attack, and where the evidence is still thin.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Last updated: October 22, 2026.<\/strong> We update this post as vendors publish new details. The update log is at the bottom.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Most security and modern incident response programs ask one question: what do we need to patch? On October 21, 2026, patching covered three of the eight incidents in the headlines. For the other five, the damage was already done or sat somewhere no patch reaches.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this blog, we cover what happened in each incident, the key action steps, which controls would have broken the attack, where those controls fall short, and what information is still awaited.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"What_to_do_in_order\"><\/span>What to do, in order<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Here\u2019s how we\u2019d sequence it.&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>PHP2Shell leads because it exposes the most systems, and the honest first step is finding out how many PHP runtimes you actually have.&nbsp;<\/li>\n\n\n\n<li>LiteLLM is second for anyone who ran it, because stolen credentials don\u2019t wait for your change window.&nbsp;<\/li>\n\n\n\n<li>Railway is real work, but it\u2019s rotation and containment, so it sits behind the patch-now items.&nbsp;<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">If you started yesterday, the last column is a quick way to see whether you\u2019re actually done.<\/p>\n\n\n\n<div id=\"tablepress-493-scroll-wrapper\" class=\"tablepress-scroll-wrapper\">\n<table id=\"tablepress-493\" class=\"tablepress tablepress-id-493 column1-color tablepress-responsive\">\n<thead>\n<tr class=\"row-1\">\n\t<th class=\"column-1\">When<\/th><th class=\"column-2\">Incident<\/th><th class=\"column-3\">Do this<\/th><th class=\"column-4\">Done when<\/th>\n<\/tr>\n<\/thead>\n<tbody class=\"row-striping row-hover\">\n<tr class=\"row-2\">\n\t<td class=\"column-1\">Now<\/td><td class=\"column-2\">PHP2Shell<\/td><td class=\"column-3\">Inventory every PHP runtime. Upgrade to 8.2.35, 8.3.36, 8.4.27 or 8.5.12, restart workers, isolate end-of-life hosts<\/td><td class=\"column-4\">The running version, not the installed one, is verified on every host<\/td>\n<\/tr>\n<tr class=\"row-3\">\n\t<td class=\"column-1\">Now<\/td><td class=\"column-2\">LiteLLM<\/td><td class=\"column-3\">Search lockfiles, CI logs and image manifests for litellm 1.107.0. If a host ran it, isolate it, rebuild, and rotate every secret it could reach<\/td><td class=\"column-4\">No host ran it, or every reachable secret is rotated and provider usage is reviewed<\/td>\n<\/tr>\n<tr class=\"row-4\">\n\t<td class=\"column-1\">Today<\/td><td class=\"column-2\">GitLab<\/td><td class=\"column-3\">Upgrade self-managed instances to your branch\u2019s fixed release, even if you patched on October 12. Turn on GitLab\u2019s two detection rules and get the login page off the open internet<\/td><td class=\"column-4\">Running version confirmed; CI tokens, deploy keys and runners reviewed if the instance was exposed<\/td>\n<\/tr>\n<tr class=\"row-5\">\n\t<td class=\"column-1\">Today<\/td><td class=\"column-2\">Node.js<\/td><td class=\"column-3\">Upgrade to v22.23.4, v24.22.1 or v26.12.1 and rebuild images. Start with internet-facing services that decompress untrusted data<\/td><td class=\"column-4\">Images rebuilt and redeployed; managed-runtime vendors have confirmed their rollout<\/td>\n<\/tr>\n<tr class=\"row-6\">\n\t<td class=\"column-1\">Today<\/td><td class=\"column-2\">Shopify<\/td><td class=\"column-3\">Test checkout in a fresh private window with the real button, check Session Storage for __ctf_ keys, remove apps you don\u2019t use<\/td><td class=\"column-4\">Clean on desktop and mobile; payment processor briefed if any doubt remains<\/td>\n<\/tr>\n<tr class=\"row-7\">\n\t<td class=\"column-1\">Today<\/td><td class=\"column-2\">Railway<\/td><td class=\"column-3\">Rotate in order: money, identity, data keys, the rest. Where you can\u2019t revoke yet, cut the key\u2019s permissions at the provider. Recreate Railway API tokens<\/td><td class=\"column-4\">Old credentials confirmed dead at each provider; usage logs show nothing unfamiliar<\/td>\n<\/tr>\n<tr class=\"row-8\">\n\t<td class=\"column-1\">This week<\/td><td class=\"column-2\">eMudhra<\/td><td class=\"column-3\">Update CA bundles and runtimes, rebuild containers, replace any certificate chaining to the emSign ECC G3 root<\/td><td class=\"column-4\">No certificate in your inventory chains to that root<\/td>\n<\/tr>\n<tr class=\"row-9\">\n\t<td class=\"column-1\">This week<\/td><td class=\"column-2\">SBI<\/td><td class=\"column-3\">Customers: verify any call or message through the official SBI app. Organizations: brief fraud and support teams<\/td><td class=\"column-4\">Warnings are out to customers and staff<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<!-- #tablepress-493 from cache -->\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Three_incidents_that_patches_can_help_with\"><\/span>Three incidents that patches can help with&nbsp;<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1. PHP2Shell<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Two flaws in PHP\u2019s core engine, CVE-2026-109618 and CVE-2026-109619, were disclosed on October 21 with fixed releases. Both are rated CVSS 9.2. Either can let an unauthenticated attacker run code on a vulnerable server, and one path can disclose process memory, which may contain sensitive information such as credentials.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The bugs live in the PHP runtime, so updating WordPress, Drupal or any other CMS doesn\u2019t touch them.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Fixes are in 8.2.35, 8.3.36, 8.4.27 and 8.5.12. PHP 8.1 and older are end of life, with source backports only for 7.4, 8.0 and 8.1.<\/li>\n\n\n\n<li>Restart workers after patching. Distribution backports often leave the version string unchanged, so check your vendor\u2019s advisory.<\/li>\n\n\n\n<li>Per Wiz, frontier AI models helped chain the bugs into working exploits, and the code had been sitting there for years.<\/li>\n\n\n\n<li>Many organisations, including government agencies in several countries and the Wikimedia Foundation, took sites offline as a precaution. <em>(Verify the country list against the Reuters factbox before publishing.)<\/em><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">When heise reported, no successful exploits had been confirmed, though attacks had begun. Full details are in our <a href=\"https:\/\/www.getastra.com\/blog\/security-advisory\/php2shell-php-vulnerabilities\/\">PHP2Shell deep dive<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2. GitLab: CVE-2026-110264 (CVSS 10.0)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">An integer overflow in the Onigmo regex compiler gives an unauthenticated attacker code execution on self-managed GitLab CE and EE, in versions going back to 7.0. No exploitation was confirmed as of October 22 and the CVE isn\u2019t in CISA\u2019s KEV catalog, but a pre-auth CVSS 10 rarely stays quiet.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>If you upgraded on October 12 and closed the ticket, you\u2019re exposed again. That patch fixed a different bug.<\/li>\n\n\n\n<li>This is the fourth regex-engine RCE in about a month, all from the same researcher. We read that as an engine in an active disclosure cycle, not a one-off.<\/li>\n\n\n\n<li>GitLab.com and eligible Dedicated tenants are already patched. Self-managed instances should move to 18.11.13, 19.0.10, 19.1.9, 19.2.9, 19.3.6, 19.4.3 or 19.5.1, depending on branch.<\/li>\n\n\n\n<li>GitLab holds source code, CI\/CD variables, deploy keys and runner credentials, so a foothold here doesn\u2019t stay here.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The same release fixes 11 other issues. More in our <a href=\"https:\/\/www.getastra.com\/blog\/security-advisory\/cve-2026-110264-gitlabs-critical-cvss-10-0-regex-rce-explained\/\">GitLab deep dive<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">3. Node.js: ten CVEs, one RCE<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The project shipped fixes for 26.x, 24.x and 22.x on October 21, covering 10 CVEs (4 high, 3 medium, 3 low). The one to worry about is CVE-2026-111497, an out-of-bounds write in the Brotli decoder that allows remote code execution when attacker-controlled compressed data is decoded. Nobody has reported exploitation in the wild yet.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Three other high-severity flaws break TLS hostname checks and DNS name handling.<\/li>\n\n\n\n<li>Upgrade to v22.23.4, v24.22.1 or v26.12.1 and rebuild images. Node 20.x and earlier are end of life and won\u2019t be patched.<\/li>\n\n\n\n<li>Until you can patch, consider stripping Content-Encoding: br from untrusted traffic.<\/li>\n\n\n\n<li>The quiet one is CVE-2026-106074. Apps packaged as Single Executable Applications can replay the same \u201crandom\u201d values from crypto.randomUUID() and randomInt(), so regenerate any secrets they produced.<\/li>\n\n\n\n<li>The release also carries the CA update for the eMudhra compromise.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Full breakdown in our <a href=\"https:\/\/www.getastra.com\/blog\/security-advisory\/nodejs-october-2026-security-patches\/\">Node.js deep dive<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Assume_the_secrets_are_gone_in_these\"><\/span>Assume the secrets are gone in these<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">4. LiteLLM<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">On October 21, a malicious litellm 1.107.0 reached PyPI and some Docker tags, carrying a credential stealer and a remote-code loader. According to LiteLLM\u2019s report, it was live on PyPI for 1 hour 44 minutes. That was still long enough: stolen AWS credentials were reportedly in use within hours, with credential validation, Bedrock model enumeration and IAM discovery.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The attackers got in through three engineers\u2019 GitHub accounts, apparently with stolen GitHub CLI OAuth tokens, and used them to approve a release. How the tokens were taken is still unknown.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">If a host ran 1.107.0:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Isolate it, rebuild from a trusted image, and pin to 1.106.2.<\/li>\n\n\n\n<li>Rotate everything it could reach: cloud roles, AI provider keys, database passwords, CI secrets.<\/li>\n\n\n\n<li>Don\u2019t stop at deleting the package. The credentials may already be gone.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Steps are in our <a href=\"https:\/\/www.getastra.com\/blog\/security-advisory\/litellm-supply-chain-attack\/\">LiteLLM deep dive<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">5. Railway<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Railway says it detected anomalous activity in the systems that store customer environment variables on the morning of October 21, and that an unauthorized party may have accessed encrypted variables and, for some, decrypted values. It recommends every customer rotate everything stored on the platform.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Rotation means a redeploy, and builds were paused for most of the first day. Enterprise builds returned at 04:00 UTC on October 22, Pro by 07:11, and Hobby, Free and Trial were still pending at 10:15.<\/li>\n\n\n\n<li>Railway invalidated every API token at 04:17 UTC. Recreate yours before trusting your CI\/CD.<\/li>\n\n\n\n<li>Still open: whether the intruder\u2019s access is closed, when it began, and whose variables were read. No email from Railway doesn\u2019t mean you\u2019re clear, and pausing your app doesn\u2019t help, since credentials already read stay usable.<\/li>\n\n\n\n<li>The Defiant reports that a developer tied a $370,000 theft to secrets stored on Railway. Railway hasn\u2019t confirmed that, and we haven\u2019t verified it.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The point we\u2019d keep from this one: a variable swap closes the exposure for bearer API keys. It doesn\u2019t for wallet keys, session and JWT signing secrets, application encryption keys or webhook signing secrets, and it can\u2019t undo what an attacker already learned about your infrastructure. So:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Rotate in order of what each secret can move: money, identity, data keys, the rest.<\/li>\n\n\n\n<li>Contain at the provider where you can\u2019t revoke yet.<\/li>\n\n\n\n<li>Scope replacements tightly and alert on first use. A new key written to a store that may still be open inherits the same risk.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The runbook is in our <a href=\"https:\/\/www.getastra.com\/blog\/security-advisory\/railway-breach-what-to-rotate-and-what-rotation-wont-fix\/\">Railway deep dive<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Trust you inherited\u2026sort of?<\/h3>\n\n\n\n<h3 class=\"wp-block-heading\">6. eMudhra<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Eight intermediate CA certificates issued by eMudhra were protected by private keys so weak they could be recovered from the public certificates almost instantly. A proper key is a random 384-bit value. Each of these was an integer below 256, and researcher Scott Helme reported that one was the number 4, as quoted by Help Net Security. eMudhra says a faulty key-ceremony script produced a second, weaker set of keys that got used by mistake, and that it wasn\u2019t breached.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>An attacker holding those keys could issue fraudulent HTTPS certificates, though they\u2019d still need to intercept traffic to use them.<\/li>\n\n\n\n<li>Chrome and Firefox blocked the intermediates on October 17, the day Mozilla got the report. No malicious use had been confirmed as of October 21.<\/li>\n\n\n\n<li>The gap is software that never gets revocation updates. Update OS packages, CA bundles and runtimes, and rebuild containers.<\/li>\n\n\n\n<li>If you run websites, replace any certificate chaining to the emSign ECC G3 root before Chrome removes it.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"7_Shopify_apps\"><\/span>7. Shopify apps<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This wasn\u2019t a confirmed breach of Shopify\u2019s platform. Attackers abused third-party app configuration to inject a script that sent shoppers from the real Checkout button to a lookalike payment page, then on to the real one. HulkApps, Selleasy and Swym have each confirmed incidents between October 10 and 14.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It stayed hidden for three reasons:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The payload arrived as configuration data, not a changed script file.<\/li>\n\n\n\n<li>It fired once per session.<\/li>\n\n\n\n<li>Orders still completed, so revenue looked normal. Wallet checkouts like Shop Pay weren\u2019t exposed.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">What merchants should do:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Click the real Checkout button in a fresh private window, on desktop and mobile.<\/li>\n\n\n\n<li>Look for __ctf_ keys in Session Storage.<\/li>\n\n\n\n<li>Remove any app with a custom JavaScript field you don\u2019t need.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Do a deep dive <a href=\"https:\/\/www.getastra.com\/blog\/vulnerability\/shopify-supply-chain-attack\/\">inside the HulkApps Shopify Checkout Hijack<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"8_A_data_leak_SBI\"><\/span>8. A data leak: SBI<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This isn\u2019t a vulnerability, and we have no evidence linking it to the other seven. A threat actor calling itself Siriusim claimed over 375,000 CSV rows and 2,722 PDFs tied to State Bank of India.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>SBI\u2019s October 21 filing says a preliminary review of about 375,000 records found 3,897 with personal information, including names, mobile numbers, dates of birth, addresses and loan metadata.<\/li>\n\n\n\n<li>SBI hasn\u2019t attributed the leak to that actor and is still establishing the source.<\/li>\n\n\n\n<li>Customers should expect phishing that uses real details, and verify any call or message through the official SBI app.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"What_they_have_in_common\"><\/span>What they have in common<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Six of the eight share something CVSS doesn\u2019t capture: the failed component mattered because of how much trust sat inside it. This is our reading of the day, not a vendor finding.<\/p>\n\n\n\n<div id=\"tablepress-494-scroll-wrapper\" class=\"tablepress-scroll-wrapper\">\n<table id=\"tablepress-494\" class=\"tablepress tablepress-id-494 column1-color tablepress-responsive\">\n<thead>\n<tr class=\"row-1\">\n\t<th class=\"column-1\">Incident<\/th><th class=\"column-2\">What was concentrated<\/th><th class=\"column-3\">Blast radius<\/th>\n<\/tr>\n<\/thead>\n<tbody class=\"row-striping row-hover\">\n<tr class=\"row-2\">\n\t<td class=\"column-1\">PHP2Shell<\/td><td class=\"column-2\">Every request\u2019s data, credentials included, in one worker process<\/td><td class=\"column-3\">One memory-disclosure path can expose other requests\u2019 secrets<\/td>\n<\/tr>\n<tr class=\"row-3\">\n\t<td class=\"column-1\">GitLab<\/td><td class=\"column-2\">Source code, CI\/CD variables, deploy keys, runner credentials<\/td><td class=\"column-3\">A foothold reaches everything GitLab can deploy to<\/td>\n<\/tr>\n<tr class=\"row-4\">\n\t<td class=\"column-1\">LiteLLM<\/td><td class=\"column-2\">Every LLM provider key, plus cloud credentials on the host<\/td><td class=\"column-3\">One bad install can empty the key ring<\/td>\n<\/tr>\n<tr class=\"row-5\">\n\t<td class=\"column-1\">Railway<\/td><td class=\"column-2\">Every customer\u2019s environment variables in one store<\/td><td class=\"column-3\">One intrusion puts every customer\u2019s secrets in question<\/td>\n<\/tr>\n<tr class=\"row-6\">\n\t<td class=\"column-1\">eMudhra<\/td><td class=\"column-2\">The authority to vouch for a site\u2019s identity<\/td><td class=\"column-3\">Weak keys could enable impersonation, given a network position<\/td>\n<\/tr>\n<tr class=\"row-7\">\n\t<td class=\"column-1\">Shopify apps<\/td><td class=\"column-2\">One third-party script on the page where cards are typed<\/td><td class=\"column-3\">A vendor\u2019s admin tool became the checkout\u2019s weakest link<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<!-- #tablepress-494 from cache -->\n\n\n\n<p class=\"wp-block-paragraph\">Patching removes a flaw. It does nothing about concentration. The better question for a leadership team isn\u2019t \u201care we patched?\u201d but \u201cif this one component were owned tomorrow, what would the attacker hold?\u201d Teams that can answer with a list instead of a guess will triage a day like this much faster.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We found no public evidence that the eight were coordinated, though Railway ties its own incident to a broader campaign against platform companies. Until something says otherwise, we\u2019d treat the clustering as coincidence plus shared root causes.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"3_clocks_and_only_1_is_yours\"><\/span>3 clocks, and only 1 is yours<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Most programs track time to patch. This day ran on three clocks.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The exploitation clock (PHP2Shell, GitLab, Node.js) is the gap between disclosure and attack. AI-built exploits hint that it\u2019s shrinking, and it\u2019s the one your patch metrics already cover.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The exposure clock (LiteLLM, Railway, eMudhra, Shopify, SBI) started before anyone told you. LiteLLM\u2019s malicious PyPI release was live for 1 hour 44 minutes; the affected Docker tags remained available for about 2 hours 34 minutes. Railway hasn\u2019t said when access began. The Shopify incidents started on October 10, eleven days before the headlines. Only your logs can say what happened in that window, and nothing you patch today changes it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The vendor clock (Railway, managed Node.js runtimes, Chrome\u2019s eMudhra root removal, Shopify app vendors) runs on someone else\u2019s schedule, and for end-of-life PHP and Node.js the fix never arrives. Your job is to verify and keep a fallback.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ask for one number per clock: how fast do we patch, how far back can our logs answer <strong>\u201cwas this used?\u201d, <\/strong>and which critical systems are waiting on a vendor?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"What_could_an_attacker_see_before_you_did\"><\/span>What could an attacker see before you did?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">We build external testing, so we start from the attacker\u2019s side of the perimeter. Three of the eight are invisible or nearly so from there, and three more are only partly visible.<\/p>\n\n\n\n<div id=\"tablepress-495-scroll-wrapper\" class=\"tablepress-scroll-wrapper\">\n<table id=\"tablepress-495\" class=\"tablepress tablepress-id-495 column1-color tablepress-responsive\">\n<thead>\n<tr class=\"row-1\">\n\t<th class=\"column-1\">Incident<\/th><th class=\"column-2\">Visible from outside?<\/th>\n<\/tr>\n<\/thead>\n<tbody class=\"row-striping row-hover\">\n<tr class=\"row-2\">\n\t<td class=\"column-1\">eMudhra<\/td><td class=\"column-2\">Yes. Certificate chains are public<\/td>\n<\/tr>\n<tr class=\"row-3\">\n\t<td class=\"column-1\">Shopify apps<\/td><td class=\"column-2\">With effort. You have to test the journey, and the payload fired once per session<\/td>\n<\/tr>\n<tr class=\"row-4\">\n\t<td class=\"column-1\">PHP2Shell, GitLab<\/td><td class=\"column-2\">Partly. Versions are sometimes exposed; exploitability and unrestarted workers aren\u2019t<\/td>\n<\/tr>\n<tr class=\"row-5\">\n\t<td class=\"column-1\">SBI<\/td><td class=\"column-2\">Partly, and only after the fact, through dark-web monitoring<\/td>\n<\/tr>\n<tr class=\"row-6\">\n\t<td class=\"column-1\">Node.js<\/td><td class=\"column-2\">Rarely. Runtime versions and container layers are seldom exposed<\/td>\n<\/tr>\n<tr class=\"row-7\">\n\t<td class=\"column-1\">LiteLLM, Railway<\/td><td class=\"column-2\">No. They live inside builds, runtimes and a platform\u2019s secret store<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<!-- #tablepress-495 from cache -->\n\n\n\n<p class=\"wp-block-paragraph\">External testing is the right control for the visible half. For the rest you need an inside-out record of what you run: a software bill of materials, a secrets inventory, and a list of every third-party script near checkout. No external scanner replaces that.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1678\" height=\"899\" src=\"\/cdn-cgi\/image\/quality=80,format=auto,onerror=redirect,metadata=none\/https:\/\/cdn-blog.getastra.com\/2026\/10\/3fe669f8-image-16.png\" alt=\"PHP2Shell testing DAST scanner Astra \" class=\"wp-image-49634\" style=\"aspect-ratio:1.862686567164179;width:624px;height:auto\" srcset=\"\/cdn-cgi\/image\/quality=80,format=auto,onerror=redirect,metadata=none\/https:\/\/storage.googleapis.com\/cdn-blog.getastra.com\/2026\/10\/3fe669f8-image-16.png 1678w, \/cdn-cgi\/image\/quality=80,format=auto,onerror=redirect,metadata=none\/https:\/\/storage.googleapis.com\/cdn-blog.getastra.com\/2026\/10\/3fe669f8-image-16.png 1536w\" sizes=\"auto, (max-width: 1678px) 100vw, 1678px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"What_would_have_broken_the_chain\"><\/span>What would have broken the chain<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u201cPatch, rotate, monitor\u201d isn\u2019t specific enough for a security team. Below are controls that would have interrupted the attacks where the chain is known, and where each one runs out. We don\u2019t know which the victims had, so read this as analysis of controls, not criticism of anyone.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For LiteLLM\u2019s release pipeline: trusted publishing pinned to one repository and workflow, provenance attestations, alerts on workflow-file changes and branch-protection overrides, and a cooldown on new releases. Even a 24-hour delay would have skipped a window under two hours. The limits are that three compromised reviewers can satisfy a required-review rule, and cooldowns delay real security fixes, so exempt vetted urgent updates.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Note: Provenance attestations help identify which workflow produced an artifact, but do not by themselves prove that the checked-out source was untampered.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For stored secrets (Railway, LiteLLM): short-lived credentials through OIDC federation so stolen values expire, provider-side scoping such as spend caps and IP conditions, and canary credentials that tell you when a store has been read and used. None of that scopes signing, encryption or webhook secrets; not every integration supports federation, and canaries detect without preventing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For the storefront: a Content Security Policy, PCI DSS 4.0.1 requirements 6.4.3 and 11.6.1 (script inventory and tamper detection), and synthetic checkout tests. The scripts were authorized and the windows were short (Swym about 1 hour 50 minutes, Selleasy about seven hours), so a weekly tamper check misses both. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ask app vendors about MFA and least privilege on their admin tools before you install, since you can\u2019t enforce it afterwards.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For certificate trust: Certificate Transparency monitoring, and trust-store reduction or pinning for clients you control. CAA records do nothing against an attacker holding a trusted intermediate\u2019s key, and absence from CT logs isn\u2019t proof of safety. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For PHP2Shell, GitLab and Node.js the control is the patch plus less exposure while you roll it out: a WAF as a stopgap, GitLab behind a VPN or allow-list, and decompression of attacker-controlled data only where you must.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"What_we_dont_know\"><\/span>What we don\u2019t know<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Several claims above rest on a single vendor statement or report. This is where the evidence stops.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>PHP2Shell, GitLab, Node.js:<\/strong> Exploitation status is still a snapshot, not an all-clear: PHP2Shell attempts and PoCs have been reported, while GitLab and Node.js had no reported exploitation as of October 22; assume this can change quickly.<\/li>\n\n\n\n<li><strong>LiteLLM:<\/strong> How the developer tokens were stolen, how many installs ran the stealer, and how much data left.<\/li>\n\n\n\n<li><strong>Railway:<\/strong> Details of when access began, whether it\u2019s closed, and whose variables were read. The status page recorded an outage from 07:24 UTC on October 21, and the security notice came at 21:59, 14 hours 35 minutes later. Public sources don\u2019t say whether the two are related.<\/li>\n\n\n\n<li><strong>eMudhra:<\/strong> How long the keys were exposed, whether unlogged forged certificates were ever used, and whether Chrome\u2019s root removal is done or planned.<\/li>\n\n\n\n<li><strong>Shopify apps:<\/strong> The exact mechanism, how many stores and shoppers were affected, and the full list of apps.<\/li>\n\n\n\n<li><strong>SBI:<\/strong> Whether the dataset is authentic or current, and what\u2019s in the claimed PDFs.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>The AI angle<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">AI helped researchers turn long-standing PHP bugs into working exploits, which narrows the gap between a flaw existing and a flaw being exploited.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">AI infrastructure is a target too: LiteLLM sits between applications and their provider keys, and Railway tied its incident to attacks on AI inference providers. Defenders have the same tools for finding and validating exposure faster, and we\u2019d encourage using them.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Five questions for Monday\u2019s leadership meeting<\/strong><\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>If our most trusted component were compromised tomorrow, what would the attacker hold? Can we list every secret in it?<\/li>\n\n\n\n<li>Which critical systems can only be fixed by a vendor, and what\u2019s our fallback while we wait?<\/li>\n\n\n\n<li>Can we revoke a leaked key in minutes without taking production down?<\/li>\n\n\n\n<li>How far back can our logs answer \u201cwas this used?\u201d<\/li>\n\n\n\n<li>Do we have an inventory of what runs inside our builds and runtimes: packages, trust stores, and third-party scripts near checkout?<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Where_can_Astra_help\"><\/span>Where can Astra help?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Start with the fix: patch, restart workers, verify the running version, and rotate what may be exposed. Beyond that, here\u2019s where we can help.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Find your PHP2Shell exposure quickly.<\/strong> Astra\u2019s Emerging Threat Scan and Lightning Scan run targeted checks for newly disclosed vulnerabilities, so they\u2019re the fastest way to check your internet-facing assets. Our Full Scan covers PHP2Shell too. A scan tells you where you\u2019re exposed, and a clean result is a starting point, not a guarantee. You should still audit the PHP versions you run and upgrade.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"2048\" height=\"1330\" src=\"\/cdn-cgi\/image\/quality=80,format=auto,onerror=redirect,metadata=none\/https:\/\/cdn-blog.getastra.com\/2026\/10\/d79c0dc8-image.png\" alt=\"PHP2Shell testing by Astra security\" class=\"wp-image-49641\" style=\"aspect-ratio:1.5407407407407407;width:624px;height:auto\" srcset=\"\/cdn-cgi\/image\/quality=80,format=auto,onerror=redirect,metadata=none\/https:\/\/cdn-blog.getastra.com\/2026\/10\/d79c0dc8-image.png 2048w, \/cdn-cgi\/image\/quality=80,format=auto,onerror=redirect,metadata=none\/https:\/\/cdn-blog.getastra.com\/2026\/10\/d79c0dc8-image.png 354w, \/cdn-cgi\/image\/quality=80,format=auto,onerror=redirect,metadata=none\/https:\/\/cdn-blog.getastra.com\/2026\/10\/d79c0dc8-image.png 1536w\" sizes=\"auto, (max-width: 2048px) 100vw, 2048px\" \/><\/figure>\n\n\n<div class=\"gb-container gb-container-e43a8917\">\n\n<p class=\"wp-block-paragraph\"><strong>Check PHP2Shell exposure for free:<\/strong> Use Astra\u2019s <a href=\"https:\/\/php2shell.getastra.com\/\" target=\"_blank\" rel=\"noopener\">PHP2Shell Checker<\/a> to test a public URL against the fixed PHP releases (8.2.35, 8.3.36, 8.4.27, and 8.5.12). It requires no account, but a clean result only confirms the detected PHP version is patched; it is not a full security assessment.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For hidden headers or internal systems, verify the installed PHP build directly.&nbsp;<\/p>\n\n<\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>Check whether it\u2019s actually exploitable.<\/strong> Autonomous Pentest tests whether an exposed application can be attacked in your setup, which helps you decide what to fix first.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Make sure the fix holds.<\/strong> Through our PTaaS platform, new exposure is caught as it appears, and findings are re-tested after you patch. They\u2019re tracked in one dashboard, and a human tester handles the judgment calls. That matters on a day like this, when you need to know the patch worked and not just that it was applied.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>For GitLab,<\/strong> our scans report version disclosure on exposed instances, and an Emerging Threat Scan is a quick way to see what your internet-facing assets reveal.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">After a credential incident like Railway or LiteLLM, a targeted assessment can confirm that old credentials are dead, no attacker-created users, keys or roles remain, and your cloud IAM can\u2019t be escalated from a single leaked key.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Final_Thoughts\"><\/span>Final Thoughts<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">October 21 showed that \u201care we patched?\u201d is only the first question after an incident. Three of the eight incidents could be handled with an upgrade. For the other five, the exposure had started before anyone told you, sat inside a vendor\u2019s platform, or was already out in the open, and a patch changes none of that.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The practical order of work is simple. Start with what exposes the most systems: find your PHP runtimes, patch them, and verify what\u2019s actually running. Rotate secrets by what they can move, starting with money. Then work through the vendor-dependent items, and keep a fallback while you wait on them.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The harder lesson sits underneath. The failed components mattered because so much trust was concentrated in them: a worker process, a CI system, an AI gateway, a secrets store, a certificate authority, a checkout page.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The next incident will hit a different component, and the teams that handle it fastest will be the ones that can say what an attacker would hold if it were compromised, how far back their logs can answer \u201cwas this used?\u201d, and which systems only a vendor can fix.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Several questions are still open, including Railway\u2019s intrusion status, how LiteLLM\u2019s tokens were stolen, whether the eMudhra keys were ever used, and the full scope of the Shopify and SBI incidents. We\u2019ll keep updating this post as vendors publish more. If you\u2019re working through a response and want a second pair of eyes on your exposure, we\u2019re glad to help.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Update log<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Oct 22:<\/strong> Initial post. We\u2019re tracking Railway\u2019s intrusion status, how LiteLLM\u2019s tokens were stolen (and its enterprise disclosure, scheduled for October 27), any use of the eMudhra keys, Chrome\u2019s decision on the root, SBI\u2019s investigation, and the full list of affected Shopify apps.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Sources<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Astra deep dives: <a href=\"https:\/\/www.getastra.com\/blog\/security-advisory\/php2shell-php-vulnerabilities\/\">PHP2Shell<\/a>, <a href=\"https:\/\/www.getastra.com\/blog\/security-advisory\/litellm-supply-chain-attack\/\">LiteLLM<\/a>, <a href=\"https:\/\/www.getastra.com\/blog\/security-advisory\/cve-2026-110264-gitlabs-critical-cvss-10-0-regex-rce-explained\/\">GitLab<\/a>, <a href=\"https:\/\/www.getastra.com\/blog\/security-advisory\/nodejs-october-2026-security-patches\/\">Node.js<\/a>, <a href=\"https:\/\/www.getastra.com\/blog\/security-advisory\/railway-breach-what-to-rotate-and-what-rotation-wont-fix\/\">Railway<\/a><\/li>\n\n\n\n<li>Primary sources: LiteLLM incident report, Railway security disclosure, Node.js October 2026 security releases, Beazley Security advisory, Wiz Research, PHP advisories for CVE-2026-109618 and CVE-2026-109619, Mozilla dev-security-policy thread, Help Net Security, Google\u2019s response on eMudhra, HulkApps, Selleasy and Swym statements, SBI regulatory filing, The Hacker News, The Defiant, Reuters, heise<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>A day-two guide for security leaders: what to do now, today and this week, which controls would have broken each attack, and where the evidence is still thin. Last updated: October 22, 2026. We update this post as vendors publish new details. The update log is at the bottom. Most security and modern incident response &#8230; <a title=\"When Foundations Fail: Lessons in Modern Incident Response\u00a0\" class=\"read-more\" href=\"https:\/\/www.getastra.com\/blog\/security-advisory\/modern-incident-response\/\" aria-label=\"Read more about When Foundations Fail: Lessons in Modern Incident Response\u00a0\">Read more<\/a><\/p>\n","protected":false},"author":111,"featured_media":49656,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[819],"tags":[],"class_list":["post-49639","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-security-advisory"],"_links":{"self":[{"href":"https:\/\/www.getastra.com\/blog\/wp-json\/wp\/v2\/posts\/49639","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.getastra.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.getastra.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.getastra.com\/blog\/wp-json\/wp\/v2\/users\/111"}],"replies":[{"embeddable":true,"href":"https:\/\/www.getastra.com\/blog\/wp-json\/wp\/v2\/comments?post=49639"}],"version-history":[{"count":2,"href":"https:\/\/www.getastra.com\/blog\/wp-json\/wp\/v2\/posts\/49639\/revisions"}],"predecessor-version":[{"id":49666,"href":"https:\/\/www.getastra.com\/blog\/wp-json\/wp\/v2\/posts\/49639\/revisions\/49666"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.getastra.com\/blog\/wp-json\/wp\/v2\/media\/49656"}],"wp:attachment":[{"href":"https:\/\/www.getastra.com\/blog\/wp-json\/wp\/v2\/media?parent=49639"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.getastra.com\/blog\/wp-json\/wp\/v2\/categories?post=49639"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.getastra.com\/blog\/wp-json\/wp\/v2\/tags?post=49639"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}