<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Incident Response | FirewallSync</title><link>https://firewallsync.com/tags/incident-response/</link><description>Practical cybersecurity writing for engineering teams that ship fast.</description><language>en-us</language><image><url>https://firewallsync.com/icon-512.png</url><title>FirewallSync</title><link>https://firewallsync.com/</link></image><lastBuildDate>Sat, 31 Oct 2026 05:00:00 +0000</lastBuildDate><atom:link href="https://firewallsync.com/tags/incident-response/index.xml" rel="self" type="application/rss+xml"/><item><title>Ivanti CVE-2026-111357 and CVE-2026-118527: What to Do</title><link>https://firewallsync.com/posts/ivanti-connect-secure-cve-2026-111357-cve-2026-118527-kev/</link><guid>https://firewallsync.com/posts/ivanti-connect-secure-cve-2026-111357-cve-2026-118527-kev/</guid><pubDate>Sat, 31 Oct 2026 05:00:00 +0000</pubDate><dc:creator>John Marshall</dc:creator><category>Security Operations</category><description>CISA added two more Ivanti Connect Secure flaws to KEV on 30 October: CVE-2026-111357, a privilege escalation to root, and CVE-2026-118527, a predictable-identifier bug that lets an authenticated attacker write files to a known path. Both chain with CVE-2026-104935, the authentication bypass Ivanti patched on 13 October. Here is what the public records confirm, what they do not, and what to do before the 2 November KEV deadline.</description><enclosure url="https://firewallsync.com/posts/ivanti-connect-secure-cve-2026-111357-cve-2026-118527-kev/cover_hu10585840409955398963.jpg" type="image/jpeg" length="0"/><media:content url="https://firewallsync.com/posts/ivanti-connect-secure-cve-2026-111357-cve-2026-118527-kev/cover_hu10585840409955398963.jpg" medium="image" type="image/jpeg" width="1200" height="630"/><content:encoded><![CDATA[<p><img src="https://firewallsync.com/posts/ivanti-connect-secure-cve-2026-111357-cve-2026-118527-kev/cover_hu10585840409955398963.jpg" alt="Close-up of three thick, rusty steel chain links, the nearest in sharp focus and the rest fading into a blurred grey background" width="1200" height="630"></p><p>If you run Ivanti Connect Secure, the job this weekend is the same as two weeks ago, only with less room for doubt. On 30 October 2026 CISA added two more Connect Secure flaws to its <a href="https://github.com/cisagov/kev-data">Known Exploited Vulnerabilities catalog</a>: <strong>CVE-2026-111357</strong>, a privilege escalation to root, and <strong>CVE-2026-118527</strong>, a predictable-identifier bug that lets an authenticated attacker write files to a known location on disk. KEV says both chain with <strong>CVE-2026-104935</strong>, the authentication bypass Ivanti patched on 13 October.</p>
<p>Upgrade to a release that fixes CVE-2026-104935 if you have not already. Then treat any appliance that was exposed on 22.8R2.4 or earlier during October as a possible compromise. As of 31 October we could not find a public fixed version for either of the two new CVEs, and the sections below explain why.</p>
<h2 id="the-three-cves-in-the-chain">The three CVEs in the chain</h2>
<table>
  <thead>
      <tr>
          <th></th>
          <th>CVE-2026-104935</th>
          <th>CVE-2026-118527</th>
          <th>CVE-2026-111357</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>What KEV calls it</td>
          <td>Authentication bypass by spoofing</td>
          <td>Generation of predictable numbers or identifiers</td>
          <td>Missing authentication for critical function</td>
      </tr>
      <tr>
          <td>Attacker position (KEV text)</td>
          <td>Remote, unauthenticated</td>
          <td>Remote, authenticated</td>
          <td>Local, authenticated</td>
      </tr>
      <tr>
          <td>Effect (KEV / CVE text)</td>
          <td>Execute arbitrary commands</td>
          <td>Upload files with attacker-controlled content to a known location on disk</td>
          <td>Privilege escalation; the CVE record says &ldquo;to root&rdquo;</td>
      </tr>
      <tr>
          <td>CWE</td>
          <td>CWE-290</td>
          <td>CWE-340</td>
          <td>KEV: CWE-306, CWE-862, CWE-345. CVE record: CWE-829</td>
      </tr>
      <tr>
          <td>Added to KEV</td>
          <td>2026-10-13</td>
          <td>2026-10-30</td>
          <td>2026-10-30</td>
      </tr>
      <tr>
          <td>KEV due date</td>
          <td>2026-10-16</td>
          <td>2026-11-13</td>
          <td>2026-11-02</td>
      </tr>
      <tr>
          <td>KEV forensic triage</td>
          <td>Yes</td>
          <td>No</td>
          <td>Yes</td>
      </tr>
      <tr>
          <td>CVE record</td>
          <td>Published by Ivanti, CVSS 3.1 8.6</td>
          <td>No published record found on 31 Oct</td>
          <td>Published by MITRE, CVSS 3.1 7.0</td>
      </tr>
  </tbody>
</table>
<p>The KEV entries for CVE-2026-118527 and CVE-2026-111357 both say the flaw &ldquo;can be chained with&rdquo; the other two. Read together, the descriptions fit a familiar pattern: an unauthenticated foothold, a way to place attacker-controlled content where the appliance will find it, then a jump to root. That ordering is our reading of the descriptions. Neither Ivanti nor CISA has published the step-by-step mechanics.</p>
<p>The MITRE record for CVE-2026-111357 adds one technical detail. It says Connect Secure 22.8R2.4 &ldquo;mishandles the manner in which the dsinvoked broker trusts DSCache configuration data, leading to privilege escalation to root, as exploited in the wild in October 2026.&rdquo;</p>
<p>If you track these programmatically, this pulls the three entries from CISA&rsquo;s KEV JSON. We ran it with Python 3.13 on 31 October; it uses only the standard library:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">import</span> json<span style="color:#f92672">,</span> urllib.request
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>URL <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;https://raw.githubusercontent.com/cisagov/kev-data/main/known_exploited_vulnerabilities.json&#34;</span>
</span></span><span style="display:flex;"><span>WANT <span style="color:#f92672">=</span> {<span style="color:#e6db74">&#34;CVE-2026-104935&#34;</span>, <span style="color:#e6db74">&#34;CVE-2026-118527&#34;</span>, <span style="color:#e6db74">&#34;CVE-2026-111357&#34;</span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">with</span> urllib<span style="color:#f92672">.</span>request<span style="color:#f92672">.</span>urlopen(URL, timeout<span style="color:#f92672">=</span><span style="color:#ae81ff">30</span>) <span style="color:#66d9ef">as</span> r:
</span></span><span style="display:flex;"><span>    kev <span style="color:#f92672">=</span> json<span style="color:#f92672">.</span>load(r)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> v <span style="color:#f92672">in</span> kev[<span style="color:#e6db74">&#34;vulnerabilities&#34;</span>]:
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> v[<span style="color:#e6db74">&#34;cveID&#34;</span>] <span style="color:#f92672">in</span> WANT:
</span></span><span style="display:flex;"><span>        print(v[<span style="color:#e6db74">&#34;cveID&#34;</span>], v[<span style="color:#e6db74">&#34;dateAdded&#34;</span>], v[<span style="color:#e6db74">&#34;dueDate&#34;</span>],
</span></span><span style="display:flex;"><span>              <span style="color:#e6db74">&#34;triage=&#34;</span> <span style="color:#f92672">+</span> v<span style="color:#f92672">.</span>get(<span style="color:#e6db74">&#34;forensicTriage&#34;</span>, <span style="color:#e6db74">&#34;?&#34;</span>), <span style="color:#e6db74">&#34;,&#34;</span><span style="color:#f92672">.</span>join(v[<span style="color:#e6db74">&#34;cwes&#34;</span>]))
</span></span></code></pre></div><p>Output on 31 October:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>CVE-2026-118527 2026-10-30 2026-11-13 triage=No CWE-340
</span></span><span style="display:flex;"><span>CVE-2026-111357 2026-10-30 2026-11-02 triage=Yes CWE-306,CWE-862,CWE-345
</span></span><span style="display:flex;"><span>CVE-2026-104935 2026-10-13 2026-10-16 triage=Yes CWE-290
</span></span></code></pre></div><p>For what each field means and how to match the feed against a scanner export, see our guide to the <a href="/posts/cisa-kev-json-feed-what-each-field-means-and-how-to-match-it-against-a-scanner-export/">CISA KEV JSON feed</a>.</p>
<h2 id="what-is-fixed-and-what-is-not">What is fixed and what is not</h2>
<p><strong>CVE-2026-104935 has fixes.</strong> The CVE record Ivanti published says the bug affects &ldquo;ICS before version 25.1.3.0&rdquo; and &ldquo;does not impact ICS version 22.7R2.14 or prior&rdquo;. It lists 25.1.3.0, 25.1.3.1, 22.8R2.5 and 22.7R2.14 as unaffected.</p>
<p>Rapid7&rsquo;s write-up of Ivanti&rsquo;s advisory breaks this down by branch: 25.1.1.1 and earlier fixed in 25.1.1.2, 25.1.2.2 and earlier fixed in 25.1.3.0 and 25.1.3.1, and 22.8R2.4 and earlier fixed in 22.8R2.5. The 25.1.1.2 entry does not appear in the CVE record&rsquo;s unaffected list, so confirm it against <a href="https://hub.ivanti.com/s/article/Security-Advisory-Ivanti-Connect-Secure-CVE-2026-104935">Ivanti&rsquo;s advisory</a> before you rely on it.</p>
<p><strong>CVE-2026-111357 and CVE-2026-118527 have no fixed version that we could confirm.</strong> When Ivanti disclosed CVE-2026-104935 on 13 October, it fixed two stages of the chain. <a href="https://www.theregister.com/a/5303095">The Register</a> and <a href="https://thehackernews.com/2026/10/attacker-chains-three-ivanti-connect.html">The Hacker News</a> both reported that a third flaw, the privilege escalation, had no fix yet, and quoted Volexity saying Ivanti planned to fix it &ldquo;in the coming weeks&rdquo;.</p>
<p>Since then:</p>
<ul>
<li>The only CVE record for CVE-2026-111357 is MITRE&rsquo;s. It lists 22.8R2.4 as affected and gives no fixed version. Its references are Volexity&rsquo;s report and Ivanti&rsquo;s CVE-2026-104935 advisory, not a separate Ivanti advisory.</li>
<li>CVE-2026-118527 had no record in the CVE List repository when we checked on 31 October. Its KEV entry is the only primary description we found.</li>
<li>Both KEV entries list Ivanti&rsquo;s CVE-2026-104935 advisory as the vendor reference, and both carry CISA&rsquo;s standard required action: apply vendor mitigations, or &ldquo;discontinue use of the product if mitigations are unavailable&rdquo;.</li>
<li>Canada&rsquo;s Cyber Centre updated its advisory on 16 October to say open-source reporting indicates CVE-2026-111357 is exploited. Singapore&rsquo;s CSA alert, last updated 30 October, still names only CVE-2026-104935 and advises updating &ldquo;to the latest versions&rdquo;.</li>
</ul>
<p>We could not read Ivanti&rsquo;s advisory directly during this run, and Ivanti may have published a fix that these records do not yet reflect. Check the advisory and Ivanti&rsquo;s support portal before you decide that your current version is enough.</p>
<h2 id="why-228r24-matters">Why 22.8R2.4 matters</h2>
<p>According to The Hacker News&rsquo;s summary of Volexity&rsquo;s report, Volexity found the chain on a customer appliance running 22.8R2.4, which was fully patched at the time. That is the exact version MITRE&rsquo;s CVE-2026-111357 record lists as affected. Exploitation began on 3 October, ten days before disclosure.</p>
<p>Volexity tracks the actor as UTA0576. The same reports say the attacker:</p>
<ul>
<li>stole LDAP domain credentials from the appliance, searched Active Directory for passwords and ran password-spraying attacks;</li>
<li>used no malware or web shells, only commands already on the appliance (per The Register);</li>
<li>was assessed by Volexity, with low confidence, as criminally rather than espionage motivated.</li>
</ul>
<p>Two vendor statements limit how much you can learn from the appliance itself. Rapid7 quotes Ivanti saying &ldquo;reliable indicators of compromise are not available&rdquo;. The Hacker News reports Volexity saying the Ivanti Integrity Checker Tool does not detect this chain, even though Ivanti still recommends running it regularly.</p>
<h2 id="triage-checklist">Triage checklist</h2>
<ol>
<li><strong>Inventory.</strong> List every Connect Secure appliance and its exact version, including standby units and lab boxes that face the internet.</li>
<li><strong>Close the entry point.</strong> Upgrade anything below the fixed versions for CVE-2026-104935 (see above). This is the unauthenticated step. KEV describes the other two flaws as needing an authenticated or local attacker.</li>
<li><strong>Assume compromise on exposed 22.8R2.4-and-earlier appliances.</strong> If an appliance ran a vulnerable version on the internet during October, patching does not undo what an attacker already did. Neither Ivanti nor Volexity has said that upgrading removes existing access.</li>
<li><strong>Rotate what the appliance knows.</strong> Volexity saw LDAP credentials stolen. Rotate the directory bind account and any other service credentials stored on the appliance, and review VPN user sessions and tokens. This is our recommendation, based on the reported attacker behavior. Our explainer on <a href="/posts/what-is-token-theft-and-why-mfa-doesnt-always-stop-it/">why MFA does not always stop token theft</a> covers the session side.</li>
<li><strong>Hunt outside the appliance.</strong> With no reliable on-box IOCs, the useful signals are in your other logs:
<ul>
<li>password spraying or bursts of failed authentications from the appliance&rsquo;s internal IP against Active Directory;</li>
<li>LDAP queries from the appliance that go beyond its normal user lookups;</li>
<li>in web or WAF logs in front of the appliance, large numbers of requests to <code>/dana-na/auth/url_default/welcome.cgi</code>, and requests whose <code>X-DSCGI-PATH</code> header does not match the URL path (both indicators Volexity published, as reported by The Hacker News);</li>
<li>traffic to or from <code>108.165.147[.]64</code>, the IP Volexity listed.</li>
</ul>
</li>
<li><strong>Escalate to forensics if you find anything.</strong> Volexity says confirming compromise needs network and memory forensics. Our guide to <a href="/posts/cisa-bod-26-04-explained-kev-deadlines-forensic-triage-and-what-private-teams-can-borrow/">CISA BOD 26-04</a> explains what the KEV &ldquo;forensic triage&rdquo; flag asks of federal agencies and what private teams can borrow from it.</li>
<li><strong>Decide on exposure while you wait.</strong> Until a fix for CVE-2026-111357 is confirmed, limit who can reach the appliance where you can. KEV&rsquo;s own fallback is to stop using the product if mitigations are unavailable. Our post on the <a href="/posts/fortimail-zero-day-cve-2026-104286-no-patch-yet-what-to-do/">FortiMail zero-day with no patch</a> walks through the same decision for another edge device.</li>
</ol>
<h2 id="limits-of-this-article">Limits of this article</h2>
<ul>
<li>We did not test any of these flaws, and we have not seen exploit code.</li>
<li>We could not fetch Ivanti&rsquo;s advisory or Volexity&rsquo;s report directly. Version and fix details come from the CVE records, CISA KEV data and Rapid7&rsquo;s reproduction of the advisory. Attacker behavior and indicators come from press summaries of Volexity&rsquo;s findings, which we attribute throughout.</li>
<li>CVE-2026-118527 had no CVE record when we checked, so its description rests on one source, CISA&rsquo;s KEV entry.</li>
<li>Fix status can change quickly. Treat &ldquo;no confirmed fix&rdquo; as true for 31 October 2026 only.</li>
</ul>
<h2 id="sources-and-verification">Sources and verification</h2>
<table>
  <thead>
      <tr>
          <th>Important claim</th>
          <th>Source</th>
          <th>Status</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>KEV additions, dates, due dates, CWEs, forensic triage, &ldquo;can be chained with&rdquo;, required action</td>
          <td><a href="https://github.com/cisagov/kev-data/blob/main/known_exploited_vulnerabilities.json">CISA KEV catalog (kev-data)</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>CVE-2026-104935 description, unaffected versions, CVSS 8.6, CISA SSVC &ldquo;active&rdquo;</td>
          <td><a href="https://github.com/CVEProject/cvelistV5/blob/main/cves/2026/104xxx/CVE-2026-104935.json">CVE-2026-104935 record</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>CVE-2026-111357 description (dsinvoked, DSCache, root), affected 22.8R2.4, CVSS 7.0, MITRE as CNA</td>
          <td><a href="https://github.com/CVEProject/cvelistV5/blob/main/cves/2026/111xxx/CVE-2026-111357.json">CVE-2026-111357 record</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Per-branch fixed versions including 25.1.1.2; Ivanti: &ldquo;reliable indicators of compromise are not available&rdquo;</td>
          <td><a href="https://www.rapid7.com/blog/post/etr-ivanti-connect-secure-zero-day-exploited-in-the-wild-cve-2026-104935/">Rapid7</a></td>
          <td>Qualified (secondary)</td>
      </tr>
      <tr>
          <td>Third flaw unfixed at disclosure; Volexity on 22.8R2.4, UTA0576, LDAP theft, indicators, Integrity Checker gap</td>
          <td><a href="https://thehackernews.com/2026/10/attacker-chains-three-ivanti-connect.html">The Hacker News</a>, <a href="https://www.theregister.com/a/5303095">The Register</a></td>
          <td>Qualified (press, citing Volexity)</td>
      </tr>
      <tr>
          <td>CVE-2026-111357 reported exploited (update of 16 Oct)</td>
          <td><a href="https://cyber.gc.ca/en/alerts-advisories/ivanti-security-advisory-av26-1035">Canadian Centre for Cyber Security AV26-1035</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Singapore alert names only CVE-2026-104935 (updated 30 Oct)</td>
          <td><a href="https://www.csa.gov.sg/alerts-and-advisories/alerts/al-2026-147/">CSA Singapore AL-2026-147</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>No public fix for CVE-2026-111357 or CVE-2026-118527</td>
          <td>Absence across the sources above</td>
          <td>Qualified</td>
      </tr>
  </tbody>
</table>
]]></content:encoded></item><item><title>GitLab CVE-2026-97229: Patch the Regex RCE, Then Hunt</title><link>https://firewallsync.com/posts/gitlab-cve-2026-97229-ci-regex-rce-patch-and-hunt/</link><guid>https://firewallsync.com/posts/gitlab-cve-2026-97229-ci-regex-rce-patch-and-hunt/</guid><pubDate>Fri, 30 Oct 2026 04:40:00 +0000</pubDate><dc:creator>John Marshall</dc:creator><category>Security Operations</category><description>CISA added GitLab CVE-2026-97229, an unauthenticated remote code execution bug in how GitLab compiles regular expressions from CI/CD configuration, to KEV on October 29 with a November 1 deadline. The 19.4.2 fix is not the end of it: a sibling bug, CVE-2026-110264, needs 19.4.3 or 19.5.1. Here are the versions that close all four related CVEs, a script to check yours, GitLab's detections, and what Ruby shops outside GitLab should check.</description><enclosure url="https://firewallsync.com/posts/gitlab-cve-2026-97229-ci-regex-rce-patch-and-hunt/cover_hu18432601525673025422.jpg" type="image/jpeg" length="0"/><media:content url="https://firewallsync.com/posts/gitlab-cve-2026-97229-ci-regex-rce-patch-and-hunt/cover_hu18432601525673025422.jpg" medium="image" type="image/jpeg" width="1200" height="630"/><content:encoded><![CDATA[<p><img src="https://firewallsync.com/posts/gitlab-cve-2026-97229-ci-regex-rce-patch-and-hunt/cover_hu18432601525673025422.jpg" alt="Black-and-white photo of rows of large valve wheels on pipes along an underground corridor, with ducting overhead and a metal grate walkway" width="1200" height="630"></p><p>CVE-2026-97229 is a remote code execution bug in self-managed GitLab Community and Enterprise Edition. GitLab&rsquo;s <a href="https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-4-2-released/">19.4.2 patch release</a> says it &ldquo;could have allowed an unauthenticated user to execute arbitrary code on the GitLab server via a specially crafted regular expression in a CI/CD configuration, due to insufficient regular expression validation.&rdquo; GitLab scores it CVSS 3.1 10.0. CISA added it to the <a href="https://www.cisa.gov/known-exploited-vulnerabilities-catalog?field_cve=CVE-2026-97229">Known Exploited Vulnerabilities catalog</a> on October 29, 2026, with a due date of November 1.</p>
<p>If you run self-managed GitLab, do two things today: upgrade to the October 21 patch release for your branch (not just the October 12 one), and check for signs that someone got there first.</p>
<h2 id="what-is-affected-and-what-fixes-it">What is affected and what fixes it</h2>
<p>CVE-2026-97229 is one of four GitLab CVEs that trace back to bugs in Onigmo, the regular expression engine inside Ruby. GitLab fixed them in three patch releases between September and October. Ruby&rsquo;s own <a href="https://www.ruby-lang.org/en/news/2026/10/23/regexp-fixes-for-gitlab-cves/">advisory of October 23</a> ties them together.</p>
<table>
  <thead>
      <tr>
          <th>CVE</th>
          <th>GitLab&rsquo;s description</th>
          <th>Auth needed</th>
          <th>CVSS 3.1</th>
          <th>Affected (from the CVE record)</th>
          <th>First fixed</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>CVE-2026-89078</td>
          <td>Double free parsing a regex in CI/CD configuration</td>
          <td>Authenticated</td>
          <td>9.9</td>
          <td>19.2 before 19.2.7, 19.3 before 19.3.3, 19.4 before 19.4.1</td>
          <td>19.4.1, 19.3.3, 19.2.7</td>
      </tr>
      <tr>
          <td>CVE-2026-93577</td>
          <td>Integer overflow compiling a regex in CI/CD configuration</td>
          <td>Authenticated</td>
          <td>9.9</td>
          <td>Same as above</td>
          <td>19.4.1, 19.3.3, 19.2.7</td>
      </tr>
      <tr>
          <td><strong>CVE-2026-97229</strong></td>
          <td>Integer overflow, CI/CD regex compiler</td>
          <td><strong>Unauthenticated</strong></td>
          <td><strong>10.0</strong></td>
          <td>19.2 before 19.2.8, 19.3 before 19.3.5, 19.4 before 19.4.2</td>
          <td>19.4.2, 19.3.5, 19.2.8 (Oct 12)</td>
      </tr>
      <tr>
          <td>CVE-2026-110264</td>
          <td>Integer overflow compiling a regex</td>
          <td>Unauthenticated</td>
          <td>10.0</td>
          <td>7.0 before 18.11.13, 19.0 before 19.0.10, 19.1 before 19.1.9, 19.2 before 19.2.9, 19.3 before 19.3.6, 19.4 before 19.4.3, 19.5 before 19.5.1</td>
          <td>19.5.1, 19.4.3, 19.3.6, 19.2.9, 19.1.9, 19.0.10, 18.11.13 (Oct 21)</td>
      </tr>
  </tbody>
</table>
<p>Only CVE-2026-97229 is in KEV today. CISA&rsquo;s SSVC entries in the CVE records list Exploitation as &ldquo;active&rdquo; for CVE-2026-97229 and &ldquo;none&rdquo; for the other three, as of the dates CISA recorded them. CVE-2026-110264 is also unauthenticated and rated 10.0, and its range reaches back to GitLab 7.0, so treat it with the same urgency.</p>
<p><strong>Upgrade target:</strong> 19.5.1, 19.4.3, 19.3.6, 19.2.9, 19.1.9, 19.0.10 or 18.11.13, or anything later on the same branch. If you are on a branch older than 18.11, there is no backport; move to a supported branch. GitLab&rsquo;s <a href="https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-5-1-released/">19.5.1 release post</a> lists no workaround, only &ldquo;upgrade to the latest version as soon as possible.&rdquo;</p>
<p>GitLab.com and GitLab Dedicated are already patched, according to both release posts. This is a self-managed problem.</p>
<h3 id="check-a-version-quickly">Check a version quickly</h3>
<p>The <a href="https://docs.gitlab.com/ee/api/version">Version API</a> returns the running version (<code>GET /api/v4/version</code> with a token). The script below compares a version string against the affected ranges in the four CVE records. We ran it with Python 3.13; the output shown is real.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#75715e">#!/usr/bin/env python3</span>
</span></span><span style="display:flex;"><span><span style="color:#e6db74">&#34;&#34;&#34;Check a GitLab version against the four Onigmo regex CVEs.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">Fixed versions come from each CVE record&#39;s &#39;affected&#39; ranges (read 2026-10-30).&#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> re<span style="color:#f92672">,</span> sys
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>FIXED <span style="color:#f92672">=</span> {  <span style="color:#75715e"># CVE -&gt; {(major, minor): first fixed patch}</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;CVE-2026-89078&#34;</span>:  {(<span style="color:#ae81ff">19</span>, <span style="color:#ae81ff">2</span>): <span style="color:#ae81ff">7</span>, (<span style="color:#ae81ff">19</span>, <span style="color:#ae81ff">3</span>): <span style="color:#ae81ff">3</span>, (<span style="color:#ae81ff">19</span>, <span style="color:#ae81ff">4</span>): <span style="color:#ae81ff">1</span>},
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;CVE-2026-93577&#34;</span>:  {(<span style="color:#ae81ff">19</span>, <span style="color:#ae81ff">2</span>): <span style="color:#ae81ff">7</span>, (<span style="color:#ae81ff">19</span>, <span style="color:#ae81ff">3</span>): <span style="color:#ae81ff">3</span>, (<span style="color:#ae81ff">19</span>, <span style="color:#ae81ff">4</span>): <span style="color:#ae81ff">1</span>},
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;CVE-2026-97229&#34;</span>:  {(<span style="color:#ae81ff">19</span>, <span style="color:#ae81ff">2</span>): <span style="color:#ae81ff">8</span>, (<span style="color:#ae81ff">19</span>, <span style="color:#ae81ff">3</span>): <span style="color:#ae81ff">5</span>, (<span style="color:#ae81ff">19</span>, <span style="color:#ae81ff">4</span>): <span style="color:#ae81ff">2</span>},
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;CVE-2026-110264&#34;</span>: {(<span style="color:#ae81ff">18</span>, <span style="color:#ae81ff">11</span>): <span style="color:#ae81ff">13</span>, (<span style="color:#ae81ff">19</span>, <span style="color:#ae81ff">0</span>): <span style="color:#ae81ff">10</span>, (<span style="color:#ae81ff">19</span>, <span style="color:#ae81ff">1</span>): <span style="color:#ae81ff">9</span>, (<span style="color:#ae81ff">19</span>, <span style="color:#ae81ff">2</span>): <span style="color:#ae81ff">9</span>,
</span></span><span style="display:flex;"><span>                        (<span style="color:#ae81ff">19</span>, <span style="color:#ae81ff">3</span>): <span style="color:#ae81ff">6</span>, (<span style="color:#ae81ff">19</span>, <span style="color:#ae81ff">4</span>): <span style="color:#ae81ff">3</span>, (<span style="color:#ae81ff">19</span>, <span style="color:#ae81ff">5</span>): <span style="color:#ae81ff">1</span>},
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>OLD_RANGE_START <span style="color:#f92672">=</span> {<span style="color:#e6db74">&#34;CVE-2026-110264&#34;</span>: (<span style="color:#ae81ff">7</span>, <span style="color:#ae81ff">0</span>)}  <span style="color:#75715e"># affected from 7.0, no fix before 18.11</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">check</span>(ver):
</span></span><span style="display:flex;"><span>    major, minor, patch <span style="color:#f92672">=</span> map(int, re<span style="color:#f92672">.</span><span style="color:#66d9ef">match</span>(<span style="color:#e6db74">r</span><span style="color:#e6db74">&#34;(\d+)\.(\d+)\.(\d+)&#34;</span>, ver)<span style="color:#f92672">.</span>groups())
</span></span><span style="display:flex;"><span>    branch, out <span style="color:#f92672">=</span> (major, minor), {}
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">for</span> cve, fixes <span style="color:#f92672">in</span> FIXED<span style="color:#f92672">.</span>items():
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> branch <span style="color:#f92672">in</span> fixes:
</span></span><span style="display:flex;"><span>            out[cve] <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;FIXED&#34;</span> <span style="color:#66d9ef">if</span> patch <span style="color:#f92672">&gt;=</span> fixes[branch] <span style="color:#66d9ef">else</span> <span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;VULNERABLE (fixed in </span><span style="color:#e6db74">{</span>major<span style="color:#e6db74">}</span><span style="color:#e6db74">.</span><span style="color:#e6db74">{</span>minor<span style="color:#e6db74">}</span><span style="color:#e6db74">.</span><span style="color:#e6db74">{</span>fixes[branch]<span style="color:#e6db74">}</span><span style="color:#e6db74">)&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">elif</span> branch <span style="color:#f92672">&gt;</span> max(fixes):
</span></span><span style="display:flex;"><span>            out[cve] <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;FIXED (newer branch)&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">elif</span> cve <span style="color:#f92672">in</span> OLD_RANGE_START <span style="color:#f92672">and</span> branch <span style="color:#f92672">&gt;=</span> OLD_RANGE_START[cve]:
</span></span><span style="display:flex;"><span>            out[cve] <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;VULNERABLE (no fix on this branch)&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">else</span>:
</span></span><span style="display:flex;"><span>            out[cve] <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;not in affected range&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> out
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> v <span style="color:#f92672">in</span> sys<span style="color:#f92672">.</span>argv[<span style="color:#ae81ff">1</span>:]:
</span></span><span style="display:flex;"><span>    print(v)
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">for</span> cve, status <span style="color:#f92672">in</span> check(v)<span style="color:#f92672">.</span>items():
</span></span><span style="display:flex;"><span>        print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;  </span><span style="color:#e6db74">{</span>cve<span style="color:#e6db74">:</span><span style="color:#e6db74">16</span><span style="color:#e6db74">}</span><span style="color:#e6db74"> </span><span style="color:#e6db74">{</span>status<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>$ python3 check_gitlab_regex_cves.py 19.4.2-ee 18.9.4
</span></span><span style="display:flex;"><span>19.4.2-ee
</span></span><span style="display:flex;"><span>  CVE-2026-89078   FIXED
</span></span><span style="display:flex;"><span>  CVE-2026-93577   FIXED
</span></span><span style="display:flex;"><span>  CVE-2026-97229   FIXED
</span></span><span style="display:flex;"><span>  CVE-2026-110264  VULNERABLE (fixed in 19.4.3)
</span></span><span style="display:flex;"><span>18.9.4
</span></span><span style="display:flex;"><span>  CVE-2026-89078   not in affected range
</span></span><span style="display:flex;"><span>  CVE-2026-93577   not in affected range
</span></span><span style="display:flex;"><span>  CVE-2026-97229   not in affected range
</span></span><span style="display:flex;"><span>  CVE-2026-110264  VULNERABLE (no fix on this branch)
</span></span></code></pre></div><p>The first result is the trap: an instance patched promptly on October 12 for the CVE that is now in KEV is still exposed to the sibling bug.</p>
<h2 id="how-the-bug-works-as-far-as-the-sources-say">How the bug works, as far as the sources say</h2>
<p>GitLab lets users supply regular expressions in places such as CI/CD configuration and compiles them with Ruby. Ruby&rsquo;s advisory explains: &ldquo;GitLab compiles regular expressions supplied by its users, such as patterns in CI configuration, with <code>Regexp.new</code>. GitLab found that specially crafted patterns could corrupt memory while Ruby compiles them, and that this could be turned into remote code execution on GitLab servers.&rdquo;</p>
<p>The Ruby change behind CVE-2026-97229 (and CVE-2026-93577) is described as an &ldquo;Integer overflow in the size of a compiled pattern&rdquo;, fixed in <a href="https://github.com/ruby/ruby/pull/19020">ruby/ruby#19020</a>. GitLab patched the Ruby it ships rather than waiting for a Ruby release.</p>
<p>GitLab says the bug is reachable by an unauthenticated user &ldquo;under certain conditions&rdquo; and does not spell those conditions out. The names of GitLab&rsquo;s own detections (below) refer to the CI Lint feature and its GraphQL endpoint, which suggests where to look first, but that is our reading of the detection names, not a statement from GitLab. No public write-up of the exploitation we could find gives more detail; treat any blog that claims a precise attack path without citing GitLab or the reporter with caution.</p>
<h2 id="hunt-gitlabs-detections">Hunt: GitLab&rsquo;s detections</h2>
<p>The 19.4.2 release post lists six detections for self-managed instances, each linked to a write-up in GitLab&rsquo;s <a href="https://gitlab.com/gitlab-security-oss/tldr"><code>gitlab-security-oss/tldr</code> repository</a> under <code>Detections/platforms/GitLab/Vulnerability Detections/</code>:</p>
<table>
  <thead>
      <tr>
          <th>Detection name</th>
          <th>File</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Onigmo native worker crash</td>
          <td><code>onigmo_native_worker_crash.md</code></td>
      </tr>
      <tr>
          <td>Graphql cilint hostile regexp</td>
          <td><code>graphql_cilint_hostile_regexp.md</code></td>
      </tr>
      <tr>
          <td>ci regexp oversized non ascii path</td>
          <td><code>ci_regexp_oversized_non_ascii_path.md</code></td>
      </tr>
      <tr>
          <td>ci regexp guard rejection</td>
          <td><code>ci_regexp_guard_rejection.md</code></td>
      </tr>
      <tr>
          <td>ci lint workhorse worker crash</td>
          <td><code>ci_lint_workhorse_worker_crash.md</code></td>
      </tr>
      <tr>
          <td>ci lint scripted client error burst</td>
          <td><code>ci_lint_scripted_client_error_burst.md</code></td>
      </tr>
  </tbody>
</table>
<p>The 19.5.1 post adds two for CVE-2026-110264: &ldquo;Onigmo native worker crash&rdquo; and &ldquo;Org mode render error burst&rdquo;.</p>
<p>We have not reproduced these detections; use GitLab&rsquo;s files for the exact log sources and queries. Practical order of work:</p>
<ol>
<li><strong>Look back before the patch date.</strong> Run the detections over logs as far back as your retention allows, up to the moment you upgraded. Worker crashes in the regex engine are not normal background noise.</li>
<li><strong>Assume the GitLab host is a credential store.</strong> A GitLab server holds CI/CD variables, runner registration tokens, deploy keys, and access tokens. If you find hits, or you cannot rule exploitation out, rotate those secrets and review recent pipeline and runner activity. Our guide to <a href="/posts/how-to-detect-and-rotate-leaked-api-keys-before-attackers-use-them/">detecting and rotating leaked API keys</a> covers the rotation order.</li>
<li><strong>Check for persistence.</strong> Look for new admin users, personal access tokens you did not create, new SSH keys on admin accounts, and unexpected files or processes on the host.</li>
</ol>
<p>KEV marks this entry <code>forensicTriage: Yes</code>. Under CISA&rsquo;s BOD 26-04 that means federal agencies must collect forensic data, not just patch; our <a href="/posts/cisa-bod-26-04-explained-kev-deadlines-forensic-triage-and-what-private-teams-can-borrow/">BOD 26-04 explainer</a> covers what that involves and what private teams can borrow.</p>
<h2 id="if-you-run-ruby-but-not-gitlab">If you run Ruby but not GitLab</h2>
<p>Ruby released 4.0.9, 3.4.12 and 3.3.13 with fixes for all the underlying Onigmo bugs. Ruby&rsquo;s advisory is precise about who is affected:</p>
<blockquote>
<p>These bugs are reached only when an application compiles a regular expression from a string that an attacker controls, for example by passing it to <code>Regexp.new</code>, <code>Regexp.union</code> or <code>Regexp.compile</code>, or by interpolating it into a regexp literal such as <code>/#{input}/</code>. Applications that only use regular expressions written by their own developers are not affected.</p>
</blockquote>
<p>Two points in that advisory matter for anyone building search filters, routing rules or admin &ldquo;match by pattern&rdquo; features:</p>
<ul>
<li>&ldquo;<code>Regexp.timeout</code> does not protect against these bugs.&rdquo; Timeouts address ReDoS, not memory corruption during compilation.</li>
<li>&ldquo;Limiting the length of patterns does not reliably protect against them either, because some of them can be triggered by short patterns.&rdquo;</li>
</ul>
<p>Ruby has not requested its own CVE IDs, so scanners may not flag your Ruby runtime. A quick way to find candidates in a codebase (illustrative, not exhaustive):</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>grep -rnE <span style="color:#e6db74">&#39;Regexp\.(new|union|compile)\(|/[^/]*#\{&#39;</span> --include<span style="color:#f92672">=</span><span style="color:#e6db74">&#39;*.rb&#39;</span> app lib
</span></span></code></pre></div><p>Review each hit for whether the pattern can come from a user. If it can, upgrade Ruby, and consider whether users need regexes at all: plain substring or glob matching is a much smaller attack surface.</p>
<h2 id="limits-of-this-article">Limits of this article</h2>
<ul>
<li>GitLab has not published the exact preconditions for unauthenticated exploitation, and we have not tested an exploit. The CI Lint connection above is inferred from detection names.</li>
<li>KEV listing tells you exploitation has happened, not how widely. We found no primary source for a count of exposed or compromised instances.</li>
<li>Version data comes from the CVE records as updated on 2026-10-30. If GitLab revises them, the records win over this page.</li>
</ul>
<p>For how to weigh a KEV entry against CVSS and EPSS in your own queue, see <a href="/posts/cvss-vs-epss-vs-kev-which-signal-should-decide-what-you-patch-first/">CVSS vs EPSS vs KEV</a>, and for reading the SSVC values quoted above, <a href="/posts/cisa-vulnrichment-how-to-read-ssvc-values-in-a-cve-record-and-turn-them-into-a-patch-decision/">our Vulnrichment guide</a>.</p>
<h2 id="sources-and-verification">Sources and verification</h2>
<table>
  <thead>
      <tr>
          <th>Important claim</th>
          <th>Source</th>
          <th>Status</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>KEV addition 2026-10-29, due 2026-11-01, CWE-190, forensic triage &ldquo;Yes&rdquo;, ransomware use &ldquo;Unknown&rdquo;</td>
          <td><a href="https://github.com/cisagov/kev-data/blob/main/known_exploited_vulnerabilities.json">CISA KEV catalog (kev-data)</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Description, CVSS 10.0 vector, affected ranges, fix versions, reporter credit</td>
          <td><a href="https://github.com/CVEProject/cvelistV5/blob/main/cves/2026/97xxx/CVE-2026-97229.json">CVE-2026-97229 record</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>SSVC Exploitation &ldquo;active&rdquo; for CVE-2026-97229; &ldquo;none&rdquo; for the other three</td>
          <td>CISA ADP entries in each CVE record (<a href="https://github.com/CVEProject/cvelistV5/blob/main/cves/2026/97xxx/CVE-2026-97229.json">97229</a>, <a href="https://github.com/CVEProject/cvelistV5/blob/main/cves/2026/110xxx/CVE-2026-110264.json">110264</a>)</td>
          <td>Verified (as of CISA&rsquo;s timestamps)</td>
      </tr>
      <tr>
          <td>Release date October 12, 2026; GitLab.com and Dedicated already patched; six detections</td>
          <td><a href="https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-4-2-released/">GitLab 19.4.2 patch release</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>CVE-2026-110264 range from 7.0; fix versions; release October 21, 2026; two detections</td>
          <td><a href="https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-5-1-released/">GitLab 19.5.1 patch release</a> and <a href="https://github.com/CVEProject/cvelistV5/blob/main/cves/2026/110xxx/CVE-2026-110264.json">CVE record</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>CVE-2026-89078 and CVE-2026-93577 authenticated, 9.9, ranges</td>
          <td><a href="https://github.com/CVEProject/cvelistV5/blob/main/cves/2026/89xxx/CVE-2026-89078.json">CVE-2026-89078</a>, <a href="https://github.com/CVEProject/cvelistV5/blob/main/cves/2026/93xxx/CVE-2026-93577.json">CVE-2026-93577</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Onigmo root cause, Ruby fix versions, who is affected, Regexp.timeout does not help</td>
          <td><a href="https://www.ruby-lang.org/en/news/2026/10/23/regexp-fixes-for-gitlab-cves/">Ruby advisory, 2026-10-23</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Unauthenticated path involves CI Lint</td>
          <td>Inferred from GitLab detection names</td>
          <td>Qualified (our interpretation)</td>
      </tr>
  </tbody>
</table>
]]></content:encoded></item><item><title>Magento CVE-2026-48356 (PolyShell): Patch and Hunt</title><link>https://firewallsync.com/posts/magento-cve-2026-48356-polyshell-patch-and-hunt/</link><guid>https://firewallsync.com/posts/magento-cve-2026-48356-polyshell-patch-and-hunt/</guid><pubDate>Thu, 29 Oct 2026 04:30:00 +0000</pubDate><dc:creator>Craig Leslie</dc:creator><category>Security Operations</category><description>CVE-2026-48356 is the PolyShell file-upload flaw in Adobe Commerce and Magento Open Source. CISA added it to the KEV catalog on October 27, 2026. Here are the fixed builds, why a store already on 2.4.9 may still need an update, and the checks that find an existing compromise.</description><enclosure url="https://firewallsync.com/posts/magento-cve-2026-48356-polyshell-patch-and-hunt/cover_hu14701130590101558514.jpg" type="image/jpeg" length="0"/><media:content url="https://firewallsync.com/posts/magento-cve-2026-48356-polyshell-patch-and-hunt/cover_hu14701130590101558514.jpg" medium="image" type="image/jpeg" width="1200" height="630"/><content:encoded><![CDATA[<p><img src="https://firewallsync.com/posts/magento-cve-2026-48356-polyshell-patch-and-hunt/cover_hu14701130590101558514.jpg" alt="Rows of empty grey metal shopping carts with orange handles, nested together against a white wall on a polished concrete floor" width="1200" height="630"></p><p>CVE-2026-48356 is the Magento file-upload flaw that Sansec calls <strong>PolyShell</strong>, and it is now on CISA&rsquo;s <a href="https://www.cisa.gov/known-exploited-vulnerabilities-catalog?field_cve=CVE-2026-48356">Known Exploited Vulnerabilities catalog</a> (added October 27, 2026; federal due date November 10). Adobe shipped the fix in <a href="https://helpx.adobe.com/security/products/magento/apsb26-73.html">APSB26-73</a> on July 14, 2026. If your store is not on a <code>2026-jul</code> build, update now. If it was exposed for any time since March, hunt as well. Attackers have used the flaw to plant webshells and to inject JavaScript loaders into CMS blocks, and an update removes neither.</p>
<h2 id="what-is-affected-and-what-fixes-it">What is affected and what fixes it</h2>
<p>The table comes from Adobe&rsquo;s <a href="https://github.com/CVEProject/cvelistV5/blob/main/cves/2026/48xxx/CVE-2026-48356.json">CVE record</a> and the APSB26-73 solution table, which agree on the fixed builds.</p>
<table>
  <thead>
      <tr>
          <th>Product</th>
          <th>Affected (up to and including)</th>
          <th>Fixed build</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Adobe Commerce</td>
          <td>2.4.9, 2.4.8-p5, 2.4.7-p10, 2.4.6-p15, 2.4.5-p17, 2.4.4-p18</td>
          <td>2.4.9-2026-jul, 2.4.8-2026-jul, 2.4.7-2026-jul, 2.4.6-2026-jul, 2.4.5-2026-jul, 2.4.4-2026-jul</td>
      </tr>
      <tr>
          <td>Magento Open Source</td>
          <td>2.4.9, 2.4.8-p5, 2.4.7-p10, 2.4.6-p15</td>
          <td>2.4.9-2026-jul, 2.4.8-2026-jul, 2.4.7-2026-jul, 2.4.6-2026-jul</td>
      </tr>
      <tr>
          <td>Adobe Commerce B2B</td>
          <td>1.5.3, 1.5.2-p5, 1.4.2-p10, 1.3.4-p17, 1.3.3-p18</td>
          <td>1.5.3-2026-jul, 1.5.2-2026-jul, 1.4.2-2026-jul, 1.3.4-2026-jul, 1.3.3-2026-jul</td>
      </tr>
      <tr>
          <td>Adobe Commerce Events</td>
          <td>1.20.0 and earlier</td>
          <td>1.21.0</td>
      </tr>
  </tbody>
</table>
<p>Two details matter here.</p>
<p><strong>2.4.9 is listed as affected.</strong> Sansec&rsquo;s <a href="https://sansec.io/research/magento-polyshell">PolyShell write-up</a> says Adobe released the fix in 2.4.9 on May 12, 2026, and backported it to the supported release lines through APSB26-73 on July 14. Adobe&rsquo;s CVE record, however, lists 2.4.9 among the affected versions and 2.4.9-2026-jul as unaffected. We have not diffed the two releases, so we can&rsquo;t say which is right. The safe reading is Adobe&rsquo;s: move to 2.4.9-2026-jul.</p>
<p><strong>Older Open Source lines are not listed at all.</strong> Adobe lists 2.4.4 and 2.4.5 <code>2026-jul</code> builds only for Adobe Commerce. For Magento Open Source 2.4.5 and older, the record names neither an affected nor a fixed version. Don&rsquo;t read that as safe: Sansec says every version up to 2.4.9-alpha2 is affected. If you run one of those lines, plan an upgrade and treat the server-side mitigations below as essential in the meantime.</p>
<p>Check what you run with <code>bin/magento --version</code> or <code>composer show magento/product-community-edition</code> (<code>magento/product-enterprise-edition</code> for Commerce), and compare the result with the table.</p>
<h2 id="how-polyshell-works">How PolyShell works</h2>
<p>Sansec describes the flaw in the REST API&rsquo;s handling of file uploads for cart item custom options, where a product option has type &ldquo;file&rdquo;. The most exposed routes are the unauthenticated guest-cart ones:</p>
<ul>
<li><code>POST /V1/guest-carts/:cartId/items</code></li>
<li><code>PUT /V1/guest-carts/:cartId/items/:itemId</code></li>
</ul>
<p>Uploaded files are written to <code>pub/media/custom_options/quote/</code>. Sansec says the GraphQL mutations use a different code path and are not vulnerable.</p>
<p>What an upload leads to depends on the server. Sansec lists code execution through an uploaded PHP file for Apache before 2.3.5 without <code>php_flag engine 0</code>, for stock nginx configs on 2.0.0 to 2.2.x, and for any nginx config that passes every <code>.php</code> request to PHP-FPM. Stored XSS is possible on versions before 2.3.5 and on custom web server configurations.</p>
<p>Adobe describes the same CVE differently. The CVE record says exploitation &ldquo;requires user interaction in that a victim must visit a maliciously crafted URL or interact with a compromised web page&rdquo; and scores it CVSS 3.1 <strong>9.3</strong> (<code>AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N</code>). The regional copy of the bulletin we read shows <strong>9.6</strong> with <code>A:L</code> and labels the impact &ldquo;Privilege escalation&rdquo;. We report both; neither changes the action. A KEV listing outranks the <code>UI:R</code> in the vector. Our <a href="/posts/cvss-vs-epss-vs-kev-which-signal-should-decide-what-you-patch-first/">CVSS vs EPSS vs KEV guide</a> explains why.</p>
<h2 id="what-attackers-have-done-with-it">What attackers have done with it</h2>
<p>Sansec reported a mass wave on March 30, 2026: <a href="https://sansec.io/research/polyshell-mass-attack-wave">471 stores compromised in one hour</a>, with a backdoor named <code>accesson.php</code> dropped across multiple directories and loaders injected into CMS pages and static blocks. That was months before Adobe&rsquo;s July backport.</p>
<p>On October 26, <a href="https://thehackernews.com/2026/10/hackers-infect-953-online-stores-with.html">The Hacker News reported</a> Sansec&rsquo;s findings on a longer campaign: 953 stores infected since July 2025 with a JavaScript loader stored in Magento&rsquo;s <code>cms_block</code> table. Per that report, Sansec attributes 471 of those infections to CVE-2026-48356, and about 102 more to file uploads through PolyShell or CVE-2025-54236 (SessionReaper). One store on 2.4.7-p10 with no missing core patches was compromised through a rogue administrator account. The report also describes webshells disguised as PNG files in <code>pub/media/custom_options/quote/</code>. The loader&rsquo;s final payload is not known.</p>
<p>These figures are Sansec&rsquo;s, as reported by The Hacker News. CISA&rsquo;s catalog entry does not say who is exploiting the flaw, and lists known ransomware use as &ldquo;Unknown&rdquo;.</p>
<h2 id="step-1-install-the-fixed-build">Step 1: Install the fixed build</h2>
<p>Update to the <code>2026-jul</code> build for your release line, then redeploy static content and clear caches as your normal release process requires. If you can&rsquo;t update this week, do steps 2 and 3 now anyway: they limit what a successful upload can do and tell you whether one has already happened.</p>
<p>Sansec suggests a WAF rule that blocks the vulnerable API calls. That buys time, but it is a mitigation, not a fix.</p>
<h2 id="step-2-make-sure-uploads-cant-be-served-or-executed">Step 2: Make sure uploads can&rsquo;t be served or executed</h2>
<p>Magento ships deny rules for this directory. Check that your live config still has them.</p>
<p><strong>nginx.</strong> The stock <a href="https://github.com/magento/magento2/blob/2.4-develop/nginx.conf.sample"><code>nginx.conf.sample</code></a> in the 2.4-develop branch denies the directory and only hands named entry points to PHP. These are excerpts from that file, not a complete config:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#66d9ef">location</span> <span style="color:#e6db74">/media/custom_options/</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">deny</span> <span style="color:#e6db74">all</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">location</span> ~ <span style="color:#e6db74">^/(index|get|static|errors/report|errors/404|errors/503|health_check)\.php$</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># ... fastcgi_pass to PHP-FPM ...
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Banned locations (only reached if the earlier PHP entry point regexes don&#39;t match)
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">location</span> ~<span style="color:#e6db74">*</span> <span style="color:#e6db74">(\.php</span>$|\.phtml$|\.htaccess$|\.htpasswd$|\.git<span style="color:#e6db74">)</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">deny</span> <span style="color:#e6db74">all</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>The risky pattern is a hand-written or hosting-panel config with a generic <code>location ~ \.php$ { fastcgi_pass ...; }</code> and no deny for <code>/media/custom_options/</code>. With that, a PHP file uploaded to the directory is executed. Sansec recommends a <code>deny all</code> location for <code>custom_options</code> placed before any <code>\.php$</code> block.</p>
<p><strong>Apache.</strong> The repository ships <code>pub/media/custom_options/.htaccess</code> containing <code>Require all denied</code> (Apache 2.4) or <code>deny from all</code> (older). Confirm it exists on disk and that <code>AllowOverride</code> lets Apache read it. Sansec also recommends <code>php_flag engine 0</code> there.</p>
<p>Neither rule stops the upload. Both stop the uploaded file from being fetched or run through the web server.</p>
<h2 id="step-3-hunt-for-an-existing-compromise">Step 3: Hunt for an existing compromise</h2>
<p>Run these from the Magento root, or adjust the paths. Sansec published the first checks; we added the database queries.</p>
<p><strong>Files in the upload directory.</strong> Customer uploads can be legitimate, but any script file there is a strong sign of compromise:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Everything uploaded through custom options, newest first</span>
</span></span><span style="display:flex;"><span>find pub/media/custom_options/ -type f ! -name <span style="color:#e6db74">&#39;.htaccess&#39;</span> -printf <span style="color:#e6db74">&#39;%TY-%Tm-%Td %TH:%TM  %s  %p\n&#39;</span> | sort -r | head -50
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Script extensions there are a red flag</span>
</span></span><span style="display:flex;"><span>find pub/media/custom_options/ -type f <span style="color:#ae81ff">\(</span> -iname <span style="color:#e6db74">&#39;*.php*&#39;</span> -o -iname <span style="color:#e6db74">&#39;*.phtml&#39;</span> -o -iname <span style="color:#e6db74">&#39;*.phar&#39;</span> <span style="color:#ae81ff">\)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># The backdoor name from the March wave, anywhere in the docroot tree</span>
</span></span><span style="display:flex;"><span>find /var/www -name <span style="color:#e6db74">&#39;accesson.php&#39;</span> -type f
</span></span></code></pre></div><p>The October report describes webshells disguised as <code>.png</code>. A PNG that starts with <code>&lt;?php</code> is not an image. Check with <code>file</code> or <code>head -c 64</code> on anything recent in that directory.</p>
<p><strong>Injected scripts in CMS content.</strong> The loader lives in the database, so file scans miss it. Run this against a replica or read-only connection (add your table prefix if you use one):</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sql" data-lang="sql"><span style="display:flex;"><span><span style="color:#66d9ef">SELECT</span> <span style="color:#e6db74">&#39;block&#39;</span> <span style="color:#66d9ef">AS</span> kind, block_id <span style="color:#66d9ef">AS</span> id, identifier, update_time
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">FROM</span> cms_block
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">WHERE</span> content <span style="color:#66d9ef">LIKE</span> <span style="color:#e6db74">&#39;%&lt;script%&#39;</span>
</span></span><span style="display:flex;"><span>   <span style="color:#66d9ef">OR</span> content <span style="color:#66d9ef">LIKE</span> <span style="color:#e6db74">&#39;%deepveindrilling%&#39;</span>
</span></span><span style="display:flex;"><span>   <span style="color:#66d9ef">OR</span> content <span style="color:#66d9ef">LIKE</span> <span style="color:#e6db74">&#39;%lanhd6549tdhse%&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">UNION</span> <span style="color:#66d9ef">ALL</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">SELECT</span> <span style="color:#e6db74">&#39;page&#39;</span>, page_id, identifier, update_time
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">FROM</span> cms_page
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">WHERE</span> content <span style="color:#66d9ef">LIKE</span> <span style="color:#e6db74">&#39;%&lt;script%&#39;</span>
</span></span><span style="display:flex;"><span>   <span style="color:#66d9ef">OR</span> content <span style="color:#66d9ef">LIKE</span> <span style="color:#e6db74">&#39;%deepveindrilling%&#39;</span>
</span></span><span style="display:flex;"><span>   <span style="color:#66d9ef">OR</span> content <span style="color:#66d9ef">LIKE</span> <span style="color:#e6db74">&#39;%lanhd6549tdhse%&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">ORDER</span> <span style="color:#66d9ef">BY</span> update_time <span style="color:#66d9ef">DESC</span>;
</span></span></code></pre></div><p>Column names come from Magento&rsquo;s <code>Cms</code> module schema; we checked the query&rsquo;s syntax against a small SQLite copy of those tables, not against a live MySQL store. Many stores have legitimate scripts in CMS blocks, so review hits by <code>update_time</code> and by where the script loads from. The October report lists these loader domains: <code>manulfie[.]click</code>, <code>neswnsssn[.]click</code>, <code>lanhd6549tdhse[.]top</code>, <code>additionalver[.]com</code> and <code>deepveindrilling[.]com</code>. Sansec&rsquo;s March write-up adds <code>jslibrary[.]net</code> and <code>canevaslab[.]com</code>. Add any you want to the <code>LIKE</code> list.</p>
<p><strong>Admin accounts you didn&rsquo;t create.</strong> One store in the October report was compromised through a rogue admin:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sql" data-lang="sql"><span style="display:flex;"><span><span style="color:#66d9ef">SELECT</span> user_id, username, email, created, logdate, is_active
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">FROM</span> admin_user
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">WHERE</span> created <span style="color:#f92672">&gt;=</span> <span style="color:#e6db74">&#39;2026-03-01&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">ORDER</span> <span style="color:#66d9ef">BY</span> created <span style="color:#66d9ef">DESC</span>;
</span></span></code></pre></div><p><strong>Web logs.</strong> Look for requests to the guest-cart item routes, which usually sit under <code>/rest/V1/</code> or <code>/rest/&lt;store_code&gt;/V1/</code>:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>grep -E <span style="color:#e6db74">&#39;&#34;(POST|PUT) /rest/([a-z0-9_]+/)?V1/guest-carts/[^/ ]+/items&#39;</span> /var/log/nginx/access.log* | head
</span></span></code></pre></div><p>Headless storefronts call these routes legitimately, so a hit is not proof. Line up timestamps with new files in <code>pub/media/custom_options/quote/</code> and with <code>cms_block</code> updates.</p>
<p>If you find a webshell or an injected loader, treat the store as compromised. Remove the artifacts, rotate admin, database and integration credentials, check for other persistence (cron, other PHP files, modified <code>app/etc/env.php</code>), and consider your payment-card obligations, since these loaders run in shoppers&rsquo; browsers. Our <a href="/posts/php2shell-cve-2026-109618-cve-2026-109619-patch-and-hunt/">PHP2Shell response guide</a> covers the server-side hunt for PHP webshells in more detail.</p>
<h2 id="hardening-after-the-patch">Hardening after the patch</h2>
<ul>
<li>Keep <code>pub/</code> as the document root and let PHP run only for Magento&rsquo;s named entry points. Sansec&rsquo;s RCE conditions are old releases or web server configs that execute PHP files in upload directories.</li>
<li>Turn off PHP execution in every writable media directory, not just this one. Our <a href="/posts/php-ini-security-hardening-production-settings/">php.ini hardening guide</a> covers related settings.</li>
<li>If you don&rsquo;t use file-type custom options, Sansec&rsquo;s WAF suggestion is cheap: block file uploads to the guest-cart item routes.</li>
<li>Monitor <code>cms_block</code> and <code>cms_page</code> for changes. A loader injected through the database survives code deploys.</li>
</ul>
<h2 id="limits-of-this-article">Limits of this article</h2>
<p>We did not reproduce the exploit or diff the patched releases. Affected and fixed versions come from Adobe&rsquo;s CVE record and bulletin. The upload mechanics, server conditions and campaign figures come from Sansec, the latter through The Hacker News. The <code>adobe.com/trust</code> copy of APSB26-73 could not be retrieved during research; we used Adobe&rsquo;s regional <code>helpx</code> copy, which shows &ldquo;Last updated on 14 July 2026&rdquo; and may not reflect later revisions. We ran the <code>find</code> and <code>grep</code> commands against a mock directory tree and sample log lines, and the SQL against SQLite, not against a production store.</p>
<h2 id="sources-and-verification">Sources and verification</h2>
<table>
  <thead>
      <tr>
          <th>Important claim</th>
          <th>Source</th>
          <th>Status</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>KEV addition 2026-10-27, due 2026-11-10, CWE-434, ransomware use &ldquo;Unknown&rdquo;</td>
          <td><a href="https://github.com/cisagov/kev-data/blob/main/known_exploited_vulnerabilities.json">CISA KEV catalog (kev-data)</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Affected and unaffected versions; CVSS 3.1 9.3 vector; &ldquo;requires user interaction&rdquo;</td>
          <td><a href="https://github.com/CVEProject/cvelistV5/blob/main/cves/2026/48xxx/CVE-2026-48356.json">CVE-2026-48356 record</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>CISA SSVC Exploitation &ldquo;active&rdquo;</td>
          <td>CISA ADP in the same CVE record</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Published July 14, 2026; priority 2; fixed builds; 9.6 score; &ldquo;not aware of any exploits&rdquo; at publication</td>
          <td><a href="https://helpx.adobe.com/security/products/magento/apsb26-73.html">Adobe APSB26-73</a> (regional helpx copy)</td>
          <td>Qualified: regional copy</td>
      </tr>
      <tr>
          <td>Guest-cart REST routes, upload path, RCE conditions, 2.4.9 fix and July backport</td>
          <td><a href="https://sansec.io/research/magento-polyshell">Sansec: PolyShell</a></td>
          <td>Qualified: researcher&rsquo;s account</td>
      </tr>
      <tr>
          <td>471 stores in one hour on March 30, 2026; accesson.php</td>
          <td><a href="https://sansec.io/research/polyshell-mass-attack-wave">Sansec: mass PolyShell wave</a></td>
          <td>Qualified: researcher&rsquo;s account</td>
      </tr>
      <tr>
          <td>953-store campaign; 471 via CVE-2026-48356; loader domains</td>
          <td><a href="https://thehackernews.com/2026/10/hackers-infect-953-online-stores-with.html">The Hacker News, Oct 26, 2026</a> citing Sansec</td>
          <td>Qualified: press report</td>
      </tr>
      <tr>
          <td>Stock nginx deny rules; custom_options .htaccess; cms_block / admin_user columns</td>
          <td><a href="https://github.com/magento/magento2/tree/2.4-develop">magento/magento2 2.4-develop</a></td>
          <td>Verified</td>
      </tr>
  </tbody>
</table>
]]></content:encoded></item><item><title>PHP2Shell CVE-2026-109618 and -109619: Patch, Then Hunt</title><link>https://firewallsync.com/posts/php2shell-cve-2026-109618-cve-2026-109619-patch-and-hunt/</link><guid>https://firewallsync.com/posts/php2shell-cve-2026-109618-cve-2026-109619-patch-and-hunt/</guid><pubDate>Tue, 27 Oct 2026 04:50:00 +0000</pubDate><dc:creator>John Marshall</dc:creator><category>Security Operations</category><description>Two PHP core flaws, CVE-2026-109618 and CVE-2026-109619, allow unauthenticated remote code execution against PHP that serves web requests. CISA added both to the KEV catalog on October 26 with a three-day deadline. Here are the fixed versions, why php -v can mislead you on distribution builds, the stopgaps PHP itself recommends, and what to hunt for.</description><enclosure url="https://firewallsync.com/posts/php2shell-cve-2026-109618-cve-2026-109619-patch-and-hunt/cover_hu12286854602341724834.jpg" type="image/jpeg" length="0"/><media:content url="https://firewallsync.com/posts/php2shell-cve-2026-109618-cve-2026-109619-patch-and-hunt/cover_hu12286854602341724834.jpg" medium="image" type="image/jpeg" width="1200" height="630"/><content:encoded><![CDATA[<p><img src="https://firewallsync.com/posts/php2shell-cve-2026-109618-cve-2026-109619-patch-and-hunt/cover_hu12286854602341724834.jpg" alt="Close-up of yellow barrier tape printed with the word ATTENTION, stretched in front of a blurred orange road sign and greenery" width="1200" height="630"></p><p>CVE-2026-109618 and CVE-2026-109619, which the security community has nicknamed &ldquo;PHP2Shell&rdquo;, are two memory-safety flaws in PHP&rsquo;s core that can give an unauthenticated attacker remote code execution on a server running PHP for the web. The fixes are PHP <strong>8.2.35, 8.3.36, 8.4.27 and 8.5.12</strong>. CISA added both CVEs to its Known Exploited Vulnerabilities (KEV) catalog on October 26, 2026, and gave federal agencies until <strong>October 29</strong> to act.</p>
<p>These are bugs in the PHP interpreter, so they apply regardless of your framework or CMS. If you run PHP behind a web server, update the PHP package today, restart every PHP worker, then look for signs that someone got in first. Everything below comes from the PHP project&rsquo;s advisory and CVE records and CISA&rsquo;s KEV entry unless we say otherwise.</p>
<h2 id="are-you-affected">Are you affected?</h2>
<p>The CVE records list PHP 8.2 before 8.2.35, 8.3 before 8.3.36, 8.4 before 8.4.27 and 8.5 before 8.5.12 as affected. PHP&rsquo;s advisory adds who is at risk: &ldquo;all PHP installations serving web requests, including PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed.&rdquo; It rates mod_php highest, &ldquo;with a demonstrated exploit where an unauthenticated request can trigger the attack before any application code runs.&rdquo;</p>
<table>
  <thead>
      <tr>
          <th>Branch</th>
          <th>Vulnerable upstream</th>
          <th>Fixed upstream</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>8.5</td>
          <td>below 8.5.12</td>
          <td>8.5.12</td>
      </tr>
      <tr>
          <td>8.4</td>
          <td>below 8.4.27</td>
          <td>8.4.27</td>
      </tr>
      <tr>
          <td>8.3</td>
          <td>below 8.3.36</td>
          <td>8.3.36</td>
      </tr>
      <tr>
          <td>8.2</td>
          <td>below 8.2.35</td>
          <td>8.2.35</td>
      </tr>
      <tr>
          <td>8.1 and older</td>
          <td>not listed in the CVE records; no upstream fix</td>
          <td>vendor backport, PHP&rsquo;s source backport branches for 7.4/8.0/8.1, or upgrade</td>
      </tr>
  </tbody>
</table>
<p>The CVE records only list 8.2 to 8.5. Do not read that as &ldquo;8.1 is safe&rdquo;: PHP says 8.1 and older &ldquo;no longer receive updates&rdquo; and published source backports for 7.4, 8.0 and 8.1 because of the severity.</p>
<h3 id="why-php--v-can-mislead-you">Why <code>php -v</code> can mislead you</h3>
<p>Most production PHP comes from a distribution or a container base image, and those vendors backport fixes without changing the upstream version number. PHP says Linux distributions and LTS vendors &ldquo;received the patches in advance&rdquo;.</p>
<p>We checked an Ubuntu 24.04 host. <code>php -v</code> reports 8.3.6, which is far below 8.3.36, yet the package changelog shows the fix:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-console" data-lang="console"><span style="display:flex;"><span>$ dpkg -l php8.3-cli | tail -1 | awk <span style="color:#e6db74">&#39;{print $2, $3}&#39;</span>
</span></span><span style="display:flex;"><span>php8.3-cli 8.3.6-0ubuntu0.24.04.13
</span></span><span style="display:flex;"><span>$ zcat /usr/share/doc/php8.3-cli/changelog.Debian.gz | head -4
</span></span><span style="display:flex;"><span>php8.3 (8.3.6-0ubuntu0.24.04.13) noble-security; urgency=medium
</span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span>  * SECURITY UPDATE: Remote RCE via state corruption issue
</span></span><span style="display:flex;"><span>    - debian/patches/CVE-2026-109618_109619.patch: Avoid state corruption via
</span></span></code></pre></div><p>So for a distribution build, search the package changelog for the CVE IDs. On Debian or Ubuntu, <code>zcat /usr/share/doc/php*-common/changelog.Debian.gz | grep -m1 CVE-2026-109618</code> works; on RPM-based systems the equivalent is <code>rpm -q --changelog &lt;php package&gt; | grep CVE-2026-109618</code> (illustrative; we did not run the RPM form). For official <code>php</code> Docker images and source builds, the upstream version is the one that counts.</p>
<p>Also check the binary that actually serves traffic. The CLI, <code>php-fpm</code> and <code>libapache2-mod-php</code> can come from different packages and be updated at different times.</p>
<h3 id="a-version-check-for-upstream-builds">A version check for upstream builds</h3>
<p>This script compares upstream version strings against the fixed releases. We ran it with PHP 8.3 CLI (<code>php php2shell-check.php 8.2.34 8.4.27 8.1.31</code>). It cannot see distribution backports, so a &ldquo;VULNERABLE&rdquo; result on a distro build means &ldquo;check the changelog&rdquo;, not &ldquo;definitely exposed&rdquo;.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;?</span><span style="color:#a6e22e">php</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// Compares upstream PHP versions with the fixed releases for
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">// CVE-2026-109618 / CVE-2026-109619. Does not detect vendor backports.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>$fixed <span style="color:#f92672">=</span> [<span style="color:#e6db74">&#39;8.2&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;8.2.35&#39;</span>, <span style="color:#e6db74">&#39;8.3&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;8.3.36&#39;</span>, <span style="color:#e6db74">&#39;8.4&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;8.4.27&#39;</span>, <span style="color:#e6db74">&#39;8.5&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;8.5.12&#39;</span>];
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">status</span>(<span style="color:#a6e22e">string</span> $v, <span style="color:#66d9ef">array</span> $fixed)<span style="color:#f92672">:</span> <span style="color:#a6e22e">string</span> {
</span></span><span style="display:flex;"><span>    $branch <span style="color:#f92672">=</span> <span style="color:#a6e22e">implode</span>(<span style="color:#e6db74">&#39;.&#39;</span>, <span style="color:#a6e22e">array_slice</span>(<span style="color:#a6e22e">explode</span>(<span style="color:#e6db74">&#39;.&#39;</span>, $v), <span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">2</span>));
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> (<span style="color:#f92672">!</span><span style="color:#a6e22e">isset</span>($fixed[$branch])) {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">version_compare</span>($v, <span style="color:#e6db74">&#39;8.2&#39;</span>, <span style="color:#e6db74">&#39;&lt;&#39;</span>)
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">?</span> <span style="color:#e6db74">&#39;END OF LIFE: no upstream fix; needs vendor backport or upgrade&#39;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;UNKNOWN branch: check php.net&#39;</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">version_compare</span>($v, $fixed[$branch], <span style="color:#e6db74">&#39;&gt;=&#39;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">?</span> <span style="color:#e6db74">&#34;fixed upstream (&gt;= </span><span style="color:#e6db74">{</span>$fixed[$branch]<span style="color:#e6db74">}</span><span style="color:#e6db74">)&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">:</span> <span style="color:#e6db74">&#34;VULNERABLE upstream (&lt; </span><span style="color:#e6db74">{</span>$fixed[$branch]<span style="color:#e6db74">}</span><span style="color:#e6db74">) unless your vendor backported the fix&#34;</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">foreach</span> (<span style="color:#a6e22e">array_slice</span>($argv, <span style="color:#ae81ff">1</span>) <span style="color:#f92672">?:</span> [<span style="color:#66d9ef">PHP_VERSION</span>] <span style="color:#66d9ef">as</span> $v) {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">printf</span>(<span style="color:#e6db74">&#34;%-10s %s</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">&#34;</span>, $v, <span style="color:#a6e22e">status</span>($v, $fixed));
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-console" data-lang="console"><span style="display:flex;"><span>$ php php2shell-check.php 8.2.34 8.4.27 8.1.31
</span></span><span style="display:flex;"><span>8.2.34     VULNERABLE upstream (&lt; 8.2.35) unless your vendor backported the fix
</span></span><span style="display:flex;"><span>8.4.27     fixed upstream (&gt;= 8.4.27)
</span></span><span style="display:flex;"><span>8.1.31     END OF LIFE: no upstream fix; needs vendor backport or upgrade
</span></span></code></pre></div><h2 id="what-the-two-flaws-do">What the two flaws do</h2>
<p>Both bugs leave PHP&rsquo;s internal request state inconsistent and let later code trust it.</p>
<ul>
<li><strong>CVE-2026-109618, &ldquo;RCE via OOM corruption&rdquo;.</strong> The CVE record says PHP &ldquo;uses longjmp() for out-of-memory (OOM) errors to exit the current context&rdquo;. Some code paths &ldquo;leave request memory in an uninitialized state before performing an allocation&rdquo;, and &ldquo;the subsequent request cleanup procedure may read or branch on this memory.&rdquo; An attacker who can push a request into an out-of-memory failure at the right moment can trigger it.</li>
<li><strong>CVE-2026-109619, &ldquo;RCE via stale global state&rdquo;.</strong> Global state that &ldquo;temporarily points into request memory&rdquo; may not be reset, so it &ldquo;may refer to request memory even after it has been freed.&rdquo; PHP&rsquo;s advisory explains the consequence: &ldquo;A later request handled by the same worker may use that stale state before normal initialization resets it.&rdquo;</li>
</ul>
<p>Both carry a CVSS v4.0 base score of 9.2 (<code>AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H</code>): network-reachable, no privileges, no user interaction, but high attack complexity with attack requirements present. If you want to decode the vector, see our guide to <a href="/posts/how-to-read-a-cvss-v4-0-vector-string-metric-by-metric-with-real-cve-records/">reading a CVSS v4.0 vector string</a>. The fix shipped in all four branches as one change, described in PHP&rsquo;s NEWS file as &ldquo;Avoid state corruption via bailout&rdquo;.</p>
<p>Credits in the CVE records name Wiz, Ryan at Calif.io and OpenAI as reporters or finders.</p>
<h2 id="exploitation-status">Exploitation status</h2>
<p>The public picture is mixed, so here is what each source says:</p>
<table>
  <thead>
      <tr>
          <th>Date</th>
          <th>Source</th>
          <th>What it says</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Oct 17</td>
          <td>Amazon Threat Intelligence, as reported by Infosecurity Magazine</td>
          <td>An exploitation attempt against its MadPot honeypot &ldquo;dating October 17&rdquo;, four days before disclosure</td>
      </tr>
      <tr>
          <td>Oct 21</td>
          <td>PHP advisory</td>
          <td>A demonstrated exploit against mod_php; patches released</td>
      </tr>
      <tr>
          <td>Oct 21</td>
          <td>oss-security disclosure</td>
          <td>&ldquo;a complete FPM exploit has not been demonstrated&rdquo;, though source analysis suggests FPM is susceptible</td>
      </tr>
      <tr>
          <td>Oct 21</td>
          <td>VulnCheck</td>
          <td>Scanning with a <code>php2shell-scan/109618</code> user agent, and one attempt that &ldquo;tried to (unsuccessfully) drop a webshell via a server-side session file&rdquo;</td>
      </tr>
      <tr>
          <td>Oct 23</td>
          <td>Security Affairs, citing honeypot operators</td>
          <td>&ldquo;no successful remote code execution has been confirmed in real-world attacks&rdquo;</td>
      </tr>
      <tr>
          <td>Oct 23</td>
          <td>FBI IC3 public service announcement</td>
          <td>Updates &ldquo;should be applied immediately&rdquo;</td>
      </tr>
      <tr>
          <td>Oct 26</td>
          <td>CISA KEV</td>
          <td>Both CVEs added; due October 29; forensic triage required for federal agencies</td>
      </tr>
  </tbody>
</table>
<p>CISA&rsquo;s Vulnrichment SSVC entry in the CVE records, dated October 21, still says <code>Exploitation: none</code>. That predates the KEV listing. For how these signals usually relate, see <a href="/posts/cvss-vs-epss-vs-kev-which-signal-should-decide-what-you-patch-first/">CVSS vs EPSS vs KEV</a>.</p>
<p>Our reading: mass scanning started within hours, working exploits exist, and CISA has listed both as exploited. Whether specific attacks succeeded against production servers is not yet established in public sources. That uncertainty is a reason to hunt after patching, not a reason to wait.</p>
<h2 id="what-to-do-now">What to do now</h2>
<ol>
<li><strong>Inventory.</strong> Find every PHP runtime that serves HTTP: VMs, containers, base images, appliances with embedded PHP, and managed hosting. Container images need a rebuild and redeploy; patching the host does nothing for them.</li>
<li><strong>Update.</strong> Move to 8.2.35, 8.3.36, 8.4.27, 8.5.12 or your vendor&rsquo;s patched package. For 8.1 and older, use a vendor backport or upgrade. PHP 8.2 itself reaches end of life on December 31, 2026, according to PHP&rsquo;s release notes, so plan that upgrade too.</li>
<li><strong>Restart every worker.</strong> CVE-2026-109619 is about state that persists across requests in the same worker. Restart PHP-FPM pools, Apache (for mod_php) and any long-running PHP servers after the package update.</li>
<li><strong>Prioritise internet-facing mod_php</strong>, then FPM behind public web servers, then internal applications.</li>
</ol>
<h3 id="if-you-cannot-update-today">If you cannot update today</h3>
<p>PHP lists stopgaps and is explicit that &ldquo;only an update is a complete solution&rdquo; and these &ldquo;do not make an installation safe&rdquo;:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ini" data-lang="ini"><span style="display:flex;"><span><span style="color:#75715e">; php.ini or FPM pool config, applied before request parsing, then restart workers.</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">; Illustrative: check each value against your application&#39;s needs.</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">; CVE-2026-109618 (OOM corruption)</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">; In an FPM pool use php_admin_value[memory_limit] = -1 so applications can&#39;t override it.</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">memory_limit</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">-1</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">; 8M if the app takes no uploads, 32M if it needs them; keep upload_max_filesize below it</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">post_max_size</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">8M</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">upload_max_filesize</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">2M</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">; CVE-2026-109619 (stale global state)</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">session.upload_progress.enabled</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">0</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">; PHP 8.5 only:</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">; fatal_error_backtraces = 0</span>
</span></span></code></pre></div><p>The reasoning behind each, from the advisory:</p>
<ul>
<li><code>memory_limit=-1</code> &ldquo;removes the controllable PHP memory limit failure, but an underlying allocation failure can still reach the vulnerable path.&rdquo; With no PHP memory limit, a container or cgroup memory limit becomes your availability boundary. PHP warns: &ldquo;Do not substitute <code>RLIMIT_AS</code> or <code>RLIMIT_DATA</code>, as these can cause the vulnerable allocation failure.&rdquo;</li>
<li>Low <code>post_max_size</code>, plus limits at the web server or proxy on decoded request size, field count, multipart part count, header count and nesting depth. These &ldquo;must also cover requests without a usable <code>Content-Length</code>.&rdquo;</li>
<li><code>session.upload_progress.enabled=0</code> &ldquo;blocks the confirmed session paths but not other variants&rdquo;. Set it in <code>php.ini</code>, the FPM pool or server config; PHP says &ldquo;Do not rely on <code>ini_set()</code> or FPM <code>.user.ini</code>.&rdquo;</li>
<li>Hiding errors does not help: &ldquo;Hiding diagnostics with <code>error_reporting</code>, <code>display_errors</code> or <code>@</code> does not help.&rdquo;</li>
</ul>
<p><code>php_admin_value</code> matters here because, per the PHP-FPM documentation, &ldquo;Settings defined with php_admin_value and php_admin_flag cannot be overridden with ini_set.&rdquo;</p>
<h2 id="what-to-hunt-for-after-patching">What to hunt for after patching</h2>
<p>Patching removes the bug, not an attacker who already used it. Preserve web server and PHP logs before you rotate or rebuild anything. The indicators below come from VulnCheck&rsquo;s published honeypot observations. They describe scanners and one attempt; real attackers can change every one of them.</p>
<ul>
<li><strong>User agents:</strong> <code>php2shell-scan/109618</code>, <code>php2shell-verify/1.0</code>, <code>Mozilla/5.0 (php2shell-poc)</code>.</li>
<li><strong>Requests:</strong> multipart POSTs to <code>/index.php</code> that upload two files named <code>a</code> and <code>b</code> through the upload-progress path; follow-up <code>GET</code> requests using <code>php://filter</code> to read a session file.</li>
<li><strong>Session files containing PHP code.</strong> The attempt VulnCheck saw tried to plant a webshell through a session file, with a payload that prints <code>PWNED::</code>. A legitimate PHP session file contains serialized data, never <code>&lt;?php</code>.</li>
</ul>
<p>Two checks you can run on a Linux host. We tested both against sample files; adjust paths to your log format and to the <code>session.save_path</code> of the pool that serves traffic (<code>php -i</code> shows the CLI&rsquo;s value, not necessarily FPM&rsquo;s):</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Web logs: known scanner user agents and php://filter reads</span>
</span></span><span style="display:flex;"><span>grep -hE <span style="color:#e6db74">&#39;php2shell|php://filter&#39;</span> /var/log/nginx/access.log* /var/log/apache2/access.log* 2&gt;/dev/null
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Session files that contain PHP code or the test marker</span>
</span></span><span style="display:flex;"><span>grep -lE <span style="color:#e6db74">&#39;&lt;\?php|PWNED::&#39;</span> /var/lib/php/sessions/sess_* 2&gt;/dev/null
</span></span></code></pre></div><p>Then do the usual post-compromise checks for a web server: new or changed <code>.php</code> files under the document root since October 17, unexpected child processes of the PHP worker or web server user (shells, <code>curl</code>, <code>wget</code>), and outbound connections from web hosts. Our guide to <a href="/posts/logging-for-incidents-not-for-dashboards/">logging for incidents</a> covers which of these you will wish you had recorded.</p>
<p>Federal agencies have to follow CISA&rsquo;s forensic triage requirements for this KEV entry. If you want to borrow that process, our explainer on <a href="/posts/cisa-bod-26-04-explained-kev-deadlines-forensic-triage-and-what-private-teams-can-borrow/">CISA BOD 26-04</a> covers it.</p>
<h2 id="limits-of-this-article">Limits of this article</h2>
<p>We have not read the full GitHub security advisories, which PHP says contain the technical details; they were not reachable from our research environment. Exploitation reporting comes from vendors and press summaries we cite, not from our own telemetry. The hunting indicators come from one vendor&rsquo;s honeypots and will not catch a modified attack. Exposure counts published by vendors differ widely, so we have not repeated them.</p>
<h2 id="sources-and-verification">Sources and verification</h2>
<table>
  <thead>
      <tr>
          <th>Important claim</th>
          <th>Source</th>
          <th>Status</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Affected ranges 8.2 &lt; 8.2.35, 8.3 &lt; 8.3.36, 8.4 &lt; 8.4.27, 8.5 &lt; 8.5.12; mechanisms; CVSS v4.0 9.2 vector; CWEs; credits</td>
          <td><a href="https://github.com/CVEProject/cvelistV5/blob/main/cves/2026/109xxx/CVE-2026-109618.json">CVE-2026-109618</a> and <a href="https://github.com/CVEProject/cvelistV5/blob/main/cves/2026/109xxx/CVE-2026-109619.json">CVE-2026-109619</a> records (PHP CNA)</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>SAPIs at risk, mod_php highest, fixed releases, 8.1-and-older guidance, source backports, all stopgaps and their caveats</td>
          <td><a href="https://www.php.net/archive/2026.php">PHP security advisory, Oct 21, 2026</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Fix shipped in 8.2.35, 8.3.36, 8.4.27, 8.5.12 as &ldquo;Avoid state corruption via bailout&rdquo;</td>
          <td>PHP NEWS files for <a href="https://github.com/php/php-src/blob/php-8.4.27/NEWS">8.4.27</a> and the other tags</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Full FPM exploit not demonstrated at disclosure</td>
          <td><a href="https://openwall.com/lists/oss-security/2026/10/21/6">oss-security, Oct 21, 2026</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>KEV addition Oct 26, due Oct 29, forensic triage flag</td>
          <td><a href="https://github.com/cisagov/kev-data">CISA KEV catalog data</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Ubuntu 24.04 package 8.3.6-0ubuntu0.24.04.13 includes the fix</td>
          <td>Package changelog on an Ubuntu 24.04 host, inspected October 27, 2026</td>
          <td>Verified (one package)</td>
      </tr>
      <tr>
          <td>php_admin_value cannot be overridden with ini_set</td>
          <td><a href="https://www.php.net/manual/en/install.fpm.configuration.php">PHP-FPM configuration docs</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Exploitation attempt from Oct 17</td>
          <td>Amazon, as reported by <a href="https://infosecurity-magazine.com/news/php2shell-exploitation-attempt">Infosecurity Magazine</a></td>
          <td>Qualified (secondary report)</td>
      </tr>
      <tr>
          <td>Scanner user agents, request pattern, session-file webshell attempt</td>
          <td><a href="https://www.vulncheck.com/blog/php2shell-vulnerabilities">VulnCheck, Oct 21, 2026</a></td>
          <td>Qualified (one vendor&rsquo;s honeypots)</td>
      </tr>
      <tr>
          <td>No confirmed successful RCE as of Oct 23</td>
          <td><a href="https://securityaffairs.com/?p=201538">Security Affairs</a></td>
          <td>Qualified (secondary report)</td>
      </tr>
      <tr>
          <td>FBI: apply updates immediately</td>
          <td><a href="https://www.ic3.gov/PSA/2026/PSA261023">FBI IC3 PSA I-102326-PSA</a></td>
          <td>Verified</td>
      </tr>
  </tbody>
</table>
]]></content:encoded></item><item><title>PAN-OS CVE-2026-0322: Patch the Management Interface RCE</title><link>https://firewallsync.com/posts/pan-os-cve-2026-0322-management-interface-rce-patch-and-hunt/</link><guid>https://firewallsync.com/posts/pan-os-cve-2026-0322-management-interface-rce-patch-and-hunt/</guid><pubDate>Mon, 26 Oct 2026 04:40:00 +0000</pubDate><dc:creator>John Marshall</dc:creator><category>Security Operations</category><description>CVE-2026-0322 lets an authenticated attacker who can reach the PAN-OS management interface run code as root on PA-Series and VM-Series firewalls and Panorama. Palo Alto Networks has seen very limited exploitation, there is no workaround, and CISA gave federal agencies three days. Here are the fixed releases, a version checker built from the CVE record, and what to review after you patch.</description><enclosure url="https://firewallsync.com/posts/pan-os-cve-2026-0322-management-interface-rce-patch-and-hunt/cover_hu12832646850512031119.jpg" type="image/jpeg" length="0"/><media:content url="https://firewallsync.com/posts/pan-os-cve-2026-0322-management-interface-rce-patch-and-hunt/cover_hu12832646850512031119.jpg" medium="image" type="image/jpeg" width="1200" height="630"/><content:encoded><![CDATA[<p><img src="https://firewallsync.com/posts/pan-os-cve-2026-0322-management-interface-rce-patch-and-hunt/cover_hu12832646850512031119.jpg" alt="A brass padlock hanging from the latch of a galvanised chain-link gate, with gravel on the ground behind it" width="1200" height="630"></p><p>CVE-2026-0322 is a code injection vulnerability in the management interface of Palo Alto Networks PAN-OS. An attacker who is authenticated and can reach that interface over the network can execute arbitrary code with root privileges on the firewall. It affects PA-Series and VM-Series firewalls and Panorama, there is no workaround, and Palo Alto Networks says it has observed &ldquo;very limited exploitation&rdquo;. CISA added it to the Known Exploited Vulnerabilities (KEV) catalog on October 14, 2026, and gave federal agencies until October 17 to act.</p>
<p>If you run PAN-OS, find your exact version, upgrade to the matching fixed release below, and use the upgrade window to check who can reach the management interface at all. Everything in this article comes from Palo Alto Networks&rsquo; CVE record and CISA&rsquo;s KEV entry unless we say otherwise.</p>
<h2 id="are-you-affected">Are you affected?</h2>
<p>You are affected if you run PAN-OS on a PA-Series or VM-Series firewall, or Panorama (virtual or M-Series), and your version is below the fixed release for its maintenance range. Palo Alto Networks says &ldquo;no special configuration is required to be affected&rdquo;. Cloud NGFW and Prisma Access are not impacted.</p>
<table>
  <thead>
      <tr>
          <th>Branch</th>
          <th>If you run</th>
          <th>Upgrade to</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>12.2</td>
          <td>12.2.0 through 12.2.3</td>
          <td>12.2.4 or later</td>
      </tr>
      <tr>
          <td>12.1</td>
          <td>12.1.8 through 12.1.10-h*</td>
          <td>12.1.10-h2 or later</td>
      </tr>
      <tr>
          <td></td>
          <td>12.1.5 through 12.1.7-h*</td>
          <td>12.1.7-h8, or 12.1.10-h2 or later</td>
      </tr>
      <tr>
          <td></td>
          <td>12.1.2 through 12.1.4-h*</td>
          <td>12.1.4-h12, or 12.1.10-h2 or later</td>
      </tr>
      <tr>
          <td>11.2</td>
          <td>11.2.14 through 11.2.15</td>
          <td>11.2.16 or later</td>
      </tr>
      <tr>
          <td></td>
          <td>11.2.11 through 11.2.13-h*</td>
          <td>11.2.13-h3, or 11.2.16 or later</td>
      </tr>
      <tr>
          <td></td>
          <td>11.2.8 through 11.2.10-h*</td>
          <td>11.2.10-h15, or 11.2.16 or later</td>
      </tr>
      <tr>
          <td></td>
          <td>11.2.5 through 11.2.7-h*</td>
          <td>11.2.7-h21, or 11.2.16 or later</td>
      </tr>
      <tr>
          <td></td>
          <td>11.2.0 through 11.2.4-h*</td>
          <td>11.2.4-h22, or 11.2.16 or later</td>
      </tr>
      <tr>
          <td>11.1</td>
          <td>11.1.14 through 11.1.16-h*</td>
          <td>11.1.16-h3 or later</td>
      </tr>
      <tr>
          <td></td>
          <td>11.1.11 through 11.1.13-h*</td>
          <td>11.1.13-h15, or 11.1.16-h3 or later</td>
      </tr>
      <tr>
          <td></td>
          <td>11.1.8 through 11.1.10-h*</td>
          <td>11.1.10-h35, or 11.1.16-h3 or later</td>
      </tr>
      <tr>
          <td></td>
          <td>11.1.7 through 11.1.7-h*</td>
          <td>11.1.7-h11, or 11.1.16-h3 or later</td>
      </tr>
      <tr>
          <td></td>
          <td>11.1.5 through 11.1.6-h*</td>
          <td>11.1.6-h39, or 11.1.16-h3 or later</td>
      </tr>
      <tr>
          <td></td>
          <td>11.1.0 through 11.1.4-h*</td>
          <td>11.1.4-h37, or 11.1.16-h3 or later</td>
      </tr>
      <tr>
          <td>10.2</td>
          <td>10.2.17 through 10.2.18-h*</td>
          <td>10.2.18-h12 or later</td>
      </tr>
      <tr>
          <td></td>
          <td>10.2.14 through 10.2.16-h*</td>
          <td>10.2.16-h11, or 10.2.18-h12 or later</td>
      </tr>
      <tr>
          <td></td>
          <td>10.2.11 through 10.2.13-h*</td>
          <td>10.2.13-h26, or 10.2.18-h12 or later</td>
      </tr>
      <tr>
          <td></td>
          <td>10.2.8 through 10.2.10-h*</td>
          <td>10.2.10-h41, or 10.2.18-h12 or later</td>
      </tr>
      <tr>
          <td></td>
          <td>10.2.0 through 10.2.7-h*</td>
          <td>10.2.7-h38, or 10.2.18-h12 or later</td>
      </tr>
  </tbody>
</table>
<p>This is the solutions table from the CVE record as published on October 14, 2026. Two details are easy to miss. First, a hotfix only fixes its own maintenance release: 11.1.4-h37 is fixed, but 11.1.5 is not, because 11.1.5 sits in the next row with its own fix (11.1.6-h39). Second, the record&rsquo;s affected range for 12.1 starts at 12.1.0, while the solutions table starts at 12.1.2; if you are on 12.1.0 or 12.1.1, move to 12.1.10-h2. Branches older than 10.2 are not listed; check the <a href="https://security.paloaltonetworks.com/CVE-2026-0322">Palo Alto Networks advisory</a> for their status.</p>
<h3 id="check-a-list-of-versions">Check a list of versions</h3>
<p>With a fleet, a lookup beats reading the table by eye. This Python 3 script encodes the table above. We checked it against the record: its 20 in-line fixes are the same set as the 20 <code>changes</code> entries in the record&rsquo;s <code>affected</code> data, and its per-branch upper bounds match the record&rsquo;s <code>lessThan</code> values. We ran it on Python 3 with the versions shown.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#75715e">#!/usr/bin/env python3</span>
</span></span><span style="display:flex;"><span><span style="color:#e6db74">&#34;&#34;&#34;Check PAN-OS versions against the CVE-2026-0322 fix table (CVE record, 2026-10-14).
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">Usage: python3 check_0322.py 11.1.6-h20 10.2.18-h12 ...&#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> re<span style="color:#f92672">,</span> sys
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># (first version in range, last minor in range, in-line fix, newest fix on the branch)</span>
</span></span><span style="display:flex;"><span>ROWS <span style="color:#f92672">=</span> [
</span></span><span style="display:flex;"><span>    (<span style="color:#e6db74">&#34;12.2.0&#34;</span>, <span style="color:#e6db74">&#34;12.2.3&#34;</span>, <span style="color:#e6db74">&#34;12.2.4&#34;</span>, <span style="color:#e6db74">&#34;12.2.4&#34;</span>),
</span></span><span style="display:flex;"><span>    (<span style="color:#e6db74">&#34;12.1.8&#34;</span>, <span style="color:#e6db74">&#34;12.1.10&#34;</span>, <span style="color:#e6db74">&#34;12.1.10-h2&#34;</span>, <span style="color:#e6db74">&#34;12.1.10-h2&#34;</span>),
</span></span><span style="display:flex;"><span>    (<span style="color:#e6db74">&#34;12.1.5&#34;</span>, <span style="color:#e6db74">&#34;12.1.7&#34;</span>, <span style="color:#e6db74">&#34;12.1.7-h8&#34;</span>, <span style="color:#e6db74">&#34;12.1.10-h2&#34;</span>),
</span></span><span style="display:flex;"><span>    (<span style="color:#e6db74">&#34;12.1.2&#34;</span>, <span style="color:#e6db74">&#34;12.1.4&#34;</span>, <span style="color:#e6db74">&#34;12.1.4-h12&#34;</span>, <span style="color:#e6db74">&#34;12.1.10-h2&#34;</span>),
</span></span><span style="display:flex;"><span>    (<span style="color:#e6db74">&#34;11.2.14&#34;</span>, <span style="color:#e6db74">&#34;11.2.15&#34;</span>, <span style="color:#e6db74">&#34;11.2.16&#34;</span>, <span style="color:#e6db74">&#34;11.2.16&#34;</span>),
</span></span><span style="display:flex;"><span>    (<span style="color:#e6db74">&#34;11.2.11&#34;</span>, <span style="color:#e6db74">&#34;11.2.13&#34;</span>, <span style="color:#e6db74">&#34;11.2.13-h3&#34;</span>, <span style="color:#e6db74">&#34;11.2.16&#34;</span>),
</span></span><span style="display:flex;"><span>    (<span style="color:#e6db74">&#34;11.2.8&#34;</span>, <span style="color:#e6db74">&#34;11.2.10&#34;</span>, <span style="color:#e6db74">&#34;11.2.10-h15&#34;</span>, <span style="color:#e6db74">&#34;11.2.16&#34;</span>),
</span></span><span style="display:flex;"><span>    (<span style="color:#e6db74">&#34;11.2.5&#34;</span>, <span style="color:#e6db74">&#34;11.2.7&#34;</span>, <span style="color:#e6db74">&#34;11.2.7-h21&#34;</span>, <span style="color:#e6db74">&#34;11.2.16&#34;</span>),
</span></span><span style="display:flex;"><span>    (<span style="color:#e6db74">&#34;11.2.0&#34;</span>, <span style="color:#e6db74">&#34;11.2.4&#34;</span>, <span style="color:#e6db74">&#34;11.2.4-h22&#34;</span>, <span style="color:#e6db74">&#34;11.2.16&#34;</span>),
</span></span><span style="display:flex;"><span>    (<span style="color:#e6db74">&#34;11.1.14&#34;</span>, <span style="color:#e6db74">&#34;11.1.16&#34;</span>, <span style="color:#e6db74">&#34;11.1.16-h3&#34;</span>, <span style="color:#e6db74">&#34;11.1.16-h3&#34;</span>),
</span></span><span style="display:flex;"><span>    (<span style="color:#e6db74">&#34;11.1.11&#34;</span>, <span style="color:#e6db74">&#34;11.1.13&#34;</span>, <span style="color:#e6db74">&#34;11.1.13-h15&#34;</span>, <span style="color:#e6db74">&#34;11.1.16-h3&#34;</span>),
</span></span><span style="display:flex;"><span>    (<span style="color:#e6db74">&#34;11.1.8&#34;</span>, <span style="color:#e6db74">&#34;11.1.10&#34;</span>, <span style="color:#e6db74">&#34;11.1.10-h35&#34;</span>, <span style="color:#e6db74">&#34;11.1.16-h3&#34;</span>),
</span></span><span style="display:flex;"><span>    (<span style="color:#e6db74">&#34;11.1.7&#34;</span>, <span style="color:#e6db74">&#34;11.1.7&#34;</span>, <span style="color:#e6db74">&#34;11.1.7-h11&#34;</span>, <span style="color:#e6db74">&#34;11.1.16-h3&#34;</span>),
</span></span><span style="display:flex;"><span>    (<span style="color:#e6db74">&#34;11.1.5&#34;</span>, <span style="color:#e6db74">&#34;11.1.6&#34;</span>, <span style="color:#e6db74">&#34;11.1.6-h39&#34;</span>, <span style="color:#e6db74">&#34;11.1.16-h3&#34;</span>),
</span></span><span style="display:flex;"><span>    (<span style="color:#e6db74">&#34;11.1.0&#34;</span>, <span style="color:#e6db74">&#34;11.1.4&#34;</span>, <span style="color:#e6db74">&#34;11.1.4-h37&#34;</span>, <span style="color:#e6db74">&#34;11.1.16-h3&#34;</span>),
</span></span><span style="display:flex;"><span>    (<span style="color:#e6db74">&#34;10.2.17&#34;</span>, <span style="color:#e6db74">&#34;10.2.18&#34;</span>, <span style="color:#e6db74">&#34;10.2.18-h12&#34;</span>, <span style="color:#e6db74">&#34;10.2.18-h12&#34;</span>),
</span></span><span style="display:flex;"><span>    (<span style="color:#e6db74">&#34;10.2.14&#34;</span>, <span style="color:#e6db74">&#34;10.2.16&#34;</span>, <span style="color:#e6db74">&#34;10.2.16-h11&#34;</span>, <span style="color:#e6db74">&#34;10.2.18-h12&#34;</span>),
</span></span><span style="display:flex;"><span>    (<span style="color:#e6db74">&#34;10.2.11&#34;</span>, <span style="color:#e6db74">&#34;10.2.13&#34;</span>, <span style="color:#e6db74">&#34;10.2.13-h26&#34;</span>, <span style="color:#e6db74">&#34;10.2.18-h12&#34;</span>),
</span></span><span style="display:flex;"><span>    (<span style="color:#e6db74">&#34;10.2.8&#34;</span>, <span style="color:#e6db74">&#34;10.2.10&#34;</span>, <span style="color:#e6db74">&#34;10.2.10-h41&#34;</span>, <span style="color:#e6db74">&#34;10.2.18-h12&#34;</span>),
</span></span><span style="display:flex;"><span>    (<span style="color:#e6db74">&#34;10.2.0&#34;</span>, <span style="color:#e6db74">&#34;10.2.7&#34;</span>, <span style="color:#e6db74">&#34;10.2.7-h38&#34;</span>, <span style="color:#e6db74">&#34;10.2.18-h12&#34;</span>),
</span></span><span style="display:flex;"><span>]
</span></span><span style="display:flex;"><span><span style="color:#75715e"># &#34;lessThan&#34; bound of each affected range in the record&#39;s affected[] data</span>
</span></span><span style="display:flex;"><span>LESS_THAN <span style="color:#f92672">=</span> {<span style="color:#e6db74">&#34;12.2&#34;</span>: <span style="color:#e6db74">&#34;12.2.4&#34;</span>, <span style="color:#e6db74">&#34;12.1&#34;</span>: <span style="color:#e6db74">&#34;12.1.10-h2&#34;</span>, <span style="color:#e6db74">&#34;11.2&#34;</span>: <span style="color:#e6db74">&#34;11.2.16&#34;</span>,
</span></span><span style="display:flex;"><span>             <span style="color:#e6db74">&#34;11.1&#34;</span>: <span style="color:#e6db74">&#34;11.1.16-h3&#34;</span>, <span style="color:#e6db74">&#34;10.2&#34;</span>: <span style="color:#e6db74">&#34;10.2.18-h12&#34;</span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">key</span>(v):
</span></span><span style="display:flex;"><span>    m <span style="color:#f92672">=</span> re<span style="color:#f92672">.</span>fullmatch(<span style="color:#e6db74">r</span><span style="color:#e6db74">&#34;(\d+)\.(\d+)\.(\d+)(?:-h(\d+))?&#34;</span>, v<span style="color:#f92672">.</span>strip())
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> <span style="color:#f92672">not</span> m:
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">raise</span> <span style="color:#a6e22e">ValueError</span>(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;unrecognised version: </span><span style="color:#e6db74">{</span>v<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span>    a, b, c, h <span style="color:#f92672">=</span> m<span style="color:#f92672">.</span>groups()
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> (int(a), int(b), int(c), int(h <span style="color:#f92672">or</span> <span style="color:#ae81ff">0</span>))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">check</span>(v):
</span></span><span style="display:flex;"><span>    k <span style="color:#f92672">=</span> key(v)
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">for</span> start, last, fix, newest <span style="color:#f92672">in</span> ROWS:
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> key(start) <span style="color:#f92672">&lt;=</span> k <span style="color:#f92672">and</span> k[:<span style="color:#ae81ff">3</span>] <span style="color:#f92672">&lt;=</span> key(last)[:<span style="color:#ae81ff">3</span>]:
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">if</span> k <span style="color:#f92672">&gt;=</span> key(fix):
</span></span><span style="display:flex;"><span>                <span style="color:#66d9ef">return</span> <span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;</span><span style="color:#e6db74">{</span>v<span style="color:#e6db74">}</span><span style="color:#e6db74">: fixed (in-line fix </span><span style="color:#e6db74">{</span>fix<span style="color:#e6db74">}</span><span style="color:#e6db74">)&#34;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">return</span> <span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;</span><span style="color:#e6db74">{</span>v<span style="color:#e6db74">}</span><span style="color:#e6db74">: AFFECTED -&gt; upgrade to </span><span style="color:#e6db74">{</span>fix<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span> <span style="color:#f92672">+</span> (<span style="color:#e6db74">&#34;&#34;</span> <span style="color:#66d9ef">if</span> fix <span style="color:#f92672">==</span> newest <span style="color:#66d9ef">else</span> <span style="color:#e6db74">f</span><span style="color:#e6db74">&#34; or </span><span style="color:#e6db74">{</span>newest<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span>    branch <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;.&#34;</span><span style="color:#f92672">.</span>join(map(str, k[:<span style="color:#ae81ff">2</span>]))
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> branch <span style="color:#f92672">in</span> LESS_THAN:
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> k <span style="color:#f92672">&gt;=</span> key(LESS_THAN[branch]):
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">return</span> <span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;</span><span style="color:#e6db74">{</span>v<span style="color:#e6db74">}</span><span style="color:#e6db74">: not affected (at or above </span><span style="color:#e6db74">{</span>LESS_THAN[branch]<span style="color:#e6db74">}</span><span style="color:#e6db74">)&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> <span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;</span><span style="color:#e6db74">{</span>v<span style="color:#e6db74">}</span><span style="color:#e6db74">: AFFECTED per the record, no row in the fix table -&gt; </span><span style="color:#e6db74">{</span>LESS_THAN[branch]<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;</span><span style="color:#e6db74">{</span>v<span style="color:#e6db74">}</span><span style="color:#e6db74">: branch </span><span style="color:#e6db74">{</span>branch<span style="color:#e6db74">}</span><span style="color:#e6db74"> not listed in the CVE record (check the advisory)&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> v <span style="color:#f92672">in</span> sys<span style="color:#f92672">.</span>argv[<span style="color:#ae81ff">1</span>:]:
</span></span><span style="display:flex;"><span>    print(check(v))
</span></span></code></pre></div><p>Sample output from our run:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>$ python3 check_0322.py 11.1.6-h20 11.2.15 10.2.18-h12 12.1.1 10.1.14
</span></span><span style="display:flex;"><span>11.1.6-h20: AFFECTED -&gt; upgrade to 11.1.6-h39 or 11.1.16-h3
</span></span><span style="display:flex;"><span>11.2.15: AFFECTED -&gt; upgrade to 11.2.16
</span></span><span style="display:flex;"><span>10.2.18-h12: fixed (in-line fix 10.2.18-h12)
</span></span><span style="display:flex;"><span>12.1.1: AFFECTED per the record, no row in the fix table -&gt; 12.1.10-h2
</span></span><span style="display:flex;"><span>10.1.14: branch 10.1 not listed in the CVE record (check the advisory)
</span></span></code></pre></div><p>To get the input, read the running software version from each firewall and Panorama: on the CLI, <code>show system info</code> is the usual place to look (illustrative; we did not run it against a device). Feed those values to the script, and remember to include Panorama itself.</p>
<h2 id="what-the-vulnerability-does">What the vulnerability does</h2>
<p>The record classifies the flaw as CWE-94, improper control of generation of code (&ldquo;code injection&rdquo;). Its title is &ldquo;Authenticated Remote Code Execution (RCE) in the Management Interface&rdquo;, and the impact is code execution &ldquo;with root privileges on the firewall&rdquo;. Palo Alto Networks found it internally; the record credits an internal reporter and gives no technical detail of the vulnerable code path.</p>
<p>Palo Alto Networks publishes two CVSS v4.0 scores for two deployment scenarios:</p>
<table>
  <thead>
      <tr>
          <th>Scenario</th>
          <th>Score</th>
          <th>Attack vector</th>
          <th>Privileges required</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Management interface reachable from external IP addresses on the internet</td>
          <td>8.6 High</td>
          <td>Network</td>
          <td>High</td>
      </tr>
      <tr>
          <td>Access restricted to a jump box that is the only system allowed to reach the interface</td>
          <td>8.5 High</td>
          <td>Adjacent</td>
          <td>High</td>
      </tr>
  </tbody>
</table>
<p>Both vectors carry <code>E:A</code> (attacked), <code>AU:N</code> (not automatable) and <code>U:Red</code>. If you want to read the vector strings metric by metric, our <a href="/posts/how-to-read-a-cvss-v4-0-vector-string-metric-by-metric-with-real-cve-records/">guide to CVSS v4.0 vectors</a> walks through each field.</p>
<p>The small gap between the two scores understates the operational difference. Restricting the interface to a jump box does not fix the bug, but it shrinks the set of places an attacker can attempt it from to one host you control and monitor.</p>
<h3 id="authenticated-does-not-mean-safe-to-wait">&ldquo;Authenticated&rdquo; does not mean &ldquo;safe to wait&rdquo;</h3>
<p>The CVSS vectors rate privileges required as High, so an attacker needs a valid management login. That is a real barrier, but not a high one when the interface is reachable. Speaking to CSO Online, IDC analyst Yih Khai Wong pointed to &ldquo;weak management-access hygiene&rdquo;: administrator credentials stolen through phishing or reuse, internet-reachable management interfaces, or an earlier compromise that left the attacker with valid logins.</p>
<p>PAN-OS management and edge services have a history here. CISA&rsquo;s KEV catalog lists 16 Palo Alto Networks entries, including two management-interface flaws added on the same day in November 2024: CVE-2024-0012, an authentication bypass, and CVE-2024-9474, an OS command injection. In 2026 alone, CVE-2026-0322 is the third PAN-OS entry, after CVE-2026-0300 (an unauthenticated buffer overflow in the User-ID Authentication Portal, added May 6) and CVE-2026-0257 (a GlobalProtect authentication bypass, added May 29, which CISA marks as known to be used in ransomware campaigns). None of those records links them to CVE-2026-0322. The point is simpler: if your management access depends on nobody having a valid password, it is weaker than it looks.</p>
<h2 id="exploitation-status">Exploitation status</h2>
<p>What the primary records say:</p>
<ul>
<li><strong>Palo Alto Networks:</strong> &ldquo;Very limited exploitation has been observed targeting the Palo Alto Networks management interface.&rdquo; The record&rsquo;s initial publication time is October 14, 2026, 16:00 UTC.</li>
<li><strong>CISA KEV:</strong> added October 14, 2026; due date October 17; known ransomware campaign use &ldquo;Unknown&rdquo;; forensic triage flag &ldquo;Yes&rdquo;. The required action points to <a href="/posts/cisa-bod-26-04-explained-kev-deadlines-forensic-triage-and-what-private-teams-can-borrow/">BOD 26-04</a> and its forensic triage requirements.</li>
<li><strong>CISA SSVC (in the CVE record):</strong> Exploitation &ldquo;active&rdquo;, Automatable &ldquo;no&rdquo;, Technical Impact &ldquo;total&rdquo;. Our <a href="/posts/cisa-vulnrichment-how-to-read-ssvc-values-in-a-cve-record-and-turn-them-into-a-patch-decision/">explainer on Vulnrichment SSVC values</a> covers how to turn those into a patch decision.</li>
</ul>
<p>What is reported but we could not confirm at the source: BleepingComputer reported that Palo Alto Networks shared three IP addresses linked to the activity, <code>66.42.72[.]14</code>, <code>208.83.239[.]114</code> and <code>149.248.47[.]234</code>. The Hacker News lists the same three as &ldquo;assessed to be linked to the exploit attempts&rdquo;. We did not read them on the advisory page itself, so treat them as reported indicators, and check the advisory for the current list. Neither outlet describes what attackers did after exploitation, and Palo Alto Networks has not said who is behind it or when it began.</p>
<h2 id="what-to-do-now">What to do now</h2>
<ol>
<li><strong>Upgrade</strong> to the fixed release for your maintenance range, firewalls and Panorama both. There is no workaround.</li>
<li><strong>Preserve evidence before you upgrade</strong> if the management interface was reachable from anywhere you do not fully control. Export system, configuration and authentication logs, and take a tech support file, so the upgrade does not become the only record of the device&rsquo;s state.</li>
<li><strong>Restrict who can reach the management interface.</strong> Palo Alto Networks&rsquo; administrative access guidance says: &ldquo;Do not enable access to your management interface from the internet or from other untrusted zones&rdquo;, &ldquo;Isolate the management interface on a dedicated management VLAN&rdquo; and &ldquo;Restrict the IP addresses that are permitted to access the management interface&rdquo;. On the firewall this is the Permitted IP Addresses list on the management interface (Device &gt; Setup &gt; Interfaces &gt; Management in the PAN-OS admin guide). An empty list allows access from any IP address.</li>
<li><strong>Check dataplane interfaces too.</strong> If you manage the firewall through an interface management profile on a data port, restrict it the same way. The guidance is explicit that a profile allowing HTTP, HTTPS, Telnet or SSH must not be attached to an interface where a GlobalProtect portal or gateway is configured, because that exposes management to the internet.</li>
<li><strong>Tighten administrator accounts.</strong> One account per person, the default <code>admin</code> password changed, and MFA through external authentication for administrators with change privileges. Rotate credentials for any administrator who logged in from outside the management network recently.</li>
<li><strong>Use the Threat IDs only as a stopgap.</strong> Threat IDs 510046 and 510047 (Applications and Threats content 9159-10287 and later) offer what Palo Alto Networks calls limited coverage. They only work if management traffic is routed through a dataplane port with a management profile, its certificate is replaced, inbound management traffic is decrypted, and threat prevention is applied to it.</li>
</ol>
<h2 id="what-to-review-after-patching">What to review after patching</h2>
<p>Upgrading closes the hole; it does not tell you whether someone used it. Root code execution on a firewall means an attacker could have changed configuration, added accounts, or used the device as a foothold. Scope the review from the earliest date you think the interface was exposed, and at least from early October 2026.</p>
<table>
  <thead>
      <tr>
          <th>Question</th>
          <th>Where to look</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Who logged in to management, from where?</td>
          <td>System and authentication logs: administrator logins from source addresses outside your management network or jump hosts, and logins at unusual times</td>
      </tr>
      <tr>
          <td>Did anyone connect from the reported addresses?</td>
          <td>Firewall traffic logs and any upstream logs for <code>66.42.72.14</code>, <code>208.83.239.114</code> and <code>149.248.47.234</code></td>
      </tr>
      <tr>
          <td>Were admin accounts added or changed?</td>
          <td>Configuration logs and the current administrator list against your expected set</td>
      </tr>
      <tr>
          <td>What changed in the configuration?</td>
          <td>Configuration logs and commit history: new NAT or security rules, new management profiles, changed authentication profiles, new certificates</td>
      </tr>
      <tr>
          <td>Is the device talking somewhere new?</td>
          <td>Outbound connections from the management address and the firewall itself to destinations it does not normally reach</td>
      </tr>
  </tbody>
</table>
<p>As illustrative starting points in the PAN-OS CLI, <code>show admins all</code> lists administrators and their sessions, and <code>show log system</code> and <code>show log config</code> read the system and configuration logs. Check the CLI reference for your release for filters and exact syntax; we did not run these against a device.</p>
<p>If you find activity you cannot explain, treat the device as compromised rather than just patched: rebuild from a known-good configuration, rotate every credential and key the firewall holds (administrator passwords, API keys, certificates, VPN and directory service secrets), and involve Palo Alto Networks support. Our <a href="/posts/logging-for-incidents-not-for-dashboards/">incident logging guide</a> covers what to keep while you do.</p>
<h2 id="limits-of-this-article">Limits of this article</h2>
<p>We did not test the vulnerability or run the CLI commands on a PAN-OS device. The fixed-release table and checker come from the CVE record as published on October 14, 2026; Palo Alto Networks can update the advisory, so check it before you finalise a change. The three IP addresses come from press reports, not from our reading of the advisory. Palo Alto Networks has not published technical details of the flaw or of the exploitation it observed.</p>
<h2 id="sources-and-verification">Sources and verification</h2>
<table>
  <thead>
      <tr>
          <th>Important claim</th>
          <th>Source</th>
          <th>Status</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Authenticated RCE as root via the management interface; PA-Series, VM-Series and Panorama affected; Cloud NGFW and Prisma Access not</td>
          <td><a href="https://github.com/CVEProject/cvelistV5/blob/main/cves/2026/0xxx/CVE-2026-0322.json">CVE-2026-0322 record (Palo Alto Networks CNA)</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Fixed-release table, no workaround, Threat IDs 510046/510047 and their conditions, no special configuration needed</td>
          <td>Same record, solutions, workarounds and configurations</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>CWE-94; CVSS v4.0 8.6 and 8.5 with the vectors shown; internal discovery</td>
          <td>Same record</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>&ldquo;Very limited exploitation has been observed&rdquo;</td>
          <td>Same record, exploits</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>KEV added 2026-10-14, due 2026-10-17, ransomware Unknown, forensic triage Yes</td>
          <td><a href="https://github.com/cisagov/kev-data">CISA KEV catalog data</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>SSVC active / no / total</td>
          <td>CISA ADP container in the CVE record</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>16 Palo Alto Networks KEV entries; CVE-2024-0012, CVE-2024-9474, CVE-2026-0300, CVE-2026-0257 details</td>
          <td>CISA KEV catalog data; CVE records for CVE-2026-0300 and CVE-2026-0257</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Three IP addresses linked to the activity</td>
          <td><a href="https://bleepingcomputer.com/news/security/palo-alto-networks-warns-of-pan-os-rce-flaw-exploited-in-attacks">BleepingComputer</a>, <a href="https://thehackernews.com/2026/10/palo-alto-networks-patches-pan-os.html">The Hacker News</a></td>
          <td>Qualified: press reports</td>
      </tr>
      <tr>
          <td>Analyst comment on credential hygiene</td>
          <td><a href="https://www.csoonline.com/article/4235787/attackers-exploit-palo-alto-pan-os-flaw-for-root-access-as-cisa-orders-three-day-fix.html">CSO Online</a></td>
          <td>Verified (attributed)</td>
      </tr>
      <tr>
          <td>Management access guidance quoted</td>
          <td><a href="https://docs.paloaltonetworks.com/pan-os/9-1/pan-os-admin/getting-started/best-practices-for-securing-administrative-access">PAN-OS admin guide: securing administrative access</a>; <a href="https://docs.paloaltonetworks.com/ngfw/administration/set-up-firewalls/device-setup/configure-the-management-interface-settings">management interface settings</a></td>
          <td>Verified; the first page is from the 9.1 guide</td>
      </tr>
      <tr>
          <td>Version checker output</td>
          <td>Our run of the script above</td>
          <td>Verified (computed)</td>
      </tr>
  </tbody>
</table>
]]></content:encoded></item><item><title>Kubernetes Audit Policy: What to Log, at What Level</title><link>https://firewallsync.com/posts/kubernetes-audit-policy-what-to-log-and-at-what-level/</link><guid>https://firewallsync.com/posts/kubernetes-audit-policy-what-to-log-and-at-what-level/</guid><pubDate>Sun, 25 Oct 2026 04:45:00 +0000</pubDate><dc:creator>Craig Leslie</dc:creator><category>Cloud Security</category><description>A Kubernetes audit policy decides which API requests kube-apiserver records and how much of each it keeps. The first matching rule wins, so one misplaced rule can write Secret values into your logs. Here is a six-rule policy we ran against kube-apiserver v1.34.1, what each rule captured, and the jq queries that turn the log into answers.</description><enclosure url="https://firewallsync.com/posts/kubernetes-audit-policy-what-to-log-and-at-what-level/cover_hu8208247904918711124.jpg" type="image/jpeg" length="0"/><media:content url="https://firewallsync.com/posts/kubernetes-audit-policy-what-to-log-and-at-what-level/cover_hu8208247904918711124.jpg" medium="image" type="image/jpeg" width="1200" height="630"/><content:encoded><![CDATA[<p><img src="https://firewallsync.com/posts/kubernetes-audit-policy-what-to-log-and-at-what-level/cover_hu8208247904918711124.jpg" alt="A worn, yellowed ledger lying open on green baize, its ruled pages covered in faded handwriting, with a white quill pen resting across them" width="1200" height="630"></p><p>A Kubernetes audit policy is the file that tells kube-apiserver which API requests to record and how much of each to keep. Without one, upstream kube-apiserver records nothing. A good policy logs everything at <code>Metadata</code> at minimum, keeps request bodies for changes that alter access, and never logs the contents of Secrets. Rule order is what makes that work: the first matching rule wins, and a broad rule placed too high will quietly write Secret values into your logs. We demonstrate that below.</p>
<p>This guide gives a six-rule policy we ran against kube-apiserver v1.34.1, shows what each rule captured, and ends with queries you can run against the log during an incident.</p>
<h2 id="how-kube-apiserver-evaluates-a-policy">How kube-apiserver evaluates a policy</h2>
<p>Every request produces audit events at one or more <strong>stages</strong>:</p>
<table>
  <thead>
      <tr>
          <th>Stage</th>
          <th>When</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>RequestReceived</code></td>
          <td>As soon as the audit handler receives the request</td>
      </tr>
      <tr>
          <td><code>ResponseStarted</code></td>
          <td>After response headers are sent, for long-running requests such as watch</td>
      </tr>
      <tr>
          <td><code>ResponseComplete</code></td>
          <td>When the response body is finished</td>
      </tr>
      <tr>
          <td><code>Panic</code></td>
          <td>When a panic occurred</td>
      </tr>
  </tbody>
</table>
<p>The policy is a list of rules. kube-apiserver compares each event with the rules <strong>in order</strong>, and the first rule that matches sets the event&rsquo;s <strong>level</strong>:</p>
<table>
  <thead>
      <tr>
          <th>Level</th>
          <th>What gets recorded</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>None</code></td>
          <td>Nothing</td>
      </tr>
      <tr>
          <td><code>Metadata</code></td>
          <td>User, groups, source IPs, user agent, verb, resource, namespace, name, response status, timestamps, annotations</td>
      </tr>
      <tr>
          <td><code>Request</code></td>
          <td>Metadata plus the request body</td>
      </tr>
      <tr>
          <td><code>RequestResponse</code></td>
          <td>Metadata plus request and response bodies</td>
      </tr>
  </tbody>
</table>
<p><code>Request</code> and <code>RequestResponse</code> don&rsquo;t apply to non-resource URLs such as <code>/healthz</code>. A rule can match on <code>users</code>, <code>userGroups</code>, <code>verbs</code>, <code>resources</code> (group, resource, subresource and <code>resourceNames</code>), <code>namespaces</code> and <code>nonResourceURLs</code>. A rule with no match fields matches everything, which is what you want for the last rule and exactly what you don&rsquo;t want near the top.</p>
<p>The policy file is passed with <code>--audit-policy-file</code>. If the flag is omitted, no events are logged, and a policy with no rules is rejected.</p>
<h2 id="a-policy-that-answers-incident-questions">A policy that answers incident questions</h2>
<p>The policy below is built around the questions you get asked during an incident: who read this Secret, who exec&rsquo;d into that Pod, who granted this binding, and was it allowed. It is a starting point, not a complete production policy; see the limits at the end.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">apiVersion</span>: <span style="color:#ae81ff">audit.k8s.io/v1</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">kind</span>: <span style="color:#ae81ff">Policy</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">omitStages</span>:
</span></span><span style="display:flex;"><span>  - <span style="color:#e6db74">&#34;RequestReceived&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">rules</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#75715e"># 1. Drop health and version probes.</span>
</span></span><span style="display:flex;"><span>  - <span style="color:#f92672">level</span>: <span style="color:#ae81ff">None</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">nonResourceURLs</span>: [<span style="color:#e6db74">&#34;/healthz*&#34;</span>, <span style="color:#e6db74">&#34;/livez*&#34;</span>, <span style="color:#e6db74">&#34;/readyz*&#34;</span>, <span style="color:#e6db74">&#34;/version&#34;</span>]
</span></span><span style="display:flex;"><span>  <span style="color:#75715e"># 2. Sensitive payloads: who touched them, never the contents.</span>
</span></span><span style="display:flex;"><span>  - <span style="color:#f92672">level</span>: <span style="color:#ae81ff">Metadata</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">resources</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#f92672">group</span>: <span style="color:#e6db74">&#34;&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">resources</span>: [<span style="color:#e6db74">&#34;secrets&#34;</span>, <span style="color:#e6db74">&#34;configmaps&#34;</span>, <span style="color:#e6db74">&#34;serviceaccounts/token&#34;</span>]
</span></span><span style="display:flex;"><span>      - <span style="color:#f92672">group</span>: <span style="color:#e6db74">&#34;authentication.k8s.io&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">resources</span>: [<span style="color:#e6db74">&#34;tokenreviews&#34;</span>]
</span></span><span style="display:flex;"><span>  <span style="color:#75715e"># 3. Interactive access into running workloads.</span>
</span></span><span style="display:flex;"><span>  - <span style="color:#f92672">level</span>: <span style="color:#ae81ff">Metadata</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">resources</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#f92672">group</span>: <span style="color:#e6db74">&#34;&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">resources</span>: [<span style="color:#e6db74">&#34;pods/exec&#34;</span>, <span style="color:#e6db74">&#34;pods/attach&#34;</span>, <span style="color:#e6db74">&#34;pods/portforward&#34;</span>, <span style="color:#e6db74">&#34;pods/proxy&#34;</span>, <span style="color:#e6db74">&#34;nodes/proxy&#34;</span>]
</span></span><span style="display:flex;"><span>  <span style="color:#75715e"># 4. Changes to who can do what, and to admission control.</span>
</span></span><span style="display:flex;"><span>  - <span style="color:#f92672">level</span>: <span style="color:#ae81ff">RequestResponse</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">verbs</span>: [<span style="color:#e6db74">&#34;create&#34;</span>, <span style="color:#e6db74">&#34;update&#34;</span>, <span style="color:#e6db74">&#34;patch&#34;</span>, <span style="color:#e6db74">&#34;delete&#34;</span>, <span style="color:#e6db74">&#34;deletecollection&#34;</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">resources</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#f92672">group</span>: <span style="color:#e6db74">&#34;rbac.authorization.k8s.io&#34;</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#f92672">group</span>: <span style="color:#e6db74">&#34;admissionregistration.k8s.io&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e"># 5. Other writes: keep the submitted object.</span>
</span></span><span style="display:flex;"><span>  - <span style="color:#f92672">level</span>: <span style="color:#ae81ff">Request</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">verbs</span>: [<span style="color:#e6db74">&#34;create&#34;</span>, <span style="color:#e6db74">&#34;update&#34;</span>, <span style="color:#e6db74">&#34;patch&#34;</span>, <span style="color:#e6db74">&#34;delete&#34;</span>, <span style="color:#e6db74">&#34;deletecollection&#34;</span>]
</span></span><span style="display:flex;"><span>  <span style="color:#75715e"># 6. Everything else (reads, watches, non-resource URLs).</span>
</span></span><span style="display:flex;"><span>  - <span style="color:#f92672">level</span>: <span style="color:#ae81ff">Metadata</span>
</span></span></code></pre></div><p>Why each rule is where it is:</p>
<table>
  <thead>
      <tr>
          <th>Rule</th>
          <th>Level</th>
          <th>Reason</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>1. Probes</td>
          <td>None</td>
          <td>High volume, no investigative value. Leaving out <code>RequestReceived</code> globally also halves events for most requests, since <code>ResponseComplete</code> carries the same metadata plus the result.</td>
      </tr>
      <tr>
          <td>2. Secrets, ConfigMaps, TokenRequest, TokenReview</td>
          <td>Metadata</td>
          <td>Their bodies hold credentials and tokens. The upstream GCE policy treats them the same way, noting they &ldquo;can contain sensitive &amp; binary data&rdquo;. It must come before any rule that logs bodies.</td>
      </tr>
      <tr>
          <td>3. exec, attach, port-forward, proxy</td>
          <td>Metadata</td>
          <td>These are how people get inside workloads. The body adds nothing, but you always want the event.</td>
      </tr>
      <tr>
          <td>4. RBAC and admission configuration</td>
          <td>RequestResponse</td>
          <td>You need the exact subjects, <code>roleRef</code>, rules and webhook targets that were written, and the response confirms what was stored. Listing a group with no <code>resources</code> matches every resource in it.</td>
      </tr>
      <tr>
          <td>5. Other writes</td>
          <td>Request</td>
          <td>Keeps the object that was submitted, such as a Pod spec with a privileged container or a hostPath mount.</td>
      </tr>
      <tr>
          <td>6. Catch-all</td>
          <td>Metadata</td>
          <td>Every read and watch is still attributable to someone.</td>
      </tr>
  </tbody>
</table>
<p>Pod Security Admission and our <a href="/posts/kubernetes-rbac-audit-11-permissions-that-escalate-access/">RBAC permission audit</a> tell you what <em>could</em> happen. The audit log is how you find out what did.</p>
<h2 id="what-it-recorded">What it recorded</h2>
<p>We ran the policy on kube-apiserver v1.34.1 (the envtest build from the kubernetes-sigs/controller-tools releases) with etcd and RBAC authorization, then made requests as a <code>system:masters</code> user and as an unprivileged user <code>alice</code>. There were no nodes, so no Pod actually ran. Results:</p>
<table>
  <thead>
      <tr>
          <th>Action</th>
          <th>Level logged</th>
          <th>What the event held</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>kubectl create secret generic db-creds --from-literal=password=...</code></td>
          <td>Metadata</td>
          <td>User, namespace, name, <code>201</code>. No request body; the value appeared nowhere in the log.</td>
      </tr>
      <tr>
          <td><code>kubectl create rolebinding alice-view --clusterrole=view --user=alice</code></td>
          <td>RequestResponse</td>
          <td>Full <code>requestObject</code> and <code>responseObject</code>, including the subject <code>alice</code> and <code>roleRef</code> <code>view</code>.</td>
      </tr>
      <tr>
          <td><code>alice</code> lists Secrets in <code>kube-system</code></td>
          <td>Metadata</td>
          <td><code>403</code>, annotation <code>authorization.k8s.io/decision: forbid</code></td>
      </tr>
      <tr>
          <td>Admin runs <code>kubectl --as alice get pods</code></td>
          <td>Metadata</td>
          <td><code>user.username: admin</code> and <code>impersonatedUser.username: alice</code> in the same event</td>
      </tr>
      <tr>
          <td><code>kubectl create deployment web --image=nginx:1.27</code></td>
          <td>Request</td>
          <td><code>requestObject</code> with the Deployment spec, no response body</td>
      </tr>
      <tr>
          <td><code>kubectl create token ci-bot</code></td>
          <td>Metadata</td>
          <td>Resource <code>serviceaccounts</code>, subresource <code>token</code>, name <code>ci-bot</code>, no token in the log</td>
      </tr>
      <tr>
          <td><code>kubectl exec shell -- cat /etc/shadow</code></td>
          <td>Metadata</td>
          <td><code>requestURI</code> of <code>/api/v1/namespaces/default/pods/shell/exec?command=cat&amp;command=%2Fetc%2Fshadow&amp;...</code></td>
      </tr>
  </tbody>
</table>
<p>Two details from the test are worth building detections around:</p>
<ul>
<li><strong>Exec shows up under more than one verb.</strong> That single <code>kubectl exec</code> produced events with verb <code>get</code> and verb <code>create</code> for the <code>exec</code> subresource. Filter on <code>objectRef.subresource == &quot;exec&quot;</code>, not on the verb.</li>
<li><strong>Impersonation keeps both identities.</strong> The authenticated user is in <code>user</code> and the identity they acted as is in <code>impersonatedUser</code>. If you only alert on <code>user.username</code>, impersonated actions look like they came from the admin&rsquo;s own account.</li>
</ul>
<p>Also keep in mind what the API reference warns about two fields: <code>userAgent</code> is reported by the client &ldquo;and must not be trusted&rdquo;, and in <code>sourceIPs</code> all entries except the last &ldquo;can be arbitrarily set by the client&rdquo;.</p>
<h2 id="the-rule-order-mistake-that-leaks-secrets">The rule-order mistake that leaks Secrets</h2>
<p>We then moved rule 5 (Request for all writes) above rule 2, restarted kube-apiserver with that policy, and created a Secret with the value <code>S3cretValue-456</code>. The audit log now contained:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>&#34;data&#34;:{&#34;key&#34;:&#34;UzNjcmV0VmFsdWUtNDU2&#34;}
</span></span></code></pre></div><p>That is the base64 encoding of <code>S3cretValue-456</code>. The broad write rule matched first, logged the request body at <code>Request</code> level, and the Metadata rule for Secrets was never reached. With the correct order, the equivalent test (a Secret holding <code>S3cretValue-123</code>) left no trace of either the plain or the encoded value in the log.</p>
<p>This is the most common way an audit log becomes a credential store. Your audit pipeline usually has wider read access than the cluster&rsquo;s Secrets do, so treat a body-logging rule above your Secrets rule as a bug. Check it in code review with a simple test: create a dummy Secret in a test cluster and search the log for its encoded value.</p>
<p>If you already store <a href="/posts/kubernetes-secrets-encryption-at-rest-what-it-protects/">Secrets encrypted at rest</a>, remember that encryption protects etcd, not the audit log. And a <a href="/posts/kubernetes-service-account-tokens-bound-vs-legacy-secrets/">Secret-based service account token</a> leaked this way never expires.</p>
<h2 id="backends-and-volume">Backends and volume</h2>
<p>There are two backends: a log file and a webhook.</p>
<ul>
<li><strong>Log backend:</strong> <code>--audit-log-path</code> sets the file (<code>-</code> means stdout). Rotation is controlled by <code>--audit-log-maxage</code> (days), <code>--audit-log-maxbackup</code> (files) and <code>--audit-log-maxsize</code> (megabytes). Batching is off by default for the log backend.</li>
<li><strong>Webhook backend:</strong> <code>--audit-webhook-config-file</code> points at a kubeconfig-format file for the remote endpoint. Batching is on by default, with a maximum of 400 events per batch and a 30-second maximum wait.</li>
<li><strong>Truncation</strong> of oversized events is off by default for both backends and has to be enabled explicitly.</li>
</ul>
<p>The Kubernetes docs also note that auditing increases API server memory use, because some context is kept for each request, and that the increase depends on the policy. <code>RequestResponse</code> on a busy resource is where cost grows: the GCE reference policy, for instance, logs <code>get</code>, <code>list</code> and <code>watch</code> at <code>Request</code> level rather than <code>RequestResponse</code> because &ldquo;Get responses can be large&rdquo;.</p>
<p>Ship the log off the control plane. An attacker with control-plane access can edit a local file, and an <a href="/posts/logging-for-incidents-not-for-dashboards/">incident log is only useful</a> if it survives the incident.</p>
<h2 id="managed-kubernetes">Managed Kubernetes</h2>
<p>On EKS, AKS and similar services the provider runs kube-apiserver, so you generally choose whether audit events are exported, not what the policy contains. Check your provider&rsquo;s documentation for what its policy logs.</p>
<ul>
<li><strong>Amazon EKS:</strong> control plane logs are not sent to CloudWatch Logs by default. Enable the <code>audit</code> log type per cluster, for example with <code>aws eks update-cluster-config --logging</code>. The audit stream is named <code>kube-apiserver-audit-&lt;id&gt;</code> in the <code>/aws/eks/&lt;cluster&gt;/cluster</code> log group. AWS notes delivery is best effort and standard CloudWatch Logs charges apply.</li>
<li><strong>Azure AKS:</strong> resource logs are not collected until you create a diagnostic setting. Microsoft&rsquo;s guidance warns that <code>kube-audit</code> can be costly and suggests <code>kube-audit-admin</code>, which leaves out <code>get</code> and <code>list</code> events. That saves money but drops exactly the read events, such as Secret reads, that matter in a credential-theft investigation. Decide that trade-off deliberately.</li>
</ul>
<h2 id="queries-to-keep-ready">Queries to keep ready</h2>
<p>These run against a JSON-lines audit log with <code>jq</code>. We ran each one against the log from the test above.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Who read or changed Secrets (excluding the API server itself)</span>
</span></span><span style="display:flex;"><span>jq -c <span style="color:#e6db74">&#39;select(.objectRef.resource==&#34;secrets&#34; and .user.username!=&#34;system:apiserver&#34;)
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">  | {ts:.requestReceivedTimestamp, user:.user.username, verb, ns:.objectRef.namespace,
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     name:.objectRef.name, code:.responseStatus.code}&#39;</span> audit.log
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Every exec into a Pod, with the command line</span>
</span></span><span style="display:flex;"><span>jq -c <span style="color:#e6db74">&#39;select(.objectRef.subresource==&#34;exec&#34;)
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">  | {ts:.requestReceivedTimestamp, user:.user.username, ns:.objectRef.namespace,
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     pod:.objectRef.name, uri:.requestURI}&#39;</span> audit.log
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Denied requests, including impersonated ones</span>
</span></span><span style="display:flex;"><span>jq -c <span style="color:#e6db74">&#39;select(.annotations[&#34;authorization.k8s.io/decision&#34;]==&#34;forbid&#34;)
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">  | {user:.user.username, as:.impersonatedUser.username, verb,
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     res:.objectRef.resource, ns:.objectRef.namespace}&#39;</span> audit.log
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># RBAC writes by people rather than the control plane, with what they granted</span>
</span></span><span style="display:flex;"><span>jq -c <span style="color:#e6db74">&#39;select(.objectRef.apiGroup==&#34;rbac.authorization.k8s.io&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">       and (.verb|test(&#34;create|update|patch|delete&#34;))
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">       and (.user.username|startswith(&#34;system:&#34;)|not))
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">  | {user:.user.username, verb, res:.objectRef.resource, name:.objectRef.name,
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     subjects:.requestObject.subjects, role:.requestObject.roleRef.name}&#39;</span> audit.log
</span></span></code></pre></div><p>A burst of <code>forbid</code> events from one identity across many resources can be a sign that someone is enumerating what a stolen credential can do.</p>
<h2 id="limits-of-this-article">Limits of this article</h2>
<p>We tested on a single kube-apiserver v1.34.1 with no nodes, no controller manager and static token authentication, so no workload actually ran and no kubelet or controller traffic was present. A real cluster produces far more events, and you will want extra <code>None</code> or <code>Metadata</code> rules for high-volume system traffic (the GCE policy is a good reference). The policy does not cover custom resources that hold credentials; add those to rule 2. <code>Request</code> level on Pod writes will log any credentials placed directly in environment variables. We did not test the webhook backend or any managed service.</p>
<h2 id="sources-and-verification">Sources and verification</h2>
<table>
  <thead>
      <tr>
          <th>Important claim</th>
          <th>Source</th>
          <th>Status</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Stages, levels, first-match evaluation, no logging without <code>--audit-policy-file</code>, zero-rule policy rejected, log and webhook flags, batching defaults, truncation off by default, memory note</td>
          <td><a href="https://kubernetes.io/docs/tasks/debug/debug-cluster/audit/">Kubernetes docs: Auditing</a> (<a href="https://github.com/kubernetes/website/blob/main/content/en/docs/tasks/debug/debug-cluster/audit.md">source</a>)</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Policy fields, <code>sourceIPs</code> and <code>userAgent</code> trust warnings, empty <code>resources</code> matches whole group</td>
          <td><a href="https://github.com/kubernetes/apiserver/blob/master/pkg/apis/audit/v1/types.go">audit.k8s.io/v1 types</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Secrets, ConfigMaps, TokenRequest and TokenReviews logged at Metadata; &ldquo;Get responses can be large&rdquo;</td>
          <td><a href="https://github.com/kubernetes/kubernetes/blob/master/cluster/gce/gci/configure-helper.sh">GCE configure-helper.sh audit policy</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td><code>authorization.k8s.io/decision</code> annotation</td>
          <td><a href="https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apiserver/pkg/endpoints/filters/authorization.go">kube-apiserver authorization filter</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Test results: Metadata Secret events without values, RequestResponse RBAC bodies, forbid annotation, impersonatedUser, exec URI and verbs, Secret value leaked with wrong rule order</td>
          <td>Our test on kube-apiserver v1.34.1 (envtest build)</td>
          <td>Verified (single test environment)</td>
      </tr>
      <tr>
          <td>EKS audit log off by default, stream naming, best-effort delivery, CloudWatch charges</td>
          <td><a href="https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html">Amazon EKS: Send control plane logs to CloudWatch Logs</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>AKS <code>kube-audit-admin</code> excludes get and list; logs need a diagnostic setting</td>
          <td><a href="https://docs.azure.cn/en-us/aks/monitor-apiserver">Microsoft: Monitor the AKS API server</a> (Azure China documentation mirror)</td>
          <td>Qualified</td>
      </tr>
      <tr>
          <td>Managed providers control the audit policy</td>
          <td>General provider architecture; not stated in one primary source</td>
          <td>Qualified</td>
      </tr>
  </tbody>
</table>
]]></content:encoded></item><item><title>VeloCloud Orchestrator CVE-2026-114625: Patch and Hunt</title><link>https://firewallsync.com/posts/velocloud-orchestrator-cve-2026-114625-patch-and-hunt/</link><guid>https://firewallsync.com/posts/velocloud-orchestrator-cve-2026-114625-patch-and-hunt/</guid><pubDate>Sun, 25 Oct 2026 04:40:00 +0000</pubDate><dc:creator>John Marshall</dc:creator><category>Security Operations</category><description>CVE-2026-114625 is a SQL injection in on-premises Arista VeloCloud Orchestrator that lets any authenticated user, down to the Enterprise Read Only role, act as the built-in superuser operator. CISA added it to KEV on October 23, 2026. It is the third exploited VCO flaw since July, and builds that fixed the first two are still vulnerable.</description><enclosure url="https://firewallsync.com/posts/velocloud-orchestrator-cve-2026-114625-patch-and-hunt/cover_hu1969827314249195703.jpg" type="image/jpeg" length="0"/><media:content url="https://firewallsync.com/posts/velocloud-orchestrator-cve-2026-114625-patch-and-hunt/cover_hu1969827314249195703.jpg" medium="image" type="image/jpeg" width="1200" height="630"/><content:encoded><![CDATA[<p><img src="https://firewallsync.com/posts/velocloud-orchestrator-cve-2026-114625-patch-and-hunt/cover_hu1969827314249195703.jpg" alt="Dozens of labelled blue network cables fanning out from rows of switch ports lit by small yellow-green status lights in a dark rack" width="1200" height="630"></p><p>CVE-2026-114625 is a SQL injection in on-premises Arista VeloCloud Orchestrator (VCO) that lets any authenticated portal user gain operator privileges and act as the local &ldquo;superuser operator&rdquo;. The lowest built-in tenant role, Enterprise Read Only, is enough. CISA added it to the Known Exploited Vulnerabilities (KEV) catalog on October 23, 2026. Upgrade to VCO 5.2.3.18, 6.1.3.10 or 6.4.2.12 or later, restrict the web interface to administrative networks until you can, and then check the orchestrator for signs that someone used it before you did.</p>
<p>It is also the third exploited VCO vulnerability in three months. If you patched in July or September and stopped there, you are still exposed.</p>
<h2 id="are-you-affected">Are you affected?</h2>
<p>You are affected if you run VCO on-premises on one of these versions, as listed in Arista&rsquo;s CVE record:</p>
<table>
  <thead>
      <tr>
          <th>Release train</th>
          <th>Affected</th>
          <th>Fixed in</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>5.2</td>
          <td>5.2.0 up to, not including, 5.2.3.18</td>
          <td>5.2.3.18 and later</td>
      </tr>
      <tr>
          <td>6.1</td>
          <td>6.1.0 up to, not including, 6.1.3.10</td>
          <td>6.1.3.10 and later</td>
      </tr>
      <tr>
          <td>6.4</td>
          <td>6.4.0 up to, not including, 6.4.2.12</td>
          <td>6.4.2.12 and later</td>
      </tr>
  </tbody>
</table>
<p>Arista says hosted VCO, including Dedicated, was affected and has already been patched. The record lists no 7.0 range for this CVE and marks unlisted versions as unaffected, but Arista&rsquo;s September advisory did list 7.0 builds as affected by an earlier flaw. If you run 7.0, confirm your status with Arista rather than relying on the absence of a row. With the July flaw, Arista said it had not assessed end-of-support releases, so if you are on an older train, ask Arista&rsquo;s Technical Assistance Center (TAC) about upgrade paths.</p>
<p>VCO is the management plane for VeloCloud SD-WAN. It holds configuration, device inventory and credentials for the Edges it manages, so treat it as a tier-0 system even if it doesn&rsquo;t look like one in your asset inventory.</p>
<h2 id="what-the-vulnerability-does">What the vulnerability does</h2>
<p>Arista&rsquo;s description in the CVE record: on an affected system, &ldquo;any authenticated user can gain operator privileges and masquerade as a local &lsquo;superuser operator&rsquo; user&rdquo;. That includes functionality meant for internal use only and not meant to be reachable remotely. The record classifies it as CWE-89 (SQL injection).</p>
<p>The conditions, per the record&rsquo;s configuration notes:</p>
<ul>
<li>VCO is exposed by default, and &ldquo;there is no configuration that can prevent the exposure&rdquo;.</li>
<li>The attacker needs network access to the VCO web interface.</li>
<li>The attacker needs a valid authenticated session on the VCO portal. The minimum role is <strong>Enterprise Read Only</strong>.</li>
</ul>
<p>That last condition matters more than it first appears. In a multi-tenant VCO, a read-only user at one customer or one business unit could reach operator-level control over the whole orchestrator. Every tenant login, including service accounts, shared logins and accounts left behind by former staff or partners, is a possible starting point.</p>
<p>Arista scores it CVSS 3.1 <strong>9.9</strong> (<code>AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H</code>) and CVSS 4.0 <strong>9.4</strong>. The <code>PR:L</code> (low privileges required) is the only thing keeping it off 10.0. The record says the issue was discovered externally. Arista published Security Advisory 0199 and the CVE record on October 22, 2026.</p>
<h2 id="exploitation-status">Exploitation status</h2>
<p>The evidence of exploitation comes from CISA rather than from Arista&rsquo;s CVE text:</p>
<ul>
<li><strong>KEV:</strong> CISA added CVE-2026-114625 on October 23, 2026, with a due date of <strong>October 26, 2026</strong> for US federal civilian agencies. The entry has the forensic triage flag set, so under <a href="/posts/cisa-bod-26-04-explained-kev-deadlines-forensic-triage-and-what-private-teams-can-borrow/">BOD 26-04</a> agencies must also check for compromise, not just patch. Known ransomware use is listed as &ldquo;Unknown&rdquo;.</li>
<li><strong>SSVC:</strong> CISA&rsquo;s Vulnrichment entry in the CVE record, timestamped October 22, rates Exploitation <strong>active</strong>, Automatable <strong>no</strong> and Technical Impact <strong>total</strong>. If you use the <a href="/posts/ssvc-deployer-patch-priority-model-explained-exploitation-exposure-automatable-and-human-impact/">SSVC deployer model</a>, &ldquo;active&rdquo; plus &ldquo;total&rdquo; puts an internet-facing VCO at the top of the queue even though the flaw needs a login.</li>
</ul>
<p>Arista&rsquo;s records for the July and September VCO flaws said explicitly that they were &ldquo;known to be actively exploited&rdquo;. The October record does not, and at the time of writing we found no public detail on who is exploiting this one or how. Treat attribution and scale as unknown.</p>
<h2 id="third-exploited-vco-flaw-since-july">Third exploited VCO flaw since July</h2>
<p>CISA&rsquo;s KEV catalog now lists three VeloCloud Orchestrator vulnerabilities, all added in 2026:</p>
<table>
  <thead>
      <tr>
          <th>CVE</th>
          <th>Arista advisory</th>
          <th>Added to KEV</th>
          <th>Type (CWE)</th>
          <th>Credentials needed</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>CVE-2026-16812</td>
          <td>0144, July 27</td>
          <td>July 27</td>
          <td>OS command injection (CWE-78)</td>
          <td>None</td>
      </tr>
      <tr>
          <td>CVE-2026-93952</td>
          <td>0183, September 22</td>
          <td>September 22</td>
          <td>Improper input validation (CWE-20)</td>
          <td>None, but needs certificate-based Edge authentication and the public part of an Edge certificate</td>
      </tr>
      <tr>
          <td>CVE-2026-114625</td>
          <td>0199, October 22</td>
          <td>October 23</td>
          <td>SQL injection (CWE-89)</td>
          <td>Any portal user (Enterprise Read Only or above)</td>
      </tr>
  </tbody>
</table>
<p>Each fix moved the floor. We checked a set of common builds against the affected ranges in all three CVE records:</p>
<table>
  <thead>
      <tr>
          <th>Build</th>
          <th>Still affected by</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>5.2.3.14 (July fix)</td>
          <td>CVE-2026-93952, CVE-2026-114625</td>
      </tr>
      <tr>
          <td>5.2.3.16 (September fix)</td>
          <td>CVE-2026-114625</td>
      </tr>
      <tr>
          <td>5.2.3.18</td>
          <td>None of the three</td>
      </tr>
      <tr>
          <td>6.1.3.4 (July fix)</td>
          <td>CVE-2026-93952, CVE-2026-114625</td>
      </tr>
      <tr>
          <td>6.1.3.10</td>
          <td>None of the three</td>
      </tr>
      <tr>
          <td>6.4.2.4 (July fix)</td>
          <td>CVE-2026-93952, CVE-2026-114625</td>
      </tr>
      <tr>
          <td>6.4.2.8 (September fix)</td>
          <td>CVE-2026-114625</td>
      </tr>
      <tr>
          <td>6.4.2.12</td>
          <td>None of the three</td>
      </tr>
      <tr>
          <td>7.0.0.1 (July fix)</td>
          <td>CVE-2026-93952</td>
      </tr>
  </tbody>
</table>
<p>That table was generated by comparing each build to the <code>affected</code> version ranges in the three CVE JSON records from the CVEProject/cvelistV5 repository. It reflects what the records say, not testing against a VCO. Arista&rsquo;s September advisory did not list a fixed 6.1 or 7.0 build for CVE-2026-93952 when it was published, so for those trains check Arista&rsquo;s current advisory before assuming you&rsquo;re clear.</p>
<p>The practical point: an orchestrator that was patched once and then left alone has been inside at least one exploited vulnerability window for most of the last three months. That changes the hunting question from &ldquo;was I hit last week?&rdquo; to &ldquo;has this box been clean since July?&rdquo;</p>
<h2 id="what-to-do-now">What to do now</h2>
<ol>
<li><strong>Find every VCO you run.</strong> Include lab, DR and acquired-company instances. Record version, train and whether the web interface is reachable from the internet.</li>
<li><strong>Restrict the web interface</strong> to trusted administrative networks now, before the upgrade window. This is Arista&rsquo;s first interim control. It does not remove the risk from users who already have access.</li>
<li><strong>Upgrade</strong> to 5.2.3.18, 6.1.3.10 or 6.4.2.12 or later. If you are on 7.0 or an unsupported train, open a case with Arista TAC.</li>
<li><strong>Preserve evidence first</strong> if anything below looks wrong. Arista&rsquo;s September advisory asks for web access logs, application and system logs, database logs and file-system timestamps to be kept before remediation. An upgrade can overwrite exactly the files you need.</li>
<li><strong>Cut back portal accounts.</strong> Remove dormant tenant users, rotate shared credentials, and check that partner and MSP accounts are still needed. This flaw turns every one of them into a path to operator rights.</li>
<li><strong>Block outbound traffic</strong> from the VCO host that normal operation doesn&rsquo;t need. Arista lists this in the October workarounds.</li>
</ol>
<p>For the wider prioritization question, our guide to <a href="/posts/cisa-kev-json-feed-what-each-field-means-and-how-to-match-it-against-a-scanner-export/">matching the KEV feed against a scanner export</a> shows how to catch the next one automatically.</p>
<h2 id="how-to-hunt">How to hunt</h2>
<p>Arista&rsquo;s October record lists the same detection areas as its earlier VCO advisories: access from known malicious IPs, unexpected outbound network activity from the VCO host, backdoor daemons and web shells, and unexpected administrator activity. It does not publish indicators specific to CVE-2026-114625.</p>
<p>Arista did publish concrete indicators with the September flaw, CVE-2026-93952 (Security Advisory 0183). Arista has not said they are linked to the October issue. Because most builds vulnerable today were also exposed to CVE-2026-93952, they are a sensible baseline:</p>
<table>
  <thead>
      <tr>
          <th>Indicator (from advisory 0183)</th>
          <th>Where to look</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>/usr/local/sbin/.vcnode.js</code></td>
          <td>File system</td>
      </tr>
      <tr>
          <td><code>/usr/local/sbin/vc-sysmond</code>, known malicious MD5 <code>dc78e206eaeadec59fc5801fe4556bd0</code></td>
          <td>File system</td>
      </tr>
      <tr>
          <td><code>/etc/systemd/system/vc-sysmon.service</code></td>
          <td>systemd units</td>
      </tr>
      <tr>
          <td><code>x-vc-opt</code> HTTP header</td>
          <td>nginx access logs</td>
      </tr>
      <tr>
          <td>142.93.149.77, 104.248.126.159</td>
          <td>Web and firewall logs</td>
      </tr>
  </tbody>
</table>
<p>A starting point on the VCO host, run as root. This is illustrative and was not tested against a VCO; adjust log paths to your build:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Persistence files named in Arista advisory 0183</span>
</span></span><span style="display:flex;"><span>ls -la /usr/local/sbin/.vcnode.js /usr/local/sbin/vc-sysmond <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>       /etc/systemd/system/vc-sysmon.service 2&gt;/dev/null
</span></span><span style="display:flex;"><span>md5sum /usr/local/sbin/vc-sysmond 2&gt;/dev/null
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Header and source IPs from the same advisory in nginx logs</span>
</span></span><span style="display:flex;"><span>zgrep -il <span style="color:#e6db74">&#39;x-vc-opt&#39;</span> /var/log/nginx/*access* 2&gt;/dev/null
</span></span><span style="display:flex;"><span>zgrep -hE <span style="color:#e6db74">&#39;142\.93\.149\.77|104\.248\.126\.159&#39;</span> /var/log/nginx/*access* 2&gt;/dev/null | head
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Unexpected outbound connections from the orchestrator</span>
</span></span><span style="display:flex;"><span>ss -tnp state established
</span></span></code></pre></div><p>Beyond file indicators, Arista&rsquo;s advisories point to behavior worth reviewing in the VCO&rsquo;s own audit trail:</p>
<ul>
<li>operator-level actions taken by accounts that only hold tenant roles, or by the local superuser operator at times nobody on your team was working</li>
<li>sensitive configuration changes or privileged maintenance actions with no matching change ticket</li>
<li>database exports, new archive files, or unexpected access to device inventory, certificates and keys</li>
<li>configuration pushed to Edges that you did not approve</li>
</ul>
<p>If you find a compromise, Arista&rsquo;s guidance from the earlier advisories applies: rotate credentials, validate the state of every managed Edge, and restore or replace the orchestrator from a trusted source. Patching a compromised VCO does not remove an attacker who is already there.</p>
<h2 id="limits-of-this-article">Limits of this article</h2>
<p>We could not retrieve Arista&rsquo;s Security Advisory 0199 page directly. The affected versions, conditions, workarounds and description above come from the CVE record Arista published as the CNA, which carries the advisory&rsquo;s content. We have not tested any VCO build, and the hunting commands are a starting point, not a validated detection. There is no public technical write-up of the exploit at the time of writing.</p>
<h2 id="sources-and-verification">Sources and verification</h2>
<table>
  <thead>
      <tr>
          <th>Important claim</th>
          <th>Source</th>
          <th>Status</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Description, &ldquo;superuser operator&rdquo;, Enterprise Read Only minimum role, exposed by default, affected and fixed versions, hosted and Dedicated patched, CVSS 9.9 / 9.4, CWE-89, external discovery, workarounds</td>
          <td><a href="https://github.com/CVEProject/cvelistV5/blob/main/cves/2026/114xxx/CVE-2026-114625.json">CVE-2026-114625 record (Arista as CNA)</a>; <a href="https://www.arista.com/en/support/advisories-notices/security-advisory/24838-security-advisory-0199">Arista Security Advisory 0199</a></td>
          <td>Verified (CVE record)</td>
      </tr>
      <tr>
          <td>KEV addition October 23, due October 26, forensic triage flag, ransomware use Unknown</td>
          <td><a href="https://www.cisa.gov/known-exploited-vulnerabilities-catalog">CISA KEV catalog</a> (JSON feed, catalog version 2026.10.23)</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>SSVC: Exploitation active, Automatable no, Technical Impact total</td>
          <td>CISA ADP Vulnrichment container in the CVE-2026-114625 record</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>CVE-2026-16812: July 27, OS command injection, no credentials needed, fixed builds</td>
          <td><a href="https://github.com/CVEProject/cvelistV5/blob/main/cves/2026/16xxx/CVE-2026-16812.json">CVE-2026-16812 record</a>; <a href="https://bleepingcomputer.com/news/security/arista-patches-velocloud-orchestrator-zero-day-exploited-in-attacks">BleepingComputer, July 27, 2026</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>CVE-2026-93952: conditions, affected and fixed builds, indicators of compromise, evidence preservation and post-compromise guidance</td>
          <td><a href="https://www.arista.com/en/support/advisories-notices/security-advisory/24765-security-advisory-0183">Arista Security Advisory 0183</a>; <a href="https://github.com/CVEProject/cvelistV5/blob/main/cves/2026/93xxx/CVE-2026-93952.json">CVE-2026-93952 record</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Build-by-build &ldquo;still affected by&rdquo; table</td>
          <td>Computed from the three CVE records&rsquo; version ranges</td>
          <td>Verified (computed, not tested on VCO)</td>
      </tr>
      <tr>
          <td>Status of the 7.0 train for CVE-2026-114625</td>
          <td>Not listed in the CVE record</td>
          <td>Qualified</td>
      </tr>
  </tbody>
</table>
]]></content:encoded></item><item><title>Collabora CODE CVE-2026-110447: Patch Nextcloud, Then Hunt</title><link>https://firewallsync.com/posts/collabora-code-cve-2026-110447-nextcloud-patch-and-hunt/</link><guid>https://firewallsync.com/posts/collabora-code-cve-2026-110447-nextcloud-patch-and-hunt/</guid><pubDate>Sat, 24 Oct 2026 04:30:00 +0000</pubDate><dc:creator>Craig Leslie</dc:creator><category>Security Operations</category><description>CVE-2026-110447 is an unauthenticated OS command injection in proxy.php of the Collabora Online Built-in CODE Server app for Nextcloud (richdocumentscode) before 26.4.303. It was exploited from September, a month before the CVE was published, and CISA added it to KEV on October 23. Update or remove the app, then hunt for web shells.</description><enclosure url="https://firewallsync.com/posts/collabora-code-cve-2026-110447-nextcloud-patch-and-hunt/cover_hu8653931782960325198.jpg" type="image/jpeg" length="0"/><media:content url="https://firewallsync.com/posts/collabora-code-cve-2026-110447-nextcloud-patch-and-hunt/cover_hu8653931782960325198.jpg" medium="image" type="image/jpeg" width="1200" height="630"/><content:encoded><![CDATA[<p><img src="https://firewallsync.com/posts/collabora-code-cve-2026-110447-nextcloud-patch-and-hunt/cover_hu8653931782960325198.jpg" alt="A panelled door standing ajar in a pitch-black room, warm light spilling through the gap and across the floor" width="1200" height="630"></p><p>If your Nextcloud server runs the <strong>Collabora Online - Built-in CODE Server</strong> app (<code>richdocumentscode</code>) at any version before 26.4.303, treat it as exposed to unauthenticated remote code execution. Update the app to the current release or remove it today, then hunt for web shells: the fix shipped on September 11, 2026, attacks were reported from September 10, and the CVE was not published until October 14. CISA added CVE-2026-110447 to its Known Exploited Vulnerabilities (KEV) catalog on October 23, with a due date of October 26 for US federal civilian agencies.</p>
<h2 id="are-you-affected">Are you affected?</h2>
<p>The CVE record is specific: the flaw is &ldquo;not present in standalone Collabora Online servers; only this deployment with CODE Server is affected.&rdquo;</p>
<table>
  <thead>
      <tr>
          <th>Deployment</th>
          <th>Affected?</th>
          <th>Basis</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>richdocumentscode</code> app before 26.4.303</td>
          <td>Yes</td>
          <td>CVE record</td>
      </tr>
      <tr>
          <td><code>richdocumentscode</code> 26.4.303 or later</td>
          <td>No</td>
          <td>CVE record (fixed version)</td>
      </tr>
      <tr>
          <td>Nextcloud Office (<code>richdocuments</code>) pointed at a separately run Collabora Online server (Docker, DEB/RPM, appliance)</td>
          <td>No</td>
          <td>CVE record; Collabora advisory as reported</td>
      </tr>
      <tr>
          <td>Nextcloud All-in-One</td>
          <td>No</td>
          <td>Collabora, as reported by BleepingComputer</td>
      </tr>
      <tr>
          <td>Nextcloud 29 or older with the app installed</td>
          <td>Upgrade Nextcloud or remove the app; 26.4.303 needs Nextcloud 30 or later</td>
          <td>App metadata (<code>min-version=&quot;30&quot;</code>); advisory as reported</td>
      </tr>
  </tbody>
</table>
<p>The two app names are easy to confuse. <code>richdocuments</code> is the Nextcloud Office connector. <code>richdocumentscode</code> is the optional app that bundles a CODE (Collabora Online Development Edition) AppImage and starts it on the Nextcloud host. Only the second is in scope.</p>
<p>Check which you have from the Nextcloud directory:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Run as the web server user; adjust the user and path for your install</span>
</span></span><span style="display:flex;"><span>sudo -u www-data php occ app:list | grep -E <span style="color:#e6db74">&#39;richdocuments(code)?:&#39;</span>
</span></span></code></pre></div><h2 id="the-vulnerability">The vulnerability</h2>
<table>
  <thead>
      <tr>
          <th>Field</th>
          <th>Value</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>CVE</td>
          <td>CVE-2026-110447</td>
      </tr>
      <tr>
          <td>Product</td>
          <td>Collabora Online - Built-in CODE Server (<code>richdocumentscode</code>), a Nextcloud app</td>
      </tr>
      <tr>
          <td>Affected</td>
          <td>All versions before 26.4.303</td>
      </tr>
      <tr>
          <td>Weakness</td>
          <td>CWE-78, OS command injection, in <code>proxy.php</code></td>
      </tr>
      <tr>
          <td>Condition</td>
          <td>The CODE server is not running, &ldquo;e.g., the product was recently restarted&rdquo;</td>
      </tr>
      <tr>
          <td>CVSS 4.0</td>
          <td>9.2 Critical, <code>CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N</code></td>
      </tr>
      <tr>
          <td>CISA SSVC</td>
          <td>Exploitation: active; Automatable: yes; Technical Impact: total</td>
      </tr>
      <tr>
          <td>KEV</td>
          <td>Added October 23, 2026; due October 26, 2026; forensic triage: yes</td>
      </tr>
  </tbody>
</table>
<p>The <code>AT:P</code> (attack requirements present) in the vector reflects that precondition: the bundled server has to be down. That is less of a barrier than it sounds. Restarts, app upgrades and crashes all stop it, and in the vulnerable code an unauthenticated <code>?status</code> request to <code>proxy.php</code> is what asks for the server to be started when it is not running. If you are new to v4.0 vectors, our guide to <a href="/posts/how-to-read-a-cvss-v4-0-vector-string-metric-by-metric-with-real-cve-records/">reading a CVSS v4.0 vector string</a> walks through each metric.</p>
<p>The CVE record also says this is &ldquo;a different vulnerability than CVE-2025-66208&rdquo;, so a host patched for that earlier issue is not covered.</p>
<h3 id="what-the-fix-changed">What the fix changed</h3>
<p>The CVE record describes the bug only as command injection in <code>proxy.php</code>. The app&rsquo;s public repository shows more. This section is our reading of that source, not a vendor statement.</p>
<p>In 26.4.302, <code>startCoolwsd()</code> built the launch command as one string. Two values derived from the request, the HTTP <code>Host</code> header and the request URI (used to build a font-configuration URL), were each passed through PHP&rsquo;s <code>escapeshellarg()</code>, which wraps them in single quotes. The whole command was then placed inside a double-quoted <code>bash -c &quot;...&quot;</code> string and handed to the shell. Single quotes have no special meaning inside double quotes, so shell command substitution in those values was still evaluated by the outer shell.</p>
<p>The 26.4.303 change, committed on September 9, wraps the entire inner command in <code>escapeshellarg()</code> before passing it to <code>bash -c</code>. The current code goes further: it passes an argument array to <code>proc_open()</code> and runs a fixed script that receives the options as <code>&quot;$@&quot;</code>, so no request value is ever parsed by a shell.</p>
<p>Two practical consequences follow. First, the attacker-controlled input sits in ordinary request fields, so web server access logs and any proxy logs that record the <code>Host</code> header are your best evidence. Second, the vulnerable <code>proxy.php</code> in 26.4.302 includes no Nextcloud bootstrap at all, which fits Collabora&rsquo;s warning that disabling the app does not help: if the web server serves the file, it runs.</p>
<h2 id="timeline">Timeline</h2>
<table>
  <thead>
      <tr>
          <th>Date (2026)</th>
          <th>Event</th>
          <th>Source</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>September 9</td>
          <td>Fix committed to <code>proxy.php</code></td>
          <td>richdocumentscode repository</td>
      </tr>
      <tr>
          <td>September 10</td>
          <td>Earliest attacks reported by administrators</td>
          <td>BleepingComputer, eSecurityPlanet</td>
      </tr>
      <tr>
          <td>September 11</td>
          <td>26.4.303 released; GitHub issue #354 opened by affected admins</td>
          <td>Repository tag and changelog; WZ-IT</td>
      </tr>
      <tr>
          <td>October 3</td>
          <td>Community warning on the Nextcloud forum to update immediately</td>
          <td>BleepingComputer</td>
      </tr>
      <tr>
          <td>October 14</td>
          <td>CVE published; Collabora advisory GHSA-g3vx-3m76-fghh</td>
          <td>CVE record</td>
      </tr>
      <tr>
          <td>October 23</td>
          <td>CISA adds the CVE to KEV; app 26.4.502 released</td>
          <td>KEV catalog; repository changelog</td>
      </tr>
      <tr>
          <td>October 26</td>
          <td>KEV due date for US federal civilian agencies</td>
          <td>KEV catalog</td>
      </tr>
  </tbody>
</table>
<p>A month passed between a public fix and a CVE. Collabora, according to BleepingComputer, attributed much of the delay to GitHub&rsquo;s CVE-processing backlog. Whatever the reason, anyone who waited for a CVE or a scanner signature before updating was exposed for the entire window, which is why the hunt below matters more than the patch date. Our explainer on <a href="/posts/cisa-bod-26-04-explained-kev-deadlines-forensic-triage-and-what-private-teams-can-borrow/">CISA BOD 26-04</a> covers what KEV&rsquo;s &ldquo;forensic triage: yes&rdquo; flag asks federal agencies to do. Private teams can borrow the same approach.</p>
<h2 id="what-to-do-now">What to do now</h2>
<ol>
<li>
<p><strong>Decide whether you need the built-in server.</strong> If you only installed it to try Nextcloud Office, remove it:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo -u www-data php occ app:remove richdocumentscode
</span></span><span style="display:flex;"><span>ls -d apps/richdocumentscode 2&gt;/dev/null <span style="color:#f92672">&amp;&amp;</span> echo <span style="color:#e6db74">&#34;directory still present&#34;</span>
</span></span></code></pre></div><p>Confirm the directory is actually gone. A leftover <code>proxy.php</code> is the risk.</p>
</li>
<li>
<p><strong>Otherwise update it.</strong> The latest release at the time of writing is 26.4.502 (October 23). Anything at or above 26.4.303 contains the fix.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo -u www-data php occ app:update richdocumentscode
</span></span><span style="display:flex;"><span>sudo -u www-data php occ app:list | grep <span style="color:#e6db74">&#39;richdocumentscode:&#39;</span>
</span></span></code></pre></div></li>
<li>
<p><strong>If you are on Nextcloud 29 or older</strong>, 26.4.303 will not install, because the app now requires Nextcloud 30. Remove the app or upgrade Nextcloud first. Those Nextcloud releases are end of life.</p>
</li>
<li>
<p><strong>Block the file at the edge as a stopgap</strong> if neither is possible in the next few hours. Denying requests to <code>/apps/richdocumentscode/proxy.php</code> at the reverse proxy breaks the built-in server, but it removes the unauthenticated entry point. This is a stopgap of our own, not vendor guidance, and it does nothing about a shell that is already there.</p>
</li>
</ol>
<h2 id="how-to-hunt">How to hunt</h2>
<p>Run these checks whether or not you have already patched. The indicators below come from administrators&rsquo; reports in the app&rsquo;s GitHub issue #354, as summarized by eSecurityPlanet and WZ-IT; we could not read the issue directly, so treat them as a starting point, not a complete list.</p>
<h3 id="files">Files</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>cd /var/www/nextcloud   <span style="color:#75715e"># your Nextcloud root</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Reported web shell names, then any PHP file that is not part of the release</span>
</span></span><span style="display:flex;"><span>find apps/richdocumentscode -maxdepth <span style="color:#ae81ff">2</span> <span style="color:#ae81ff">\(</span> -name <span style="color:#e6db74">&#39;shx*.php&#39;</span> -o -name <span style="color:#e6db74">&#39;shrf4645.php&#39;</span> <span style="color:#ae81ff">\)</span>
</span></span><span style="display:flex;"><span>sudo -u www-data php occ integrity:check-app richdocumentscode
</span></span></code></pre></div><p><code>integrity:check-app</code> compares the app directory with the signed release and lists extra files as <code>EXTRA_FILE</code>. A clean result after an update is good news; a hit means you go to the response steps below. Also look for recently modified PHP files elsewhere under <code>apps/</code> and in the data directory, since an attacker with a shell can write anywhere the web server account can.</p>
<h3 id="web-server-logs">Web server logs</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Requests to proxy.php that carry shell syntax, raw or URL-encoded</span>
</span></span><span style="display:flex;"><span>zgrep -hiE <span style="color:#e6db74">&#39;richdocumentscode/proxy\.php&#39;</span> /var/log/nginx/access.log* /var/log/apache2/access.log* 2&gt;/dev/null <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  | grep -iE <span style="color:#e6db74">&#39;\$\(|%24%28|\$\{IFS\}|%24%7BIFS|%2e%2e&#39;</span>
</span></span></code></pre></div><p>We ran the <code>find</code> and log-search commands above against sample files with GNU findutils and grep to confirm they match the reported patterns; adapt the paths to your install. The reported patterns are <code>$(</code> or <code>%24%28</code> (command substitution), <code>${IFS}</code> (used to avoid spaces) and <code>%2e%2e</code> (path traversal), along with bursts of <code>proxy.php?status</code> requests. Because the injected value can travel in the <code>Host</code> header, check whether your log format records it; the default combined format does not. If it does not, look at reverse proxy or load balancer logs that do. Go back to at least September 10, 2026.</p>
<h3 id="host-signals">Host signals</h3>
<ul>
<li>Outbound connections from the web server to <code>webhook.site</code> or other request-capture services, which reported payloads used to send back system information.</li>
<li>Failed <code>sudo</code> attempts by <code>www-data</code> or your equivalent web server user in the auth log.</li>
<li>New cron entries, SSH keys or processes owned by the web server user.</li>
</ul>
<p>Reported post-exploitation activity included searches for password manager files, cryptocurrency wallets and keystores. Published reporting we reviewed does not confirm data exfiltration or root access.</p>
<h2 id="if-you-find-a-web-shell">If you find a web shell</h2>
<p>The web server account can read Nextcloud&rsquo;s <code>config/config.php</code>, which holds the database password, the instance secret and any object storage, SMTP or other service credentials configured there. It can also read every file in the data directory.</p>
<ol>
<li>Preserve the suspicious files and logs before you delete anything.</li>
<li>Isolate the host, then rebuild it or restore from a backup taken before the first suspicious request. Deleting the shell does not remove anything else the attacker set up.</li>
<li>Rotate every secret in <code>config.php</code> and any credential the web server account could reach.</li>
<li>Tell users whose files were on the server, and follow your own incident and notification obligations.</li>
</ol>
<h2 id="prioritizing-this-against-everything-else">Prioritizing this against everything else</h2>
<p>This one does not need a scoring debate. It has an active-exploitation SSVC value, it is in KEV, it needs no credentials, and the vulnerable component is reachable on the same host and port as Nextcloud. If you use the three signals together, as we argue in <a href="/posts/cvss-vs-epss-vs-kev-which-signal-should-decide-what-you-patch-first/">CVSS vs EPSS vs KEV</a>, every one of them points the same way. CISA&rsquo;s SSVC values are explained in our guide to <a href="/posts/cisa-vulnrichment-how-to-read-ssvc-values-in-a-cve-record-and-turn-them-into-a-patch-decision/">reading Vulnrichment SSVC data</a>.</p>
<h2 id="limits-of-this-article">Limits of this article</h2>
<p>We could not read Collabora&rsquo;s advisory (GHSA-g3vx-3m76-fghh), the Nextcloud forum warning or GitHub issue #354 directly. Statements attributed to them come from the CVE record, CISA&rsquo;s KEV entry and press coverage, and are labelled as such. The root-cause description is our reading of the public source diff. We have not tested exploitation, and the indicator list comes from early victim reports, so absence of these indicators is not proof that a server is clean.</p>
<h2 id="sources-and-verification">Sources and verification</h2>
<table>
  <thead>
      <tr>
          <th>Important claim</th>
          <th>Source</th>
          <th>Verification</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Affected before 26.4.303; OS command injection in <code>proxy.php</code> when the CODE server isn&rsquo;t running; exploited in September and October 2026; distinct from CVE-2025-66208; standalone servers not affected; CWE-78; CVSS 4.0 9.2 and vector; published October 14</td>
          <td><a href="https://www.cve.org/CVERecord?id=CVE-2026-110447">CVE-2026-110447 record</a> (read via the cvelistV5 repository)</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>SSVC: Exploitation active, Automatable yes, Technical Impact total</td>
          <td>CISA ADP container in the CVE record</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>KEV addition October 23, due October 26, forensic triage flag, BOD 26-04 required action</td>
          <td><a href="https://www.cisa.gov/known-exploited-vulnerabilities-catalog">CISA KEV catalog</a> (JSON feed, catalog version 2026.10.23)</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Fix committed September 9; 26.4.303 released September 11; 26.4.502 released October 23; Nextcloud 30 minimum; <code>Host</code> header and request URI in the launch command; standalone <code>proxy.php</code>; <code>?status</code> starts the server</td>
          <td><a href="https://github.com/CollaboraOnline/richdocumentscode">richdocumentscode repository</a> (tags 26.4.302, 26.4.303, 26.4.502 and CHANGELOG)</td>
          <td>Verified from source; root-cause reading is editorial</td>
      </tr>
      <tr>
          <td>&ldquo;Disabling the app is insufficient&rdquo;; Docker, package and All-in-One installs not affected; attacks from September 10; October 3 forum warning; Collabora&rsquo;s comments on CVE delay</td>
          <td><a href="https://www.bleepingcomputer.com/news/security/hackers-exploit-collabora-rce-flaw-to-backdoor-nextcloud-servers/">BleepingComputer</a></td>
          <td>Qualified: secondary report of vendor and admin statements</td>
      </tr>
      <tr>
          <td>Web shell names, log patterns, webhook.site callbacks, sudo attempts, data searched for</td>
          <td><a href="https://www.esecurityplanet.com/threats/news-collabora-nextcloud-cve-2026-110447/">eSecurityPlanet</a>; <a href="https://wz-it.com/en/blog/nextcloud-built-in-code-server-cve-2026-110447-rce-webshell/">WZ-IT</a></td>
          <td>Qualified: secondary summaries of GitHub issue #354</td>
      </tr>
      <tr>
          <td><code>occ integrity:check-app</code> reports extra files</td>
          <td>WZ-IT</td>
          <td>Qualified</td>
      </tr>
  </tbody>
</table>
]]></content:encoded></item><item><title>Atlassian CVE-2026-21589 File Read: Patch and Hunt</title><link>https://firewallsync.com/posts/atlassian-cve-2026-21589-data-center-file-read-patch-and-hunt/</link><guid>https://firewallsync.com/posts/atlassian-cve-2026-21589-data-center-file-read-patch-and-hunt/</guid><pubDate>Fri, 23 Oct 2026 04:30:00 +0000</pubDate><dc:creator>John Marshall</dc:creator><category>Security Operations</category><description>CVE-2026-21589 lets an unauthenticated attacker read files inside the web root of eight Atlassian Data Center products, including Jira, Confluence and Bitbucket. CISA added it to KEV on October 15. Here are the fixed versions, the interim mitigations, how to search access logs, and which secrets to rotate if a read succeeded.</description><enclosure url="https://firewallsync.com/posts/atlassian-cve-2026-21589-data-center-file-read-patch-and-hunt/cover_hu8381364802700144461.jpg" type="image/jpeg" length="0"/><media:content url="https://firewallsync.com/posts/atlassian-cve-2026-21589-data-center-file-read-patch-and-hunt/cover_hu8381364802700144461.jpg" medium="image" type="image/jpeg" width="1200" height="630"/><content:encoded><![CDATA[<p><img src="https://firewallsync.com/posts/atlassian-cve-2026-21589-data-center-file-read-patch-and-hunt/cover_hu8381364802700144461.jpg" alt="Two worn white card-catalog cabinets with brass label holders and handles, several drawers pulled partly open" width="1200" height="630"></p><p>CVE-2026-21589 lets an unauthenticated attacker read files from the web root of self-managed Jira, Confluence, Bitbucket, Bamboo, Crowd, Crucible and Fisheye. If you run any of them, upgrade to a fixed release now, check your access logs back to early October, and rotate credentials stored in configuration files if a read may have succeeded. CISA added the flaw to its <a href="/posts/cisa-kev-json-feed-what-each-field-means-and-how-to-match-it-against-a-scanner-export/">Known Exploited Vulnerabilities catalog</a> on October 15, 2026.</p>
<p>Atlassian Cloud is not part of the job: Atlassian says it has already patched affected Cloud products.</p>
<h2 id="the-vulnerability">The vulnerability</h2>
<p>Atlassian&rsquo;s CVE record describes an arbitrary file access flaw (CWE-552, files or directories accessible to external parties) that &ldquo;allows an unauthenticated attacker to access specific files within the web application root directory.&rdquo; Atlassian scores it CVSS 4.0 <strong>9.3</strong>, vector <code>CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:H/SI:H/SA:H</code>.</p>
<p>Read that vector carefully (our <a href="/posts/how-to-read-a-cvss-v4-0-vector-string-metric-by-metric-with-real-cve-records/">CVSS v4.0 walkthrough</a> covers each metric). The vulnerable product loses confidentiality only (<code>VC:H</code>, <code>VI:N</code>, <code>VA:N</code>). The high scores for <em>subsequent</em> systems (<code>SC:H/SI:H/SA:H</code>) reflect what stolen files can unlock elsewhere: credentials in a configuration file are worth more than the file.</p>
<p>Two limits from the record matter for triage:</p>
<ul>
<li>The attacker needs the <strong>exact name and path</strong> of the file. The flaw &ldquo;does not allow attackers to enumerate or list directory contents.&rdquo;</li>
<li>Atlassian says &ldquo;in some configurations, there may be some sensitive files that make this highly severe.&rdquo; Whether a given instance is a nuisance or a breach depends on what sits in its web root.</li>
</ul>
<h3 id="root-cause-per-watchtowr">Root cause, per watchTowr</h3>
<p>watchTowr Labs diffed vulnerable and patched Jira, Confluence and Bitbucket builds and, as summarized by Rapid7, found a path traversal in Atlassian&rsquo;s web-resource handling where double-colon (<code>::</code>) sequences can act as path separators during request processing. In watchTowr&rsquo;s testing the attacker could not leave the Tomcat context but could read files throughout the web root, including the protected <code>WEB-INF/web.xml</code>.</p>
<p>The most serious example in the research is Crowd. In a Crowd deployment connected to Jira, reading <code>WEB-INF/classes/crowd.properties</code> exposed application credentials. watchTowr used them to create a user and add it to <code>jira-administrators</code>. Rapid7 notes that Crowd&rsquo;s IP allowlisting for applications can block that second step.</p>
<h2 id="timeline">Timeline</h2>
<table>
  <thead>
      <tr>
          <th>Date (2026)</th>
          <th>Event</th>
          <th>Source</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>October 5</td>
          <td>Atlassian publishes the advisory and fixed releases; CVE record published</td>
          <td>CVE record, Rapid7</td>
      </tr>
      <tr>
          <td>October 6</td>
          <td>watchTowr publishes its technical analysis and a checker script</td>
          <td>Rapid7, Help Net Security</td>
      </tr>
      <tr>
          <td>October 6</td>
          <td>Previdian reports exploitation attempts hitting its honeypots</td>
          <td>Help Net Security</td>
      </tr>
      <tr>
          <td>October 15</td>
          <td>CISA adds the CVE to KEV; CISA&rsquo;s SSVC entry records exploitation as active</td>
          <td>KEV catalog, CVE record (CISA ADP)</td>
      </tr>
      <tr>
          <td>October 18</td>
          <td>KEV due date for US federal civilian agencies</td>
          <td>KEV catalog</td>
      </tr>
  </tbody>
</table>
<p>Reports differ on what was published. Help Net Security says watchTowr built but did not publish an exploit and released a vulnerability checker. Rapid7 says file-read proof-of-concept scripts and a Nuclei template are publicly available. Either way, detailed root-cause analysis has been public since October 6, and you should assume working exploits exist.</p>
<p>CISA&rsquo;s SSVC values in the CVE record are Exploitation <strong>active</strong>, Automatable <strong>no</strong>, Technical Impact <strong>total</strong>. &ldquo;Automatable: no&rdquo; fits the need to know file paths per target; it is not a reason to wait. Our <a href="/posts/cisa-vulnrichment-how-to-read-ssvc-values-in-a-cve-record-and-turn-them-into-a-patch-decision/">Vulnrichment guide</a> explains how to read these fields.</p>
<h2 id="what-to-patch">What to patch</h2>
<p>Upgrade to one of these releases or later. Versions are from Atlassian&rsquo;s CVE record; Atlassian&rsquo;s Jira ticket says versions past end of life may also be affected, so an unsupported release needs a move to a fixed supported line, not a hunt for a patch.</p>
<table>
  <thead>
      <tr>
          <th>Product</th>
          <th>Fixed releases</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Jira Software Data Center</td>
          <td>9.12.40, 10.3.26, 11.3.12</td>
      </tr>
      <tr>
          <td>Jira Service Management Data Center</td>
          <td>5.12.40, 10.3.26, 11.3.12</td>
      </tr>
      <tr>
          <td>Confluence Data Center</td>
          <td>9.2.26, 10.2.19</td>
      </tr>
      <tr>
          <td>Bitbucket Data Center</td>
          <td>9.4.26, 10.2.8, 10.5.1</td>
      </tr>
      <tr>
          <td>Bamboo Data Center</td>
          <td>10.2.24, 12.1.12</td>
      </tr>
      <tr>
          <td>Crowd Data Center</td>
          <td>6.3.7, 7.0.3, 7.1.7, 7.2.4</td>
      </tr>
      <tr>
          <td>Crucible</td>
          <td>4.9.15</td>
      </tr>
      <tr>
          <td>Fisheye</td>
          <td>4.9.15</td>
      </tr>
  </tbody>
</table>
<p>Don&rsquo;t forget the quiet ones. Crowd and Bamboo often run on separate hosts owned by a different team, and Crowd is where the published credential-theft path lives.</p>
<h3 id="if-you-cannot-patch-today">If you cannot patch today</h3>
<p>Atlassian offers three interim mitigations, described in its per-product Jira tickets:</p>
<ol>
<li><strong>A WAF or reverse-proxy rule</strong> (all products) that blocks URLs where <code>..</code> sits next to <code>/</code>, <code>\</code> or <code>::</code>, including URL-encoded forms. Atlassian asks you to test that encoded variants are blocked.</li>
<li><strong>A Tomcat <code>RewriteValve</code></strong> (Confluence, Jira Software, Jira Service Management, Bamboo, Crowd): add <code>&lt;Valve className=&quot;org.apache.catalina.valves.rewrite.RewriteValve&quot; /&gt;</code> inside the application&rsquo;s <code>&lt;Context&gt;</code> in <code>conf/server.xml</code>, install Atlassian&rsquo;s <code>rewrite.config</code> under the application&rsquo;s <code>WEB-INF</code>, and restart each node in turn.</li>
<li><strong>A <code>urlrewrite.xml</code> rule</strong> for Bitbucket.</li>
</ol>
<p>Take the rule content from Atlassian&rsquo;s ticket for your product, not from a third-party blog. Atlassian is direct about the value: the mitigations are &ldquo;limited and not a replacement for patching.&rdquo; Where possible, remove unpatched instances from internet reach until they are upgraded.</p>
<h2 id="how-to-hunt">How to hunt</h2>
<p>Patching closes the hole; it does not tell you whether someone already read a file. Rapid7 recommends checking for compromise even after patching and describes a log search: decode each request line up to twice, then look for <code>..</code> directly next to <code>/</code>, <code>\</code> or <code>::</code>.</p>
<p>Here is a small implementation of that approach. It is <strong>our</strong> script, not Atlassian&rsquo;s published regex, and it will flag some benign requests. We ran it with Python 3 against a five-line synthetic log; the request paths in that test were made up to exercise the matcher and are not real exploit strings.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#75715e">#!/usr/bin/env python3</span>
</span></span><span style="display:flex;"><span><span style="color:#e6db74">&#34;&#34;&#34;Flag access-log lines with &#39;..&#39; next to &#39;/&#39;, &#39;</span><span style="color:#ae81ff">\\</span><span style="color:#e6db74">&#39; or &#39;::&#39; after up to two
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">rounds of URL decoding. Illustrates the approach Rapid7 describes for
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">CVE-2026-21589; it is not Atlassian&#39;s published regex.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">Usage: python3 scan_access_log.py access_log.txt&#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> re
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> sys
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> urllib.parse <span style="color:#f92672">import</span> unquote
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>PATTERN <span style="color:#f92672">=</span> re<span style="color:#f92672">.</span>compile(<span style="color:#e6db74">r</span><span style="color:#e6db74">&#34;(\.\.(/|</span><span style="color:#ae81ff">\\</span><span style="color:#e6db74">|::))|((/|</span><span style="color:#ae81ff">\\</span><span style="color:#e6db74">|::)\.\.)&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">suspicious</span>(line):
</span></span><span style="display:flex;"><span>    candidates <span style="color:#f92672">=</span> [line]
</span></span><span style="display:flex;"><span>    decoded <span style="color:#f92672">=</span> line
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">for</span> _ <span style="color:#f92672">in</span> range(<span style="color:#ae81ff">2</span>):
</span></span><span style="display:flex;"><span>        decoded <span style="color:#f92672">=</span> unquote(decoded)
</span></span><span style="display:flex;"><span>        candidates<span style="color:#f92672">.</span>append(decoded)
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> any(PATTERN<span style="color:#f92672">.</span>search(c) <span style="color:#66d9ef">for</span> c <span style="color:#f92672">in</span> candidates)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">with</span> open(sys<span style="color:#f92672">.</span>argv[<span style="color:#ae81ff">1</span>], errors<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;replace&#34;</span>) <span style="color:#66d9ef">as</span> f:
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">for</span> n, line <span style="color:#f92672">in</span> enumerate(f, <span style="color:#ae81ff">1</span>):
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> suspicious(line):
</span></span><span style="display:flex;"><span>            print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;</span><span style="color:#e6db74">{</span>n<span style="color:#e6db74">}</span><span style="color:#e6db74">: </span><span style="color:#e6db74">{</span>line<span style="color:#f92672">.</span>rstrip()<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span></code></pre></div><p>On the synthetic log it flagged a raw <code>::..::</code> request, a double-encoded <code>%252e%252e%252f</code> request and an encoded backslash variant, and ignored a filename containing <code>report..final</code>.</p>
<p>When you triage hits:</p>
<ul>
<li><strong>Start from October 5.</strong> Scan back at least to the advisory date; extend further if your logs allow, because the CVE record lists every release before the fixes as affected.</li>
<li><strong>Look at the status code and size.</strong> A <code>200</code> with a body on a traversal-shaped request deserves more attention than a <code>404</code>.</li>
<li><strong>Check every node and the proxy.</strong> In a Data Center cluster each node has its own Tomcat access log; a WAF or load balancer in front may log what the nodes did not.</li>
<li><strong>Note what the path aimed at.</strong> Requests for <code>WEB-INF</code> paths, configuration files or <code>.properties</code> files tell you which secrets to rotate.</li>
</ul>
<h2 id="if-a-read-may-have-succeeded">If a read may have succeeded</h2>
<p>Treat any secret in a web-root file as exposed, then contain and rotate in this order:</p>
<ol>
<li><strong>Crowd application credentials</strong> from <code>crowd.properties</code>, and review Crowd&rsquo;s application IP allowlists.</li>
<li><strong>Recently created users and group changes</strong>, especially additions to <code>jira-administrators</code> or other admin groups since October 5.</li>
<li><strong>Database credentials, API tokens and integration secrets</strong> held in configuration files the requests could have reached.</li>
<li><strong>Downstream systems</strong> those credentials unlock: build agents behind Bamboo, repositories behind Bitbucket, SSO-linked applications behind Crowd.</li>
</ol>
<p>Rapid7&rsquo;s advice matches: contain first, then rotate exposed credentials and secrets. If you work to US federal timelines, this flaw also falls under <a href="/posts/cisa-bod-26-04-explained-kev-deadlines-forensic-triage-and-what-private-teams-can-borrow/">BOD 26-04&rsquo;s forensic triage requirements</a>, which the required action of every KEV entry added in October cites.</p>
<h2 id="limits-of-this-article">Limits of this article</h2>
<p>We have not tested the vulnerability or Atlassian&rsquo;s mitigations. The root-cause details come from watchTowr&rsquo;s research as reported by Rapid7 and Help Net Security; we did not reach watchTowr&rsquo;s original post or Atlassian&rsquo;s main advisory page during research, and rely on the CVE record and Atlassian&rsquo;s public Jira tickets for versions and mitigations. No public source we found names the files requested in observed attacks.</p>
<h2 id="sources-and-verification">Sources and verification</h2>
<table>
  <thead>
      <tr>
          <th>Important claim</th>
          <th>Source</th>
          <th>Verification</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Description, eight products, unauthenticated web-root file read, no enumeration, CWE-552, CVSS 4.0 9.3 and vector, fixed releases, published October 5</td>
          <td><a href="https://www.cve.org/CVERecord?id=CVE-2026-21589">CVE-2026-21589 record</a> (read via the cvelistV5 repository)</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>SSVC: Exploitation active, Automatable no, Technical Impact total</td>
          <td>CISA ADP container in the CVE record</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>KEV addition October 15, due date October 18, BOD 26-04 forensic triage wording</td>
          <td><a href="https://www.cisa.gov/known-exploited-vulnerabilities-catalog">CISA KEV catalog</a> (JSON feed, catalog version 2026.10.21)</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Cloud already patched; WAF, RewriteValve and urlrewrite mitigations; &ldquo;limited and not a replacement for patching&rdquo;; EOL versions may be affected</td>
          <td><a href="https://jira.atlassian.com/browse/JRASERVER-79546">Atlassian JRASERVER-79546</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td><code>::</code> traversal root cause; web-root reads; crowd.properties to jira-administrators path; log-search approach</td>
          <td><a href="https://www.rapid7.com/blog/post/etr-cve-2026-21589-critical-unauthenticated-arbitrary-file-access-in-atlassian-products/">Rapid7 analysis</a> summarizing watchTowr</td>
          <td>Qualified: secondary account of watchTowr research</td>
      </tr>
      <tr>
          <td>Exploitation attempts reported by Previdian on October 6; watchTowr released a checker, not an exploit</td>
          <td><a href="https://www.helpnetsecurity.com/?p=387226">Help Net Security</a></td>
          <td>Qualified: Rapid7 reports public file-read PoCs</td>
      </tr>
  </tbody>
</table>
]]></content:encoded></item><item><title>BeyondTrust CVE-2026-102764: Patch, Then Hunt for SAWFLY</title><link>https://firewallsync.com/posts/beyondtrust-remote-support-cve-2026-102764-patch-and-hunt/</link><guid>https://firewallsync.com/posts/beyondtrust-remote-support-cve-2026-102764-patch-and-hunt/</guid><pubDate>Thu, 22 Oct 2026 18:41:00 +0000</pubDate><dc:creator>Craig Leslie</dc:creator><category>Security Operations</category><description>A BeyondTrust Remote Support authentication bypass was exploited as a zero-day from late August 2026. SaaS instances are patched; self-hosted appliances need the BT26-05-RS patch, and patching does not remove an attacker who is already in. Here is what to patch, what to hunt for and what to rotate.</description><enclosure url="https://firewallsync.com/posts/beyondtrust-remote-support-cve-2026-102764-patch-and-hunt/cover_hu10350490808426910252.jpg" type="image/jpeg" length="0"/><media:content url="https://firewallsync.com/posts/beyondtrust-remote-support-cve-2026-102764-patch-and-hunt/cover_hu10350490808426910252.jpg" medium="image" type="image/jpeg" width="1200" height="630"/><content:encoded><![CDATA[<p><img src="https://firewallsync.com/posts/beyondtrust-remote-support-cve-2026-102764-patch-and-hunt/cover_hu10350490808426910252.jpg" alt="A bright, empty data centre hall with black and white equipment cabinets under overhead trays of blue network cables" width="1200" height="630"></p><p>BeyondTrust Remote Support appliances running version 26.2.3 or earlier have an authentication bypass, CVE-2026-102764, that was exploited as a zero-day for about six weeks before it was disclosed. If you run a self-hosted appliance, apply the BT26-05-RS patch now. Then assume the appliance may have been compromised and check it, because the actor behind the attacks installed a web shell, a tunnel and a root backdoor that a patch does not remove.</p>
<p><strong>Scope.</strong> On October 22, 2026 we read the CVE record, the KEV catalog (version 2026.10.21), BeyondTrust&rsquo;s blog post on BT26-05 (last updated October 16), Google Threat Intelligence Group&rsquo;s analysis, the Canadian Centre for Cyber Security&rsquo;s alert AL26-025 and Rapid7&rsquo;s analysis. BeyondTrust&rsquo;s advisory page for BT26-05 did not load for us, so patch and version details below come from the CVE record, the Cyber Centre and Google, and we say so where it matters. We did not test the vulnerability.</p>
<h2 id="the-vulnerability">The vulnerability</h2>
<p>The CVE record, published by BeyondTrust on October 15, 2026, says internal components of Remote Support &ldquo;did not adequately validate the origin of the messages it received&rdquo;, which &ldquo;could allow an attacker to perform file operations on the appliance&rdquo;. It is classified as CWE-290, authentication bypass by spoofing, and affects Remote Support versions up to and including 26.2.3.</p>
<p>BeyondTrust scores it CVSS 4.0 9.3 (<code>AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H</code>): reachable over the network, no privileges, no user interaction. CISA&rsquo;s enrichment in the record rates it exploitation active, automatable yes, technical impact total. The Cyber Centre describes the impact as unauthorized file operations &ldquo;including arbitrary file uploads, potentially leading to full appliance compromise&rdquo;.</p>
<p>That combination matters more than the score. Remote Support appliances sit at the edge, broker privileged sessions into internal systems and can store credentials. An unauthenticated file upload on such a device is a direct path to the systems it administers.</p>
<h2 id="timeline">Timeline</h2>
<table>
  <thead>
      <tr>
          <th>Date (2026)</th>
          <th>Event</th>
          <th>Source</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>August 29</td>
          <td>The zero-day is used against one BeyondTrust-hosted Remote Support instance and one self-hosted appliance</td>
          <td>BeyondTrust; Google says &ldquo;late August&rdquo;</td>
      </tr>
      <tr>
          <td>September 28</td>
          <td>BeyondTrust finds activity on the hosted instance and contains it, it says within 27 minutes of first detection</td>
          <td>BeyondTrust</td>
      </tr>
      <tr>
          <td>September 30</td>
          <td>Mandiant shares findings from the self-hosted customer&rsquo;s investigation</td>
          <td>BeyondTrust</td>
      </tr>
      <tr>
          <td>October 8</td>
          <td>Patch released to SaaS and self-hosted customers</td>
          <td>BeyondTrust</td>
      </tr>
      <tr>
          <td>October 9</td>
          <td>SaaS tenants patched</td>
          <td>Google, Canadian Cyber Centre</td>
      </tr>
      <tr>
          <td>October 15</td>
          <td>Coordinated disclosure: CVE, BeyondTrust blog, Google analysis</td>
          <td>CVE record, BeyondTrust, Google</td>
      </tr>
      <tr>
          <td>October 16</td>
          <td>CISA adds the CVE to KEV; due date October 19; forensic triage required</td>
          <td>KEV catalog</td>
      </tr>
  </tbody>
</table>
<p>As of its last update on October 16, BeyondTrust said it knew of only those two affected customers and had seen no adversary activity since August. That is a statement about what BeyondTrust has observed, not a guarantee about every appliance.</p>
<h2 id="what-to-patch">What to patch</h2>
<table>
  <thead>
      <tr>
          <th>Deployment</th>
          <th>Action</th>
          <th>Source</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Remote Support SaaS</td>
          <td>No patch action; BeyondTrust says SaaS was patched automatically</td>
          <td>BeyondTrust, Cyber Centre, Google</td>
      </tr>
      <tr>
          <td>Self-hosted Remote Support 24.3.1 to 26.2.3</td>
          <td>Apply the BT26-05-RS patch (Google says from the <code>/appliance</code> interface)</td>
          <td>Cyber Centre, Google</td>
      </tr>
      <tr>
          <td>Self-hosted Remote Support older than 24.3.1</td>
          <td>Upgrade to a supported version, then apply the patch</td>
          <td>Cyber Centre, Google</td>
      </tr>
      <tr>
          <td>Self-hosted Privileged Remote Access</td>
          <td>Apply BeyondTrust&rsquo;s precautionary PRA patch; BeyondTrust found no exploit path in PRA</td>
          <td>BeyondTrust; Rapid7 says confirm the right patch with BeyondTrust Support</td>
      </tr>
  </tbody>
</table>
<p>The Cyber Centre also advises checking that automatic updates are enabled where appropriate. If you have more than one appliance, inventory them first; a forgotten secondary or lab instance is a common gap.</p>
<h2 id="what-the-attackers-did">What the attackers did</h2>
<p>Google Threat Intelligence Group attributes the exploitation to ARMORY CASTLE, &ldquo;a suspected PRC-nexus espionage threat actor (formerly tracked as UNC5221)&rdquo;. BeyondTrust attributes it, with moderate to high confidence, to the same group under its earlier name. Google&rsquo;s analysis describes:</p>
<ul>
<li><strong>SAWFLY</strong>, an obfuscated PHP web shell named <code>mangoapi.php</code>, placed under the appliance&rsquo;s Laravel <code>public</code> directory, that returns HTTP 404 unless a specific POST parameter (<code>_c94mfe</code>) is present.</li>
<li><strong>BARECLAW</strong>, a tunneler at <code>/tmp/ingredi_ws</code> providing a SOCKS5 proxy over WebSocket, listening on local TCP port 19800 and exposed through an added HAProxy route, <code>/uidchanarge</code>, in <code>/ns/config/haproxy.conf</code>.</li>
<li>A copy of <code>/bin/sh</code> at <code>/usr/bin/dbus-authd</code>, owned by root with the SUID bit set.</li>
<li>Persistence through <code>/home/bomgar/sbin/post_boot.d/zz-root-persist</code>, which adds a passwordless sudo rule to <code>/ns/config/sudoers.template</code> and rebuilds <code>/etc/sudoers</code>.</li>
<li>Deletion of logs on the appliance.</li>
</ul>
<p>Google publishes these SHA-256 hashes:</p>
<table>
  <thead>
      <tr>
          <th>File</th>
          <th>SHA-256</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>mangoapi.php</code> (SAWFLY)</td>
          <td><code>dc14e215269a93fdbc4c1a80b984c23faf7af0911c6dbb85309796a6f2ae95fb</code></td>
      </tr>
      <tr>
          <td><code>ingredi_ws</code> (BARECLAW)</td>
          <td><code>1f19b9a27d79c11bda00a1e8faf74a7fdd683d38ccef1b60df2fd0307e3aa462</code></td>
      </tr>
  </tbody>
</table>
<p>Rapid7 notes that customers cannot audit the appliance&rsquo;s host file system directly and should coordinate host-level inspection with BeyondTrust Support. BeyondTrust offers a threat-hunting package through its trust portal.</p>
<h2 id="how-to-hunt-without-relying-on-hashes">How to hunt without relying on hashes</h2>
<p>BeyondTrust warns that indicators from one victim &ldquo;rarely reappear at the next&rdquo; and that evidence stored only on the appliance may be missing or manipulated. Its blog and Google&rsquo;s analysis suggest hunting for behavior instead:</p>
<ul>
<li>Successful <code>/login</code> sessions from residential broadband or commercial VPN addresses, or outside business hours.</li>
<li><code>user_changed</code> events that raise Jump Item or team roles, and any unauthorized changes to accounts, permissions or session policies.</li>
<li>Requests to unknown <code>.php</code> paths, and WebSocket upgrades from unexpected sources.</li>
<li>Web service accounts spawning shells.</li>
<li>Gaps in syslog forwarding, especially gaps that start and end within one session.</li>
</ul>
<p>The last one depends on external logs. If the appliance does not already forward syslog and session events to a SIEM, BeyondTrust&rsquo;s advice is to start now; as Rapid7 points out, logging enabled today cannot recover evidence that was already deleted.</p>
<h2 id="if-an-appliance-may-be-compromised">If an appliance may be compromised</h2>
<p>Google&rsquo;s recommended order, condensed:</p>
<ol>
<li><strong>Preserve evidence first.</strong> Snapshot virtual appliances with memory, and collect syslog, reverse-proxy or WAF and firewall logs before reboots or changes.</li>
<li><strong>Contain.</strong> Block inbound traffic at the perimeter, restrict egress, end sessions, and disable, rather than delete, Jump Clients, Jumpoints and API accounts.</li>
<li><strong>Rebuild rather than clean.</strong> Redeploy from a clean, patched image, and restore only configuration backups from before the exposure window.</li>
<li><strong>Rotate credentials after patching or rebuilding</strong>, in dependency order: credentials in the vault and Password Safe, and any credential typed into a support session during the window. BeyondTrust adds: watch for unmanaged logins and review new MFA registrations on privileged accounts.</li>
<li><strong>Restrict the admin interfaces.</strong> Limit <code>/login</code> and <code>/appliance</code> by IP and require single sign-on with phishing-resistant MFA.</li>
</ol>
<p>If you find evidence of exploitation, BeyondTrust asks customers to open a severity 1 support case citing BT26-05.</p>
<p>For federal agencies, the KEV due date was October 19 and forensic triage is required; <a href="/posts/cisa-bod-26-04-explained-kev-deadlines-forensic-triage-and-what-private-teams-can-borrow/">our BOD 26-04 explainer</a> covers what that triage involves and what private teams can borrow from it. For how a KEV listing should outrank a score when you prioritize, see <a href="/posts/cvss-vs-epss-vs-kev-which-signal-should-decide-what-you-patch-first/">CVSS vs EPSS vs KEV</a>.</p>
<h2 id="limits-of-this-article">Limits of this article</h2>
<p>BeyondTrust&rsquo;s BT26-05 advisory page did not load for us; we relied on its blog post, the CVE record, Google and the Canadian Cyber Centre for versions and patch names. Rapid7&rsquo;s article is a secondary source and is used only for statements it attributes to BeyondTrust or Mandiant and for its own clearly labelled advice. Attribution and indicators are Google&rsquo;s and BeyondTrust&rsquo;s; we have not verified them. Details may change as the vendors update their guidance.</p>
<h2 id="sources-and-verification">Sources and verification</h2>
<p>Checked on October 22, 2026.</p>
<table>
  <thead>
      <tr>
          <th>Important claim</th>
          <th>Source</th>
          <th>Verification</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Description, CWE-290, affected up to 26.2.3, CVSS 4.0 9.3 and vector, published October 15</td>
          <td><a href="https://www.cve.org/CVERecord?id=CVE-2026-102764">CVE-2026-102764 record</a> (read via the cvelistV5 repository)</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>CISA SSVC: exploitation active, automatable, total impact</td>
          <td>CISA-ADP container in the CVE record</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>KEV: added October 16, due October 19, forensic triage Yes</td>
          <td><a href="https://www.cisa.gov/known-exploited-vulnerabilities-catalog">CISA KEV catalog</a>, version 2026.10.21</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Timeline (August 29 to October 15), two affected customers, PRA precautionary patch, SaaS auto-patched, hunting behaviors, rotation advice, Sev 1 case</td>
          <td><a href="https://beyondtrust.com/blog/entry/bt26-05">BeyondTrust: ARMORY CASTLE and BT26-05</a></td>
          <td>Verified against the vendor&rsquo;s blog</td>
      </tr>
      <tr>
          <td>Attribution, malware names, file paths, HAProxy route, hashes, response steps</td>
          <td><a href="https://cloud.google.com/blog/topics/threat-intelligence/armory-castle-exploits-beyondtrust">Google Threat Intelligence: ARMORY CASTLE Exploits BeyondTrust</a></td>
          <td>Qualified: Google&rsquo;s analysis, not independently verified</td>
      </tr>
      <tr>
          <td>BT26-05-RS patch for 24.3.1 to 26.2.3; upgrade first if older; SaaS patched October 9</td>
          <td><a href="https://cyber.gc.ca/en/alerts-advisories/al26-025-critical-vulnerability-impacting-beyondtrust-remote-support-cve-2026-102764">Canadian Centre for Cyber Security alert AL26-025</a> and Google</td>
          <td>Verified across two sources</td>
      </tr>
      <tr>
          <td>Host file system can&rsquo;t be audited directly; logs enabled now can&rsquo;t recover deleted evidence</td>
          <td><a href="https://www.rapid7.com/blog/post/etr-cve-2026-102764-critical-beyondtrust-remote-support-authentication-bypass-exploited-in-the-wild">Rapid7 analysis</a></td>
          <td>Qualified: secondary source</td>
      </tr>
  </tbody>
</table>
]]></content:encoded></item><item><title>Plex Media Server CVE-2026-96656 Chain: Patch and Hunt</title><link>https://firewallsync.com/posts/plex-media-server-cve-2026-96656-exploited-chain-patch-and-hunt/</link><guid>https://firewallsync.com/posts/plex-media-server-cve-2026-96656-exploited-chain-patch-and-hunt/</guid><pubDate>Thu, 22 Oct 2026 18:40:00 +0000</pubDate><dc:creator>John Marshall</dc:creator><category>Security Operations</category><description>Four Plex Media Server flaws fixed in 1.43.3.10861 are now in CISA's KEV catalog, and Plex says the chain is being widely exploited after a public proof of concept. Here is what each CVE does, which deadlines apply, and what to check if your server was exposed.</description><enclosure url="https://firewallsync.com/posts/plex-media-server-cve-2026-96656-exploited-chain-patch-and-hunt/cover_hu5450766343746298430.jpg" type="image/jpeg" length="0"/><media:content url="https://firewallsync.com/posts/plex-media-server-cve-2026-96656-exploited-chain-patch-and-hunt/cover_hu5450766343746298430.jpg" medium="image" type="image/jpeg" width="1200" height="630"/><content:encoded><![CDATA[<p><img src="https://firewallsync.com/posts/plex-media-server-cve-2026-96656-exploited-chain-patch-and-hunt/cover_hu5450766343746298430.jpg" alt="A strip of red film curling across a pale surface toward a dark film reel standing on its edge" width="1200" height="630"></p><p>Plex Media Server builds older than 1.43.3.10861 contain four vulnerabilities that the US Cybersecurity and Infrastructure Security Agency (CISA) added to its Known Exploited Vulnerabilities (KEV) catalog on October 20, 2026. Plex says that, chained together, they let an unauthenticated remote attacker run code on the server, and that exploitation is now wide. The fix has been available since September. If you run Plex anywhere, at home, in a lab or on a company network, update it, then check whether it was compromised before you updated.</p>
<p><strong>Scope.</strong> We read the four CVE records in the CVE List, CISA&rsquo;s machine-readable advisory VA-26-266-01, the KEV catalog (version 2026.10.21) and Plex&rsquo;s security thread on its forums, including the October 19, 2026 update, on October 22, 2026. We did not test the vulnerabilities or the proof of concept. For how KEV deadlines work, see <a href="/posts/cisa-bod-26-04-explained-kev-deadlines-forensic-triage-and-what-private-teams-can-borrow/">our explainer on BOD 26-04</a>.</p>
<h2 id="what-is-affected-and-what-fixes-it">What is affected and what fixes it</h2>
<p>Every one of the four CVE records lists Plex Media Server before 1.43.3.10861 as affected and 1.43.3.10861 as unaffected. CISA, acting as the CVE Numbering Authority, published the records and the advisory on September 23, 2026.</p>
<table>
  <thead>
      <tr>
          <th>CVE</th>
          <th>Weakness</th>
          <th>What the record says</th>
          <th>CVSS v3.1 / v4.0 (CVE record)</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>CVE-2026-96652</td>
          <td>SSRF (CWE-918)</td>
          <td>Any <code>X-Plex-Token</code> value lets an attacker put a full URL in the <code>protocol</code> parameter of <code>/player/timeline</code> and make the server POST to a destination of their choice</td>
          <td>4.3 / 5.3</td>
      </tr>
      <tr>
          <td>CVE-2026-96654</td>
          <td>URL injection (CWE-84)</td>
          <td>URL values in <code>searchOne</code> are not neutralized, so an attacker can call other plugins&rsquo; functions with their own parameters</td>
          <td>6.5 / 6.9</td>
      </tr>
      <tr>
          <td>CVE-2026-96655</td>
          <td>SSRF (CWE-918)</td>
          <td>An authenticated user can make the server request arbitrary internal or external addresses through the <code>/video/:/transcode/universal</code> path parameter</td>
          <td>4.3 / 5.3</td>
      </tr>
      <tr>
          <td>CVE-2026-96656</td>
          <td>File path control (CWE-73)</td>
          <td>An admin user can write files that may be executed on load. The <code>TranscoderH264Options</code> preference is appended verbatim to x264&rsquo;s options on every transcode, and at startup all <code>.so</code> files are loaded without signature, execute-bit or symbol checks</td>
          <td>7.2 / 8.6</td>
      </tr>
  </tbody>
</table>
<p>The individual scores look moderate. That is the trap: each score rates one flaw on its own, while the risk comes from the chain. Plex&rsquo;s update says that chained, the four &ldquo;allow an unauthenticated remote attacker&rdquo; to execute code as the server process. Plex has not published the chain step by step, and we have not reproduced it. Our reading of the CVE descriptions is that the request-forgery and injection flaws provide the access that the file-write flaw, which on its own needs admin rights, requires. Treat that as interpretation, not a confirmed sequence.</p>
<p>The same advisory lists a fifth flaw, CVE-2026-96651, a path traversal in <code>/system/agents/media/get</code> that can read files including the <code>PlexOnlineToken</code>, which the advisory says &ldquo;grants control of the Plex account and server&rdquo;. It is not in KEV, and CISA&rsquo;s enrichment dated September 23 records no exploitation. The same build fixes it.</p>
<h2 id="what-changed-from-routine-update-to-active-exploitation">What changed: from routine update to active exploitation</h2>
<table>
  <thead>
      <tr>
          <th>Date (2026)</th>
          <th>Event</th>
          <th>Source</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>September 1</td>
          <td>Plex posts a security notice telling users to update to Plex Media Server 1.43.3 and Plex Desktop 1.115.0</td>
          <td>Plex forum thread</td>
      </tr>
      <tr>
          <td>September 23</td>
          <td>CISA publishes the CVE records and advisory VA-26-266-01, fixed in 1.43.3.10861</td>
          <td>CVE records, CSAF advisory</td>
      </tr>
      <tr>
          <td>October 16</td>
          <td>A public proof of concept is released, according to Plex</td>
          <td>Plex forum update</td>
      </tr>
      <tr>
          <td>October 19</td>
          <td>Plex updates its notice: the flaws are &ldquo;being actively and widely exploited&rdquo;, attackers are installing cryptocurrency miners and proxy software, and unpatched internet-facing servers should be assumed compromised</td>
          <td>Plex forum update</td>
      </tr>
      <tr>
          <td>October 20</td>
          <td>CISA adds the four CVEs to KEV; its enrichment marks exploitation as active for all four</td>
          <td>KEV catalog, CVE records</td>
      </tr>
  </tbody>
</table>
<h3 id="kev-details">KEV details</h3>
<table>
  <thead>
      <tr>
          <th>CVE</th>
          <th>Added</th>
          <th>Due date (federal agencies)</th>
          <th>Forensic triage</th>
          <th>CISA SSVC: Automatable / Technical impact</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>CVE-2026-96652</td>
          <td>Oct 20</td>
          <td>Nov 3</td>
          <td>No</td>
          <td>No / Partial</td>
      </tr>
      <tr>
          <td>CVE-2026-96654</td>
          <td>Oct 20</td>
          <td>Oct 23</td>
          <td>No</td>
          <td>Yes / Partial</td>
      </tr>
      <tr>
          <td>CVE-2026-96655</td>
          <td>Oct 20</td>
          <td>Nov 3</td>
          <td>No</td>
          <td>No / Partial</td>
      </tr>
      <tr>
          <td>CVE-2026-96656</td>
          <td>Oct 20</td>
          <td>Oct 23</td>
          <td>Yes</td>
          <td>No / Total</td>
      </tr>
  </tbody>
</table>
<p>Each KEV entry says the flaw can be chained with the other three. The deadlines bind US federal civilian agencies under BOD 26-04; for everyone else they are a signal of urgency. CISA&rsquo;s catalog does not explain why two flaws got three days and two got fourteen.</p>
<h2 id="what-to-do-now">What to do now</h2>
<h3 id="1-update-and-confirm-the-build-number">1. Update and confirm the build number</h3>
<p>Update Plex Media Server to 1.43.3.10861 or later, then confirm the version under <strong>Settings → General</strong> in Plex Web, as Plex&rsquo;s notice describes. &ldquo;1.43.3&rdquo; alone is not enough to be sure: Plex&rsquo;s later update gives the full build number as the threshold. Plex also tells desktop users to update Plex Desktop.</p>
<h3 id="2-decide-whether-the-server-was-exposed">2. Decide whether the server was exposed</h3>
<p>Plex&rsquo;s guidance is that a server running an older build that was reachable from the internet &ldquo;may be compromised&rdquo;. Exposure usually came from Plex&rsquo;s Remote Access feature or a port forward. Plex specifically advises against forwarding port 32400 directly and suggests turning remote access off if you don&rsquo;t need it.</p>
<h3 id="3-look-for-the-signs-plex-lists">3. Look for the signs Plex lists</h3>
<p>Plex&rsquo;s October 19 update names these indicators:</p>
<ul>
<li>Processes you don&rsquo;t recognize running as the Plex user.</li>
<li>Unfamiliar <code>.so</code> (Linux) or <code>.dll</code> (Windows) files in the Plex <strong>Codecs</strong> folder.</li>
<li>Outbound connections to <code>proxystream.st</code>.</li>
<li>High CPU use while nothing is playing.</li>
<li>Transcoder options you did not set in <code>Preferences.xml</code>, which ties directly to CVE-2026-96656&rsquo;s <code>TranscoderH264Options</code> behavior.</li>
</ul>
<p>The location of the Codecs folder and <code>Preferences.xml</code> depends on your operating system and install method; Plex&rsquo;s support documentation lists them. A clean result is not proof of a clean server: these are the indicators Plex has published so far, and an attacker can remove files.</p>
<h3 id="4-if-you-find-something-or-cant-rule-it-out">4. If you find something, or can&rsquo;t rule it out</h3>
<p>Plex&rsquo;s update recommends rebuilding from a clean installation, clearing the Codecs folder and reviewing <code>Preferences.xml</code>. It also says to sign out of all devices and change the Plex account password, and to treat any network shares or credentials the Plex service account could reach as potentially exposed. Because CVE-2026-96651 can expose the server token, signing out all devices after updating is sensible even without other signs; Plex&rsquo;s notice does not explicitly address token rotation.</p>
<h3 id="for-companies">For companies</h3>
<p>If Plex appears in an asset inventory or scanner export, check for it on employee-run lab machines and NAS devices too. Media servers often run under accounts with broad read access to shared storage, which is what turns a hobby service into a foothold. Our guide to <a href="/posts/cisa-kev-json-feed-what-each-field-means-and-how-to-match-it-against-a-scanner-export/">matching the KEV feed against a scanner export</a> shows how to flag entries like these automatically. If you are new to SSRF, <a href="/posts/ssrf-explained-how-server-side-request-forgery-works-and-how-to-prevent-it/">our SSRF explainer</a> covers why &ldquo;make the server send a request&rdquo; is so often the first link in a chain.</p>
<h2 id="limits-of-this-article">Limits of this article</h2>
<p>We did not run the proof of concept or confirm the chain&rsquo;s steps. Plex&rsquo;s statements about exploitation, the proof-of-concept date and the indicators come from its forum post and are not independently verified. We did not read the researcher&rsquo;s write-up referenced in the CVE records. KEV entries and Plex&rsquo;s guidance may change; check the sources below for updates.</p>
<h2 id="sources-and-verification">Sources and verification</h2>
<p>Checked on October 22, 2026.</p>
<table>
  <thead>
      <tr>
          <th>Important claim</th>
          <th>Source</th>
          <th>Verification</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Affected versions (before 1.43.3.10861), descriptions, CWE and CVSS scores of the four CVEs; published September 23, 2026 by CISA as CNA</td>
          <td>CVE records <a href="https://www.cve.org/CVERecord?id=CVE-2026-96652">CVE-2026-96652</a>, <a href="https://www.cve.org/CVERecord?id=CVE-2026-96654">-96654</a>, <a href="https://www.cve.org/CVERecord?id=CVE-2026-96655">-96655</a>, <a href="https://www.cve.org/CVERecord?id=CVE-2026-96656">-96656</a> (CVE List, read via the cvelistV5 repository)</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Advisory VA-26-266-01: risk evaluation, fix in 1.43.3.10861, CVE-2026-96651 details</td>
          <td><a href="https://raw.githubusercontent.com/cisagov/CSAF/develop/csaf_files/IT/white/2026/va-26-266-01.json">CISA CSAF advisory VA-26-266-01</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>KEV additions on October 20, due dates, forensic triage flags, chaining note</td>
          <td><a href="https://www.cisa.gov/known-exploited-vulnerabilities-catalog">CISA KEV catalog</a>, version 2026.10.21 (JSON via cisagov/kev-data)</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>CISA SSVC values (exploitation active; automatable; technical impact)</td>
          <td>CISA-ADP containers in the CVE records</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>September 1 notice; October 19 update on wide exploitation, public proof of concept on October 16, indicators and remediation steps</td>
          <td><a href="https://forums.plex.tv/t/942319">Plex forum: Important Security Update for Plex Media Server v1.43.2 and earlier</a></td>
          <td>Qualified: vendor statements, not independently verified</td>
      </tr>
      <tr>
          <td>The chain&rsquo;s step-by-step mechanics</td>
          <td>Our reading of the CVE descriptions</td>
          <td>Qualified: not confirmed by Plex or reproduced</td>
      </tr>
  </tbody>
</table>
]]></content:encoded></item><item><title>What Is Token Theft and Why MFA Doesn't Always Stop It?</title><link>https://firewallsync.com/posts/what-is-token-theft-and-why-mfa-doesnt-always-stop-it/</link><guid>https://firewallsync.com/posts/what-is-token-theft-and-why-mfa-doesnt-always-stop-it/</guid><pubDate>Thu, 08 Oct 2026 09:00:00 +0000</pubDate><dc:creator>FirewallSync Editorial</dc:creator><category>Identity &amp; Access</category><description>MFA verifies who's logging in, not who's still using the session afterward. Token theft attacks steal what MFA leaves behind: the authenticated session itself.</description><enclosure url="https://firewallsync.com/posts/what-is-token-theft-and-why-mfa-doesnt-always-stop-it/cover_hu12907188549560242146.jpg" type="image/jpeg" length="0"/><media:content url="https://firewallsync.com/posts/what-is-token-theft-and-why-mfa-doesnt-always-stop-it/cover_hu12907188549560242146.jpg" medium="image" type="image/jpeg" width="1200" height="630"/><content:encoded><![CDATA[<p><img src="https://firewallsync.com/posts/what-is-token-theft-and-why-mfa-doesnt-always-stop-it/cover_hu12907188549560242146.jpg" alt="Padlock on a laptop with light trails" width="1200" height="630"></p><p>Multi-factor authentication verifies identity at the moment of login. It says nothing about what happens to the session afterward — and that gap is exactly what token theft attacks exploit. A user can enter their password, complete their MFA prompt correctly, and still hand an attacker full account access, because the thing worth stealing isn&rsquo;t the password or the MFA code anymore. It&rsquo;s the session token issued after both succeed.</p>
<h2 id="how-token-theft-actually-works">How token theft actually works</h2>
<p>The dominant technique is adversary-in-the-middle (AiTM) phishing, using open-source tooling such as Evilginx2, which Microsoft Threat Intelligence <a href="https://www.microsoft.com/en-us/security/blog/2022/07/12/from-cookie-theft-to-bec-attackers-use-aitm-phishing-sites-as-entry-point-to-further-financial-fraud/">documented in a July 12, 2022 report</a> on a campaign it said targeted more than 10,000 organizations from September 2021 and was followed by business email compromise fraud. The attacker doesn&rsquo;t build a fake login page — they proxy the real one. The victim lands on a domain that looks wrong on close inspection, but the page itself is the actual login flow, relayed through the attacker&rsquo;s server in real time.</p>
<p>The victim enters their real username and password, and completes MFA exactly as they normally would — push approval, OTP, whatever the org uses. The legitimate service verifies everything correctly and issues a session cookie or token, because as far as the identity provider is concerned, a real authentication just happened. The attacker&rsquo;s proxy captures that session token in transit before relaying the successful login back to the victim, who notices nothing wrong.</p>
<p>From that point, the attacker doesn&rsquo;t need the password or MFA again. They load the stolen session token directly into their own browser and are treated as an already-authenticated user — because they are one, technically, just not the one the identity provider thinks.</p>
<h2 id="why-traditional-mfa-doesnt-stop-this">Why traditional MFA doesn&rsquo;t stop this</h2>
<p>MFA that relies on a human relaying a value — typing an OTP, tapping &ldquo;approve&rdquo; on a push notification — is phishable by design, because nothing prevents that value from being captured and relayed through a proxy. The code or approval doesn&rsquo;t know which site it&rsquo;s being used on. Microsoft&rsquo;s report describes this as not being a flaw in MFA itself: the attacker obtains an authenticated session cookie, so access follows regardless of the sign-in method used. We have not verified how the technique behaves on specific platforms other than those in that report.</p>
<p>Phishing-resistant authentication (FIDO2/WebAuthn passkeys and security keys) closes this specific gap because the cryptographic challenge is bound to the actual domain — an AiTM proxy sitting on a different origin can&rsquo;t get a valid signed response out of it, even with a perfect visual clone of the login page. But phishing-resistant login doesn&rsquo;t retroactively protect a session token that&rsquo;s already been issued under older MFA methods, which is why detection matters as much as prevention. Microsoft&rsquo;s report recommends phish-resistant MFA (FIDO v2.0 and certificate-based) plus conditional access that evaluates signals such as device compliance and trusted IPs.</p>
<h2 id="what-detection-actually-needs-to-catch">What detection actually needs to catch</h2>
<p>Standard login monitoring looks for failed authentication attempts and unusual login locations. Token theft typically produces neither — the original login succeeded legitimately, and the attacker&rsquo;s subsequent access uses a valid token, not a new login attempt. What it does produce, if you&rsquo;re watching for it:</p>
<ul>
<li><strong>The same session token used from two meaningfully different locations or devices close together in time</strong> — not a new login, but continued use of an existing session from an inconsistent source</li>
<li><strong>Impossible travel on session activity, not just login events</strong> — a session that was active in one region and is suddenly active somewhere geographically implausible minutes later</li>
<li><strong>Anomalous behavior after a legitimate-looking login</strong> — mailbox rule changes, unusual OAuth app consent grants, or access patterns inconsistent with the user&rsquo;s normal activity, occurring shortly after a routine sign-in</li>
</ul>
<h2 id="what-actually-reduces-the-risk">What actually reduces the risk</h2>
<ul>
<li><strong>Shorten session and token lifetimes</strong> so a stolen token has a narrower window of usefulness before it expires and forces re-authentication</li>
<li><strong>Bind sessions to device and network signals</strong> where your identity provider supports it, so a token replayed from a different device or context gets challenged again rather than accepted silently</li>
<li><strong>Move toward phishing-resistant authentication</strong> for the accounts where a compromised session would matter most, since it removes the initial credential-and-code capture step the whole attack depends on</li>
<li><strong>Monitor session and token reuse patterns specifically</strong>, not just login failures — this is the signal that actually exists in this attack, and most detection stacks aren&rsquo;t tuned to look for it</li>
</ul>
<p>Token theft is a reminder that &ldquo;did MFA succeed&rdquo; and &ldquo;is this session legitimate right now&rdquo; are different questions. Most security programs have built strong controls around the first and comparatively little around the second, which is exactly the gap this attack class is built to walk through.</p>
]]></content:encoded></item><item><title>NetScaler CVE-2026-88779: Exploited SAML Flaw Needs Newer Builds Than Last Week's Zero-Day Fixes</title><link>https://firewallsync.com/posts/netscaler-cve-2026-88779-saml-denial-of-service-exploited-patched-last-weeks-zero-days/</link><guid>https://firewallsync.com/posts/netscaler-cve-2026-88779-saml-denial-of-service-exploited-patched-last-weeks-zero-days/</guid><pubDate>Tue, 06 Oct 2026 06:30:00 +0000</pubDate><dc:creator>FirewallSync Editorial</dc:creator><category>Security Operations</category><description>CVE-2026-88779 can knock SAML-configured NetScaler ADC and Gateway appliances offline and is on CISA's exploited list. The fixed builds are newer than the ones that fixed last week's two zero-days, so an appliance patched on September 27 can still be vulnerable.</description><enclosure url="https://firewallsync.com/posts/netscaler-cve-2026-88779-saml-denial-of-service-exploited-patched-last-weeks-zero-days/cover_hu15350512838332202912.jpg" type="image/jpeg" length="0"/><media:content url="https://firewallsync.com/posts/netscaler-cve-2026-88779-saml-denial-of-service-exploited-patched-last-weeks-zero-days/cover_hu15350512838332202912.jpg" medium="image" type="image/jpeg" width="1200" height="630"/><content:encoded><![CDATA[<p><img src="https://firewallsync.com/posts/netscaler-cve-2026-88779-saml-denial-of-service-exploited-patched-last-weeks-zero-days/cover_hu15350512838332202912.jpg" alt="Server rack with network cables attached" width="1200" height="630"></p><p>If you run Citrix NetScaler ADC or NetScaler Gateway with SAML authentication, check your build number today. CVE-2026-88779, a memory overflow that can take a SAML-configured appliance offline, is being exploited, and the fix is in builds newer than the ones Citrix shipped for last week&rsquo;s two zero-days. An appliance upgraded to 14.1-73.37 or 13.1-64.23 on or after September 27 is still inside the affected range.</p>
<p>This article separates what Citrix, CISA and the security researchers have each confirmed, because early reporting mixed denial of service with remote code execution. For the two earlier flaws, see our <a href="/posts/citrix-netscaler-zero-days-cve-2026-88771-cve-2026-88772-patch-and-hunt/">patch-and-hunt guide for CVE-2026-88771 and CVE-2026-88772</a>.</p>
<h2 id="what-is-confirmed">What is confirmed</h2>
<p>NetScaler, acting as its own CVE Numbering Authority (the organization authorized to assign and describe CVE IDs for its products), published the record for CVE-2026-88779 on October 4, 2026 at 02:35 UTC. The record&rsquo;s public date is 02:19 UTC on October 4, which is the evening of October 3 in US time zones. Sources that say Citrix published its bulletin, CTX697174, on &ldquo;October 3&rdquo; and the CVE record&rsquo;s &ldquo;October 4&rdquo; describe the same event in different time zones.</p>
<table>
  <thead>
      <tr>
          <th></th>
          <th>CVE-2026-88779</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Product</td>
          <td>NetScaler ADC and NetScaler Gateway (on-premises)</td>
      </tr>
      <tr>
          <td>Weakness</td>
          <td>Memory buffer bounds error (CWE-119, as classified by CISA), reported as a memory overflow leading to denial of service</td>
      </tr>
      <tr>
          <td>CVSS 4.0 base score</td>
          <td>8.7 (High); attack over the network, low complexity, no privileges, no user interaction; impact on availability only</td>
      </tr>
      <tr>
          <td>Affected builds</td>
          <td>ADC: before 14.1-73.41, before 13.1-64.28, before 14.1-73.41 FIPS, before 13.1-37.282. Gateway: before 14.1-73.41 and before 13.1-64.28</td>
      </tr>
      <tr>
          <td>Fixed in</td>
          <td>14.1-73.41, 13.1-64.28, 14.1-73.41 FIPS, 13.1-37.282 (FIPS and NDcPP ADC builds)</td>
      </tr>
      <tr>
          <td>Configuration condition</td>
          <td>Appliance configured as a SAML service provider or SAML identity provider, per watchTowr and The Hacker News</td>
      </tr>
      <tr>
          <td>CISA KEV added</td>
          <td>October 4, 2026; due date October 7, 2026</td>
      </tr>
  </tbody>
</table>
<p>CVSS (Common Vulnerability Scoring System) is the standard 0 to 10 severity scale; this score uses version 4.0. KEV is CISA&rsquo;s Known Exploited Vulnerabilities catalog.</p>
<h3 id="why-last-weeks-patch-level-is-not-enough">Why last week&rsquo;s patch level is not enough</h3>
<p>The earlier bulletin, CTX697096 of September 27, 2026, fixed CVE-2026-88771 through CVE-2026-88778 in builds 14.1-73.37 and 13.1-64.23 (and 14.1-73.37 FIPS and 13.1-37.279 for FIPS and NDcPP ADC). The new record uses &ldquo;before&rdquo; ranges that start higher:</p>
<table>
  <thead>
      <tr>
          <th>Branch</th>
          <th>Fixes the September 27 bulletin (CVE-2026-88771 to -88778)</th>
          <th>Fixes CVE-2026-88779 (October 3-4 bulletin)</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>14.1</td>
          <td>14.1-73.37</td>
          <td>14.1-73.41</td>
      </tr>
      <tr>
          <td>13.1</td>
          <td>13.1-64.23</td>
          <td>13.1-64.28</td>
      </tr>
      <tr>
          <td>14.1 FIPS</td>
          <td>14.1-73.37 FIPS</td>
          <td>14.1-73.41 FIPS</td>
      </tr>
      <tr>
          <td>13.1 FIPS and NDcPP (ADC only)</td>
          <td>13.1-37.279</td>
          <td>13.1-37.282</td>
      </tr>
  </tbody>
</table>
<p>An appliance on 14.1-73.37, for example, is earlier than 14.1-73.41, so the record lists it as affected. SecurityWeek reported that appliances already patched for the earlier flaws were hit; that matches the version arithmetic. The practical consequence is that &ldquo;we patched the NetScaler last week&rdquo; is no longer a complete answer, and the target build is the newer one.</p>
<p>Two limits apply. The Gateway records list only the 14.1 and 13.1 non-FIPS builds, which is why the FIPS builds are shown for ADC only. And we did not test any build; this is the reading of the published ranges.</p>
<h2 id="what-attackers-can-do-with-it-and-what-is-unconfirmed">What attackers can do with it, and what is unconfirmed</h2>
<p>The evidence supports one consequence: denial of service. CISA&rsquo;s catalog entry says the flaw &ldquo;could allow for a denial of service&rdquo;. Citrix said, as quoted by The Hacker News, that it observed targeted attacks on unmitigated deployments that can lead to denial of service, and that it had not identified an impact on the integrity of customer data. Help Net Security also quotes Citrix as saying that if the condition is triggered repeatedly, the service may remain unavailable.</p>
<p>Several details in early coverage deserve caution:</p>
<ul>
<li><strong>Remote code execution.</strong> Help Net Security says attackers reportedly attempt to download and install web shells. SOC Prime, citing SecurityWeek, describes authentication requests containing shell commands in username fields and a researcher&rsquo;s report of a malware binary downloaded on one honeypot. These are described as attempts. None of the sources we read shows code execution through CVE-2026-88779 itself. SecurityWeek reported that watchTowr concluded the flaw is a denial-of-service issue that can only crash systems. The earlier flaws, CVE-2026-88771 and CVE-2026-88772, are the ones for which web shell deployment has been documented, and some of that traffic may be aimed at them.</li>
<li><strong>Why attackers would crash appliances.</strong> watchTowr suspects, according to SecurityWeek, that crashing appliances may be intended to speed up exploitation of CVE-2026-88771. That is a researcher&rsquo;s hypothesis, not a confirmed attacker goal.</li>
<li><strong>A reboot after a set number of crashes.</strong> One summary we read claims the appliance reboots after a particular number of crashes. We could not confirm that in Citrix&rsquo;s or watchTowr&rsquo;s own text, so we are not repeating the number.</li>
<li><strong>Which flaw caused a given crash.</strong> Administrators told reporters that patched appliances were rebooting and that interim workarounds sometimes failed to stop the crashes, per SecurityWeek. Those are reports from the field, not measurements of a specific flaw.</li>
</ul>
<h3 id="what-cisas-data-says">What CISA&rsquo;s data says</h3>
<p>CISA added the flaw to KEV on October 4, 2026 with a due date of October 7, marked forensic triage as required, and listed ransomware campaign use as &ldquo;Unknown&rdquo;. The due date comes from Binding Operational Directive 26-04 and applies to US Federal Civilian Executive Branch agencies, not to private organizations; CISA encourages everyone to adopt the same risk-based approach.</p>
<p>CISA&rsquo;s own enrichment of the CVE record rates exploitation as &ldquo;active&rdquo;, the flaw as automatable by an attacker (&ldquo;yes&rdquo;), and technical impact as &ldquo;partial&rdquo;. The Exploit Prediction Scoring System (EPSS), a model that estimates the chance of exploitation in the next 30 days, gave the flaw 0.00534 (about 0.5%, 43rd percentile) on October 5, 2026. That number is low despite confirmed exploitation. Use it as a reminder that EPSS lags new disclosures, not as a reason to wait.</p>
<h2 id="what-to-do-in-order">What to do, in order</h2>
<p>This sequence is our recommendation, built on the vendor and researcher guidance cited above.</p>
<h3 id="1-establish-whether-saml-is-configured">1. Establish whether SAML is configured</h3>
<p>watchTowr says the condition is a SAML service provider or identity provider setup. WorkOS suggests searching the configuration file for the two relevant commands; the search itself changes nothing:</p>
<pre tabindex="0"><code>grep -E &#34;add authentication saml(Action|IdPProfile)&#34; /nsconfig/ns.conf
</code></pre><p>Run it from the appliance shell and read the result against the Citrix bulletin. A match means the appliance meets the described condition. No match is encouraging but the safe default is still to move to the fixed build, since every build you would choose in the next maintenance window should be at or above the newer ones.</p>
<h3 id="2-upgrade-to-the-new-fixed-build">2. Upgrade to the new fixed build</h3>
<p>Target 14.1-73.41 or later, or 13.1-64.28 or later (or the FIPS and NDcPP builds in the table above). Confirm exact build strings on Citrix&rsquo;s download page before upgrading FIPS or NDcPP appliances, because our earlier article noted inconsistent formatting of the 13.1 FIPS string in CVE records. Versions 12.1 and 13.0 are end-of-life, and we found no statement on whether they are affected; plan the migration rather than assuming they are not.</p>
<h3 id="3-apply-interim-mitigation-if-you-cannot-upgrade-today">3. Apply interim mitigation if you cannot upgrade today</h3>
<p>watchTowr and Help Net Security both point to Citrix&rsquo;s Global Deny List signatures, delivered through NetScaler Console, as the interim step; WorkOS also mentions responder policies available from Citrix Support. SecurityWeek&rsquo;s reporting that workarounds sometimes failed to stop the crashes means mitigation buys time and is not a substitute for the fixed build.</p>
<h3 id="4-look-for-crashes-then-for-what-came-with-them">4. Look for crashes, then for what came with them</h3>
<p>WorkOS lists crashes in <code>/var/log/ns.log</code> or <code>/var/log/messages</code>, repeated daemon restarts, &ldquo;Pitboss declaring system failure&rdquo; messages and unexplained reboots since late September as signs to look for. Help Net Security reports that Citrix offers an indicator-of-compromise script run through NetScaler Console. We did not run either.</p>
<p>A denial-of-service flaw should not close the investigation. If an appliance rebooted unexpectedly in the past two weeks, check it for the configuration theft and web shell activity described in our <a href="/posts/citrix-netscaler-zero-days-cve-2026-88771-cve-2026-88772-patch-and-hunt/">CVE-2026-88771 and CVE-2026-88772 article</a>. Preserve logs first; our piece on <a href="/posts/logging-for-incidents-not-for-dashboards/">logging for incidents</a> explains why off-box copies matter.</p>
<h3 id="5-decide-what-an-outage-costs-you">5. Decide what an outage costs you</h3>
<p>Many organizations authenticate staff to everything through the same NetScaler SAML configuration. A flaw that can crash it is an availability risk to every application behind it. Whether you can reach critical systems when the gateway is down is worth testing, and our <a href="/posts/the-vulnerability-backlog-that-never-shrinks/">vulnerability backlog</a> piece covers how to rank exposed and exploited items ahead of the rest. The general sequence for flaws attacked before a patch plan existed is in our <a href="/posts/what-is-a-zero-day-vulnerability-and-how-should-you-actually-respond-to-one/">zero-day response guide</a>.</p>
<h2 id="what-to-take-from-this">What to take from this</h2>
<p>Two security bulletins in under a week for one product means the version you recorded last week is stale. Track the fixed build per advisory, not &ldquo;patched&rdquo; as a status, and recheck the product&rsquo;s bulletin page after any exploited-flaw announcement before closing the ticket.</p>
<h2 id="sources-and-verification">Sources and verification</h2>
<p>Checked on October 6, 2026. We did not test the vulnerability, run any script or access a NetScaler appliance. Citrix&rsquo;s own bulletin pages (CTX697174 and the Citrix community post) returned an access error from our environment, so Citrix&rsquo;s statements are quoted through the CVE record, CISA data and the secondary reports named in the table.</p>
<table>
  <thead>
      <tr>
          <th>Important claim</th>
          <th>Source</th>
          <th>Verification</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Record published October 4, 2026 02:35 UTC; affects ADC before 14.1-73.41, 13.1-64.28, 14.1-73.41 FIPS and 13.1-37.282, and Gateway before 14.1-73.41 and 13.1-64.28</td>
          <td><a href="https://cveawg.mitre.org/api/cve/CVE-2026-88779">CVE record via the CVE Program API</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>CVSS 4.0 base score 8.7 (High), availability impact only; CWE-119</td>
          <td>Same CVE record</td>
          <td>Verified: score assigned by NetScaler; CWE assigned by CISA, not NetScaler</td>
      </tr>
      <tr>
          <td>CISA KEV added October 4, 2026; due October 7; forensic triage required; ransomware use unknown; description says it could allow denial of service</td>
          <td><a href="https://github.com/cisagov/kev-data/blob/main/known_exploited_vulnerabilities.json">CISA KEV data</a>, catalog version 2026.10.04; <a href="https://www.cisa.gov/news-events/alerts/2026/10/04/cisa-adds-one-known-exploited-vulnerability-catalog">CISA alert</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>BOD 26-04 applies to US federal civilian agencies; CISA encourages all organizations to adopt the approach</td>
          <td>CISA alert above</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>CISA enrichment: exploitation active, automatable yes, technical impact partial</td>
          <td>CVE record, CISA ADP section</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>September 27 bulletin fixed builds were 14.1-73.37 and 13.1-64.23</td>
          <td><a href="/posts/citrix-netscaler-zero-days-cve-2026-88771-cve-2026-88772-patch-and-hunt/">FirewallSync article on CVE-2026-88771 and CVE-2026-88772</a>, from NetScaler&rsquo;s CVE records</td>
          <td>Verified: our earlier reporting</td>
      </tr>
      <tr>
          <td>Condition: SAML service provider or identity provider</td>
          <td><a href="https://watchtowr.com/intelligence/citrix-netscaler-denial-of-service-memory-overflow-cve-2026-88779/">watchTowr, October 5, 2026</a>; <a href="https://thehackernews.com/2026/10/new-netscaler-zero-day-exploited-in.html">The Hacker News</a></td>
          <td>Qualified: not stated in NetScaler&rsquo;s CVE record</td>
      </tr>
      <tr>
          <td>Citrix: targeted attacks on unmitigated deployments can lead to denial of service; no impact on customer data integrity identified</td>
          <td>The Hacker News; <a href="https://www.securityweek.com/exploitation-of-citrix-netscaler-zero-day-hits-appliances-patched-days-earlier/">SecurityWeek</a></td>
          <td>Qualified: quoted second-hand; Citrix pages not accessible</td>
      </tr>
      <tr>
          <td>watchTowr concluded denial of service only; suspects use to speed exploitation of CVE-2026-88771</td>
          <td>SecurityWeek</td>
          <td>Qualified: researcher assessment and hypothesis</td>
      </tr>
      <tr>
          <td>Patched appliances reported rebooting; workarounds sometimes failed</td>
          <td>SecurityWeek</td>
          <td>Qualified: administrator reports</td>
      </tr>
      <tr>
          <td>Global Deny List signatures as interim mitigation</td>
          <td>watchTowr post; <a href="https://www.helpnetsecurity.com/2026/10/05/cisa-flags-new-exploited-netscaler-flaw-as-attackers-crash-appliances-cve-2026-88779/">Help Net Security, October 5, 2026</a></td>
          <td>Qualified: Citrix guidance not directly read</td>
      </tr>
      <tr>
          <td>Log indicators and configuration search command</td>
          <td><a href="https://workos.com/blog/netscaler-saml-zero-day-cve-2026-88779">WorkOS</a></td>
          <td>Qualified: third-party guidance, not run</td>
      </tr>
      <tr>
          <td>EPSS 0.00534 (43rd percentile) on October 5, 2026</td>
          <td><a href="https://api.first.org/data/v1/epss?cve=CVE-2026-88779">FIRST EPSS API</a></td>
          <td>Verified: figure changes daily</td>
      </tr>
  </tbody>
</table>
]]></content:encoded></item><item><title>Cisco Catalyst SD-WAN Manager CVE-2026-76504: Fixed Releases and Log Checks</title><link>https://firewallsync.com/posts/cisco-catalyst-sd-wan-manager-cve-2026-76504-authentication-bypass-fixed-releases-and-log-checks/</link><guid>https://firewallsync.com/posts/cisco-catalyst-sd-wan-manager-cve-2026-76504-authentication-bypass-fixed-releases-and-log-checks/</guid><pubDate>Mon, 05 Oct 2026 09:05:00 +0000</pubDate><dc:creator>FirewallSync Editorial</dc:creator><category>Security Operations</category><description>Cisco says an unauthenticated authentication bypass in Catalyst SD-WAN Manager is being exploited. There is no workaround, only upgrades, a temporary shield and a short list of log entries worth checking today.</description><enclosure url="https://firewallsync.com/posts/cisco-catalyst-sd-wan-manager-cve-2026-76504-authentication-bypass-fixed-releases-and-log-checks/cover_hu14211424645131340512.jpg" type="image/jpeg" length="0"/><media:content url="https://firewallsync.com/posts/cisco-catalyst-sd-wan-manager-cve-2026-76504-authentication-bypass-fixed-releases-and-log-checks/cover_hu14211424645131340512.jpg" medium="image" type="image/jpeg" width="1200" height="630"/><content:encoded><![CDATA[<p><img src="https://firewallsync.com/posts/cisco-catalyst-sd-wan-manager-cve-2026-76504-authentication-bypass-fixed-releases-and-log-checks/cover_hu14211424645131340512.jpg" alt="Fiber optic cables plugged into a network switch" width="1200" height="630"></p><p>If you run Cisco Catalyst SD-WAN Manager (formerly vManage) on your own infrastructure, you need to do two things today: confirm whether it is reachable from the internet, and look at two log files for requests that mention <code>j_security_check</code>. Cisco says the flaw, CVE-2026-76504, lets an unauthenticated attacker act as the <code>admin</code> user through the manager&rsquo;s API, and that its security team became aware of active exploitation in September 2026. The only remediation is a software upgrade.</p>
<h2 id="what-cisco-has-published">What Cisco has published</h2>
<p>Cisco published advisory <a href="https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-sdwan-webauth-xr8beuuU">cisco-sa-sdwan-webauth-xr8beuuU</a> on September 30, 2026. Version 1.1, dated October 2, 2026, added information about a temporary protection called Live Protect. Cisco rates it Critical.</p>
<table>
  <thead>
      <tr>
          <th></th>
          <th>CVE-2026-76504</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Product</td>
          <td>Cisco Catalyst SD-WAN Manager (the management and control interface for a Cisco SD-WAN network)</td>
      </tr>
      <tr>
          <td>Weakness</td>
          <td>Improper handling of URI encoding (CWE-177) in API session-based authentication</td>
      </tr>
      <tr>
          <td>Access needed</td>
          <td>None. The attacker does not need an account</td>
      </tr>
      <tr>
          <td>What the attacker gains</td>
          <td>Access to the API with the privileges of the <code>admin</code> user</td>
      </tr>
      <tr>
          <td>CVSS 3.1 base score</td>
          <td>9.8 (Critical), as assigned by Cisco</td>
      </tr>
      <tr>
          <td>Affected systems</td>
          <td>SD-WAN Manager &ldquo;regardless of system configuration&rdquo;</td>
      </tr>
      <tr>
          <td>Workaround</td>
          <td>None</td>
      </tr>
      <tr>
          <td>Exploitation</td>
          <td>Cisco PSIRT became aware of active exploitation in September 2026. The advisory gives no more precise date</td>
      </tr>
      <tr>
          <td>How it was found</td>
          <td>During the resolution of a Cisco Technical Assistance Center (TAC) support case</td>
      </tr>
  </tbody>
</table>
<p>CVSS (Common Vulnerability Scoring System) is the standard 0 to 10 severity scale; this score uses version 3.1.</p>
<p>Cisco describes the mechanism this way: improper handling of URI encoding in an HTTP request lets a request bypass an authentication rule meant to restrict access to a specific API endpoint. URI encoding replaces a character with a percent sign and two hexadecimal digits, so <code>j</code> can be written <code>%6a</code>. Cisco&rsquo;s description implies the check looks at the encoded form while the application later treats it as the plain character. That last step is our reading of the mechanism, not a statement in the advisory.</p>
<h2 id="which-releases-are-fixed">Which releases are fixed</h2>
<p>Cisco&rsquo;s advisory gives these first fixed releases:</p>
<table>
  <thead>
      <tr>
          <th>SD-WAN software release train</th>
          <th>First fixed release</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Earlier than 20.9</td>
          <td>Migrate to a fixed release</td>
      </tr>
      <tr>
          <td>20.9</td>
          <td>20.9.10.1</td>
      </tr>
      <tr>
          <td>20.12</td>
          <td>20.12.8.2</td>
      </tr>
      <tr>
          <td>20.15</td>
          <td>20.15.6.1</td>
      </tr>
      <tr>
          <td>20.18</td>
          <td>20.18.4.1</td>
      </tr>
      <tr>
          <td>26.1</td>
          <td>26.1.2.1</td>
      </tr>
      <tr>
          <td>26.2</td>
          <td>26.2.1</td>
      </tr>
  </tbody>
</table>
<p>Two points on reading this table. First, the table lists only these trains. If you run a train that is not in it, the advisory neither marks that train fixed nor says it is unaffected, and we could not find a Cisco statement on it. Treat it as unresolved and ask Cisco TAC rather than assume it is covered. Second, Cisco says it validates only the affected and fixed release information in the advisory, so use the advisory, not a scanner&rsquo;s interpretation of the CVE record, to decide.</p>
<p>For Cisco-hosted deployments, Cisco says the flaw is addressed in SD-WAN Cloud (Cisco Managed) release 20.15.605 with no customer action needed.</p>
<h2 id="the-live-protect-shield-what-it-is-and-is-not">The Live Protect shield: what it is and is not</h2>
<p>Cisco&rsquo;s October 2 update says it released a Live Protect shield for this CVE &ldquo;to provide temporary security coverage to allow time for software upgrade planning&rdquo;. Cisco is explicit about the limits: it &ldquo;offers only temporary partial protection&rdquo; and &ldquo;the only way to remediate this vulnerability is to upgrade to the first fixed software release&rdquo;. It also warns of a side effect: a legitimate user who uses URI encoding might not be able to log in to SD-WAN Manager once the shield is applied.</p>
<p>Our reading: use the shield, if you use it at all, to buy days while you schedule the upgrade, not as the end state. &ldquo;Partial&rdquo; means Cisco is not claiming it blocks every variant. Cisco&rsquo;s documentation for the feature is <a href="https://www.cisco.com/c/en/us/td/docs/routers/sdwan/26x-later/network-monitoring/network-monitoring-guide/live-protect-for-cisco-catalyst-sd-wan.html">Live Protect for Cisco Catalyst SD-WAN</a>. We did not test the shield.</p>
<h2 id="reduce-exposure-first">Reduce exposure first</h2>
<p>Cisco&rsquo;s mitigation for on-premises deployments is to restrict access from unsecured networks, including the internet. If you need internet access to the manager, Cisco says to restrict it to known, trusted hosts on the ports and protocols in its user guides, and to place the control components behind a filtering device such as a firewall. Cisco&rsquo;s advisory says managers &ldquo;exposed to the internet&rdquo; with ports exposed are at risk.</p>
<p>Practical steps that follow from that:</p>
<ul>
<li>Find out whether the manager&rsquo;s web and API ports are reachable from the internet. Check from outside your network, not from the configuration alone.</li>
<li>If they are, restrict them to a management network or a named allowlist before you do anything else. This does not fix the flaw, but it removes the unauthenticated attacker&rsquo;s path while you plan the upgrade.</li>
<li>Remember what the manager controls. SD-WAN Manager is the administrative plane for the WAN, so admin API access is access to the network&rsquo;s configuration. That is our assessment of impact, not a Cisco statement of what an attacker did.</li>
</ul>
<h2 id="check-for-exploitation">Check for exploitation</h2>
<p>Cisco says its indicators may also occur during normal operations, so assess them against your usual traffic. It names two files:</p>
<ol>
<li><strong><code>/var/log/nms/containers/service-proxy/serviceproxy-access.log</code>.</strong> Look for entries related to <code>j_security_check</code> from unknown or unauthorized IP addresses. Cisco&rsquo;s example is a <code>POST /%6a_security_check</code> request.</li>
<li><strong><code>/var/log/nms/vmanage-server.log</code>.</strong> Look for entries related to <code>j_security_check</code> from unknown or unauthorized IP addresses, specifically for users whose names start with <code>viptela-reserved-</code>. Cisco&rsquo;s example reads <code>Request Stored in Map is (/%6a_security_check) for user (viptela-reserved-..)</code>.</li>
</ol>
<p><code>viptela-reserved-</code> accounts are system service accounts that Cisco documents in the authentication section of its SD-WAN configuration guide. A request that authenticates as one of them from an outside address is the pattern Cisco is pointing to.</p>
<p>Cisco states the <code>%6a</code> form is only an example: &ldquo;the vulnerability will allow any one character that is encoded in the request to be used to exploit this.&rdquo; So searching for <code>%6a</code> alone will miss other variants. As an untested starting point (ours, not Cisco&rsquo;s), also list every request to the endpoint whose path contains a percent-encoded character:</p>
<pre tabindex="0"><code>grep -E &#39;POST /[^ ]*%[0-9A-Fa-f]{2}[^ ]*&#39; serviceproxy-access.log
</code></pre><p>Review the results against your normal logins. Expect some noise, because other legitimate requests can contain encoded characters.</p>
<p>Cisco&rsquo;s other guidance:</p>
<ul>
<li>To determine whether a system has been compromised, open a Cisco TAC case as Severity 3 with <code>CVE-2026-76504</code> in the title. Before opening it, run <code>request admin-tech</code> on the manager so the diagnostic file can go to TAC.</li>
<li>Cisco publishes Snort rule 67179 for this advisory, for teams that run Snort-based inspection in front of the manager.</li>
<li>Send manager logs to an external server and retain them long enough for investigations, which is also general hardening advice in the advisory. Our piece on <a href="/posts/logging-for-incidents-not-for-dashboards/">logging for incidents rather than dashboards</a> covers why.</li>
</ul>
<h2 id="upgrade-then-decide-what-else-to-rotate">Upgrade, then decide what else to rotate</h2>
<p>Cisco&rsquo;s advice is to upgrade to a fixed release as soon as possible. The advisory does not describe what an attacker with admin API access did in the observed attacks, and we found no public report that does. So the following is general incident response practice, not vendor guidance, and applies if your logs show a suspicious request:</p>
<ul>
<li>Treat the manager&rsquo;s configuration as readable and changeable by an outsider for the period of exposure. Review recent user, template and policy changes.</li>
<li>Rotate the administrator credentials and any API keys or integration credentials the manager holds.</li>
<li>Cisco&rsquo;s hardening list also says to change the default administrator password and to restrict the administrator account by creating named user accounts based on access needs. Do both if you have not.</li>
</ul>
<h2 id="what-the-cisa-entry-means">What the CISA entry means</h2>
<p>CISA added CVE-2026-76504 to its Known Exploited Vulnerabilities (KEV) catalog on September 30, 2026, the day Cisco published. The entry sets a due date of October 3, 2026, requires forensic triage, and lists ransomware campaign use as &ldquo;Unknown&rdquo;. CISA&rsquo;s enrichment data on the CVE record rates exploitation &ldquo;active&rdquo;, automatable &ldquo;yes&rdquo; and technical impact &ldquo;total&rdquo;. The due date comes from Binding Operational Directive 26-04 and applies to US Federal Civilian Executive Branch agencies; it does not bind private companies.</p>
<h2 id="what-this-adds-up-to">What this adds up to</h2>
<p>This section is editorial analysis.</p>
<p>CISA&rsquo;s catalog added Citrix NetScaler (September 27), this Cisco flaw (September 30), Fortinet FortiMail (October 1) and Zammad (October 2) within six days. They are different products and different bugs, but each is software reachable over the network that was already being exploited when the advisory appeared. We covered the <a href="/posts/fortimail-zero-day-cve-2026-104286-no-patch-yet-what-to-do/">FortiMail file-write zero-day</a>, the <a href="/posts/citrix-netscaler-zero-days-cve-2026-88771-cve-2026-88772-patch-and-hunt/">Citrix NetScaler zero-days</a> and the <a href="/posts/zammad-zero-days-cve-2026-102489-and-cve-2026-102490-what-is-fixed-and-what-is-not/">Zammad zero-days</a> separately. Three habits shorten the next response:</p>
<ul>
<li><strong>Keep management planes off the public internet.</strong> Cisco&rsquo;s own mitigation is this. If the only thing standing between the internet and admin access is a login check, one encoding bug removes it.</li>
<li><strong>Know your release train before the advisory arrives.</strong> The table above only helps if you can say in a minute which train you run.</li>
<li><strong>Ship manager logs off the box.</strong> Cisco&rsquo;s indicators are log lines. They are only useful if the logs exist and an intruder could not have edited them. For triage order, see <a href="/posts/what-is-a-zero-day-vulnerability-and-how-should-you-actually-respond-to-one/">what a zero-day is and how to respond to one</a> and <a href="/posts/the-vulnerability-backlog-that-never-shrinks/">the vulnerability backlog that never shrinks</a>.</li>
</ul>
<h2 id="sources-and-verification">Sources and verification</h2>
<p>Checked on October 5, 2026. We did not test the vulnerability, the Live Protect shield or the grep pattern on a Cisco SD-WAN Manager. We could not open CISA&rsquo;s website from our environment, so CISA data was read from CISA&rsquo;s published KEV data file and from CISA&rsquo;s entry embedded in the CVE record.</p>
<table>
  <thead>
      <tr>
          <th>Important claim</th>
          <th>Source</th>
          <th>Verification</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Unauthenticated remote attacker can gain admin-level API access via URI-encoding handling flaw; affects SD-WAN Manager regardless of configuration</td>
          <td><a href="https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-sdwan-webauth-xr8beuuU">Cisco advisory cisco-sa-sdwan-webauth-xr8beuuU</a>, first published September 30, 2026</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>CVSS 3.1 base score 9.8; CWE-177</td>
          <td>Cisco advisory; <a href="https://www.cve.org/CVERecord?id=CVE-2026-76504">CVE record</a>, updated October 2, 2026</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Cisco PSIRT became aware of active exploitation in September 2026</td>
          <td>Cisco advisory, Exploitation and Public Announcements</td>
          <td>Verified: no more precise date given</td>
      </tr>
      <tr>
          <td>First fixed releases 20.9.10.1, 20.12.8.2, 20.15.6.1, 20.18.4.1, 26.1.2.1, 26.2.1; earlier than 20.9 migrate</td>
          <td>Cisco advisory, Fixed Releases table</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>No fixed release is listed for trains not named in the table</td>
          <td>Cisco advisory, Fixed Releases table, as read October 5, 2026</td>
          <td>Qualified: absence of a listing, not a Cisco statement</td>
      </tr>
      <tr>
          <td>No workaround; mitigation is restricting access from unsecured networks; already deployed for cloud-hosted</td>
          <td>Cisco advisory</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Cloud (Cisco Managed) release 20.15.605 addresses the flaw</td>
          <td>Cisco advisory</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Live Protect shield added October 2, 2026; temporary, partial; may block legitimate URI-encoded logins</td>
          <td>Cisco advisory, version 1.1</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Log files and <code>j_security_check</code> / <code>viptela-reserved-</code> indicators; any single encoded character can be used</td>
          <td>Cisco advisory, Indicators of Compromise</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>TAC case at Severity 3 with CVE ID in title; run <code>request admin-tech</code> first; Snort rule 67179</td>
          <td>Cisco advisory</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Added to CISA KEV September 30, 2026; due October 3; forensic triage required; ransomware use unknown</td>
          <td><a href="https://github.com/cisagov/kev-data">CISA KEV data</a>, catalog version 2026.10.04</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>CISA rates exploitation active, automatable yes, technical impact total</td>
          <td>CISA ADP entry in the CVE record, dated September 30, 2026</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>BOD 26-04 binds US federal civilian agencies</td>
          <td><a href="https://www.tenable.com/blog/cisa-bod-26-04-FAQ-vulnerability-remediation-impact">Tenable analysis of BOD 26-04</a></td>
          <td>Qualified: secondary source</td>
      </tr>
  </tbody>
</table>
]]></content:encoded></item><item><title>Zammad Zero-Days CVE-2026-102489 and CVE-2026-102490: What Is Fixed and What Is Not</title><link>https://firewallsync.com/posts/zammad-zero-days-cve-2026-102489-and-cve-2026-102490-what-is-fixed-and-what-is-not/</link><guid>https://firewallsync.com/posts/zammad-zero-days-cve-2026-102489-and-cve-2026-102490-what-is-fixed-and-what-is-not/</guid><pubDate>Mon, 05 Oct 2026 09:00:00 +0000</pubDate><dc:creator>FirewallSync Editorial</dc:creator><category>Security Operations</category><description>Two Zammad flaws chained in the breach of the Dutch Institute for Vulnerability Disclosure are on CISA's exploited list. The sources disagree on which versions are safe, and no fix for the privilege-escalation flaw was visible as of October 5, 2026.</description><enclosure url="https://firewallsync.com/posts/zammad-zero-days-cve-2026-102489-and-cve-2026-102490-what-is-fixed-and-what-is-not/cover_hu4738225789966563780.jpg" type="image/jpeg" length="0"/><media:content url="https://firewallsync.com/posts/zammad-zero-days-cve-2026-102489-and-cve-2026-102490-what-is-fixed-and-what-is-not/cover_hu4738225789966563780.jpg" medium="image" type="image/jpeg" width="1200" height="630"/><content:encoded><![CDATA[<p><img src="https://firewallsync.com/posts/zammad-zero-days-cve-2026-102489-and-cve-2026-102490-what-is-fixed-and-what-is-not/cover_hu4738225789966563780.jpg" alt="Person wearing an earbud looking at code on a monitor" width="1200" height="630"></p><p>If you run Zammad, the helpdesk and ticketing system, check your version today. Anything on 6.5 or older is on a branch Zammad no longer patches and is the version range where the remote code execution flaw, CVE-2026-102489, can be used. Moving to Zammad 7.2.0, the version Zammad currently recommends, closes that path. It does not, on the evidence available as of October 5, 2026, settle the second flaw, CVE-2026-102490, which lets someone who already runs code as the <code>zammad</code> user become root.</p>
<p>This article separates what the CVE records, the discoverer, the vendor and CISA each say, because on this incident they do not fully agree.</p>
<h2 id="what-happened">What happened</h2>
<p>The Dutch Institute for Vulnerability Disclosure (DIVD) is a non-profit made up largely of volunteer security researchers. It was breached. In its public timeline for the incident (case DIVD-2026-00014), DIVD dates the first malicious access to September 21, 2026 and says it became aware of the activity on September 22. On September 30 it said the attackers got in through two previously unknown flaws in Zammad, an open-source helpdesk it ran, which it then tracked as CVE-2026-102489 and CVE-2026-102490. On October 1 it said volunteer data had been taken, including email addresses and possibly contact details.</p>
<p>DIVD also says the intrusion was run by an automated AI agent that chose each next step itself, and that the agent moved from the Zammad user to root &ldquo;in seconds&rdquo;. That is DIVD&rsquo;s own assessment from its forensic work with Merlon Security. We have not seen independent forensic evidence, and the trade press (Help Net Security) notes it is unknown whether this was part of a larger attack or a capability test. Treat the AI-agent description as DIVD&rsquo;s account.</p>
<p>DIVD&rsquo;s response gives a useful second detail. It says network segmentation and its incident team&rsquo;s actions stopped the attackers from going deeper into its systems.</p>
<h2 id="the-two-flaws">The two flaws</h2>
<table>
  <thead>
      <tr>
          <th></th>
          <th>CVE-2026-102489</th>
          <th>CVE-2026-102490</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Type</td>
          <td>Session hijack (CISA labels the weakness session fixation, CWE-384)</td>
          <td>Local privilege escalation (improper privilege management, CWE-269)</td>
      </tr>
      <tr>
          <td>What it gives an attacker</td>
          <td>Remote code execution as the <code>zammad</code> user</td>
          <td>Root on the server, starting from the <code>zammad</code> user</td>
      </tr>
      <tr>
          <td>Access needed</td>
          <td>No account; CVSS marks user interaction as &ldquo;passive&rdquo;</td>
          <td>Already running as the local <code>zammad</code> user</td>
      </tr>
      <tr>
          <td>Severity scored by DIVD (CVSS 4.0)</td>
          <td>8.7 High on its own</td>
          <td>8.5 High on its own</td>
      </tr>
      <tr>
          <td>Severity when chained</td>
          <td>9.4 Critical</td>
          <td>9.4 Critical</td>
      </tr>
      <tr>
          <td>Affected versions per CVE record</td>
          <td>6.3.0 up to 6.5.4 exploitable; 7.0.0 to 7.1.3 present but not exploitable</td>
          <td>1.5.0 up to 7.1.0-alpha; text says &ldquo;all versions&rdquo;</td>
      </tr>
      <tr>
          <td>CVE record published</td>
          <td>September 30, 2026</td>
          <td>September 30, 2026</td>
      </tr>
      <tr>
          <td>CISA KEV added</td>
          <td>October 2, 2026</td>
          <td>October 2, 2026</td>
      </tr>
  </tbody>
</table>
<p>CVSS (Common Vulnerability Scoring System) is the standard 0 to 10 severity scale. These scores use version 4.0 and were assigned by DIVD, which also acted as the CVE Numbering Authority, the body that issued these CVE IDs.</p>
<p>Two details in secondary coverage are easy to get wrong. Some reports say both flaws score 9.4. In DIVD&rsquo;s records, 9.4 is the score for the chain; each flaw alone scores lower. And one report describes an attack going &ldquo;from unauthenticated access to root&rdquo;. That is the chain, not a single flaw: the first needs no account, the second needs the foothold the first provides.</p>
<h3 id="where-the-sources-disagree">Where the sources disagree</h3>
<p><strong>Is there a fix?</strong> Help Net Security reported on October 1 that both flaws were &ldquo;currently without a fix&rdquo;. DIVD&rsquo;s case file lists patch status as &ldquo;Available&rdquo; with the recommendation &ldquo;Upgrade to Zammad version 7&rdquo;. Zammad&rsquo;s statement says CVE-2026-102489 does not affect current versions and that it hardened the code anyway in 7.2.0. These are not the same claim. The consistent reading is that 7.x removes the remote path for the first flaw, and no fix has been announced for the second.</p>
<p><strong>Affected versions.</strong> The CVE record&rsquo;s structured data lists CVE-2026-102489 as affected from 6.3.0 up to, but not including, 6.5.4. DIVD&rsquo;s case file and the record&rsquo;s own description say 6.3.0 to 6.5.4. A scanner that reads only the structured field could skip 6.5.4. Zammad&rsquo;s wording is broader still: &ldquo;6.5 and older&rdquo;. Use Zammad&rsquo;s range if you are deciding whether to act.</p>
<p><strong>How the flaw was disclosed.</strong> DIVD&rsquo;s case file says it reported the vulnerabilities to Zammad on September 24, 2026 and scanned for exposed instances and created a limited disclosure on September 26. Zammad says it first received a report about the session issue in August 2026, and that DIVD had not given it technical details of the second flaw until October 1. Zammad also wrote that it does &ldquo;not consider this a responsible way to handle vulnerabilities&rdquo;. We cannot reconcile the August report with DIVD&rsquo;s September 24 date from the public record, so we state both. For readers the practical point is the same: the CVE IDs were public before the vendor had published fixes or an advisory for the second flaw.</p>
<p><strong>How exploitable is the second flaw?</strong> DIVD&rsquo;s case file says it affects &ldquo;all versions&rdquo;. Zammad said on October 1 that it &ldquo;cannot be exploited remotely on its own. An attacker would already need access to your server.&rdquo; Both can be true: it matters most as the second step of a chain, which is exactly how it was used.</p>
<h2 id="what-cisa-says">What CISA says</h2>
<p>CISA added both CVEs to its Known Exploited Vulnerabilities (KEV) catalog on October 2, 2026. The entries set a due date of October 5, 2026, mark forensic triage as required, and list ransomware campaign use as &ldquo;Unknown&rdquo;. CISA&rsquo;s required action is to apply mitigations per vendor instructions or stop using the product if mitigations are unavailable. The due date comes from Binding Operational Directive 26-04 and applies to US Federal Civilian Executive Branch agencies, not to private organizations.</p>
<p>CISA&rsquo;s own enrichment data on the CVE records rates exploitation as &ldquo;active&rdquo; and technical impact as &ldquo;total&rdquo; for both. It rates the first flaw &ldquo;automatable: yes&rdquo; and the second &ldquo;automatable: no&rdquo;, which fits the difference above: one can be launched against many servers over the network, the other needs a foothold.</p>
<p>One data point worth knowing, with its limits. The Exploit Prediction Scoring System (EPSS), a model that estimates the probability a CVE will be exploited in the next 30 days, gave CVE-2026-102489 a score of 0.0140 (about 1.4%, 71st percentile) and CVE-2026-102490 0.0063 (about 0.6%, 48th percentile) on October 4, 2026. Exploitation has already been confirmed for both. A low EPSS number soon after disclosure reflects how little public data the model had, not safety. Do not use it to lower priority for a flaw on CISA&rsquo;s exploited list.</p>
<h2 id="what-to-do-in-order">What to do, in order</h2>
<p>This sequence is our recommendation, built on DIVD&rsquo;s, Zammad&rsquo;s and the Dutch NCSC&rsquo;s published advice as cited. Vendor advice is marked as such.</p>
<h3 id="1-find-every-zammad-instance-and-its-version">1. Find every Zammad instance and its version</h3>
<p>Include test, staging and forgotten copies. DIVD&rsquo;s recommendation covers any version, and its affected range for the root escalation begins at 1.5.0. Record whether each one is reachable from the internet.</p>
<h3 id="2-preserve-logs-before-you-upgrade">2. Preserve logs before you upgrade</h3>
<p>The Dutch National Cyber Security Centre (NCSC-NL) advised copying application and network logs before updating, because they may help you check later for abuse of the second flaw, as reported by Help Net Security. Do this first. Our piece on <a href="/posts/logging-for-incidents-not-for-dashboards/">logging for incidents rather than dashboards</a> covers why off-server copies matter.</p>
<h3 id="3-remove-the-remote-entry-point">3. Remove the remote entry point</h3>
<p>Zammad recommends moving to 7.2.0, released September 23, 2026 according to its release page. If you cannot upgrade today, DIVD&rsquo;s alternative is to take the instance offline. Our addition: if the helpdesk must stay up for staff, restrict it to a VPN or an allowlist of source addresses until you have upgraded. If you are on 6.5 or older, treat the upgrade as overdue regardless of this incident, since Zammad says those versions get no security fixes.</p>
<h3 id="4-check-for-compromise-even-after-upgrading">4. Check for compromise, even after upgrading</h3>
<p>DIVD published a log-check script for indicators of compromise, linked from its <a href="https://csirt.divd.nl/cases/DIVD-2026-00015/">case file</a>. We did not run it. Read any script before running it against production logs, and run it on a copy. A clean result lowers the likelihood of this specific activity. It does not prove a server was never accessed, and DIVD itself says it assumes breach until it can prove otherwise.</p>
<p>Upgrading after an intrusion does not remove an attacker who already has root. If the logs show suspicious sessions or code execution, plan a rebuild rather than a patch.</p>
<h3 id="5-assume-the-ticket-system-holds-more-than-tickets">5. Assume the ticket system holds more than tickets</h3>
<p>This part is analysis, not vendor guidance. A helpdesk typically stores customer emails and attachments, internal notes, and credentials for connected channels such as mailboxes and chat. If a server may have been reached, rotate those integration credentials and API tokens, and revoke active sessions. Our <a href="/posts/what-is-a-zero-day-vulnerability-and-how-should-you-actually-respond-to-one/">zero-day response guide</a> covers the general order of work.</p>
<h3 id="6-watch-for-the-second-fix">6. Watch for the second fix</h3>
<p>Follow Zammad&rsquo;s <a href="https://github.com/zammad/zammad/security/advisories">GitHub security advisories</a> for CVE-2026-102490. When a fixed version is named, that becomes the target, not &ldquo;version 7&rdquo; in general.</p>
<h2 id="the-lesson-that-does-not-depend-on-zammad">The lesson that does not depend on Zammad</h2>
<p>Two points from DIVD&rsquo;s account apply to any internal tool, offered here as our reading of it.</p>
<ul>
<li><strong>Low-severity entry points still matter when a second step exists.</strong> The first flaw lands on a service account with limited rights. The second turns that into root. Defenders who triage each CVE alone can underrate a chain. When two advisories name the same product on the same day, read them together.</li>
<li><strong>Segmentation is what limited the damage.</strong> DIVD credits it for stopping lateral movement. A ticketing server that can reach everything is a larger risk than the ticketing software itself.</li>
</ul>
<p>The same pattern of an edge or internal service exploited before a full patch plan existed appeared in the <a href="/posts/fortimail-zero-day-cve-2026-104286-no-patch-yet-what-to-do/">FortiMail zero-day</a> and the <a href="/posts/citrix-netscaler-zero-days-cve-2026-88771-cve-2026-88772-patch-and-hunt/">Citrix NetScaler zero-days</a> in recent days, and the <a href="/posts/the-vulnerability-backlog-that-never-shrinks/">vulnerability backlog</a> is where &ldquo;exposed and exploited&rdquo; should jump the queue.</p>
<h2 id="sources-and-verification">Sources and verification</h2>
<p>Checked on October 5, 2026. We did not test either vulnerability, run DIVD&rsquo;s script or install Zammad. We could not open Zammad&rsquo;s GitHub security advisories page or CISA&rsquo;s website from our environment, so CISA data was read from CISA&rsquo;s published KEV data file and from CISA&rsquo;s entries embedded in the CVE records.</p>
<table>
  <thead>
      <tr>
          <th>Important claim</th>
          <th>Source</th>
          <th>Verification</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>DIVD dates first malicious access to September 21, 2026; report to Zammad September 24; limited disclosure September 26</td>
          <td><a href="https://csirt.divd.nl/cases/DIVD-2026-00014/">DIVD case DIVD-2026-00014</a> and <a href="https://csirt.divd.nl/cases/DIVD-2026-00015/">DIVD-2026-00015</a></td>
          <td>Verified: DIVD&rsquo;s own timeline</td>
      </tr>
      <tr>
          <td>Attackers used CVE-2026-102489 and CVE-2026-102490; volunteer email addresses and possibly contact details taken</td>
          <td>DIVD case DIVD-2026-00014, statements of September 30 and October 1, 2026</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Attack was run by an AI agent</td>
          <td>DIVD case DIVD-2026-00014; <a href="https://www.helpnetsecurity.com/2026/10/01/divd-agentic-ai-attack-breach/">Help Net Security, October 1, 2026</a></td>
          <td>Qualified: DIVD&rsquo;s assessment; no independent forensic confirmation seen</td>
      </tr>
      <tr>
          <td>CVE-2026-102489: 6.3.0 to 6.5.4 exploitable; 7.0.0 to 7.1.3 present but not exploitable</td>
          <td><a href="https://www.cve.org/CVERecord?id=CVE-2026-102489">CVE record</a>, updated October 3, 2026; DIVD-2026-00015</td>
          <td>Qualified: structured data says &ldquo;before 6.5.4&rdquo;, text says &ldquo;to 6.5.4&rdquo;</td>
      </tr>
      <tr>
          <td>CVE-2026-102490: local zammad user to root; affects 1.5.0 up to 7.1.0-alpha</td>
          <td><a href="https://www.cve.org/CVERecord?id=CVE-2026-102490">CVE record</a>, updated October 3, 2026</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Scores: 8.7 and 8.5 individually, 9.4 chained (CVSS 4.0, assigned by DIVD)</td>
          <td>CVE records for both CVEs</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Zammad: 7.0 and later not affected by CVE-2026-102489; hardened in 7.2.0; 6.5 and older receive no security fixes</td>
          <td><a href="https://community.zammad.org/t/take-care-local-privilege-escalation-cve-2026-102490-is-reported-as-being-actively-exploited/21297/2">Zammad community statement, October 1, 2026</a></td>
          <td>Verified as Zammad&rsquo;s statement</td>
      </tr>
      <tr>
          <td>Zammad: CVE-2026-102490 cannot be exploited remotely on its own</td>
          <td>Zammad community thread, post of October 1, 2026</td>
          <td>Verified as Zammad&rsquo;s statement</td>
      </tr>
      <tr>
          <td>Zammad 7.2 released September 23, 2026</td>
          <td><a href="https://zammad.com/en/product/releases/7-2">Zammad 7.2 release page</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>No fix named for CVE-2026-102490</td>
          <td>Absence in the sources above as of October 5, 2026</td>
          <td>Qualified: GitHub advisories page could not be opened</td>
      </tr>
      <tr>
          <td>Both CVEs added to CISA KEV October 2, 2026; due October 5; forensic triage required; ransomware use unknown</td>
          <td><a href="https://github.com/cisagov/kev-data">CISA KEV data</a>, catalog version 2026.10.04</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>BOD 26-04 binds US federal civilian agencies</td>
          <td><a href="https://www.tenable.com/blog/cisa-bod-26-04-FAQ-vulnerability-remediation-impact">Tenable analysis of BOD 26-04</a></td>
          <td>Qualified: secondary source</td>
      </tr>
      <tr>
          <td>EPSS 0.01396 and 0.00629 on October 4, 2026; EPSS predicts 30-day exploitation probability</td>
          <td><a href="https://api.first.org/data/v1/epss?cve=CVE-2026-102489,CVE-2026-102490">FIRST EPSS API</a>; <a href="https://www.first.org/epss/faq">FIRST EPSS FAQ</a></td>
          <td>Verified: figures change daily</td>
      </tr>
      <tr>
          <td>NCSC-NL advised copying logs before updating</td>
          <td>Help Net Security, October 1, 2026</td>
          <td>Qualified: secondary report of NCSC-NL advice</td>
      </tr>
  </tbody>
</table>
]]></content:encoded></item><item><title>FortiMail CVE-2026-104286: Affected Builds, IBE Workaround</title><link>https://firewallsync.com/posts/fortimail-zero-day-cve-2026-104286-no-patch-yet-what-to-do/</link><guid>https://firewallsync.com/posts/fortimail-zero-day-cve-2026-104286-no-patch-yet-what-to-do/</guid><pubDate>Sun, 04 Oct 2026 06:30:00 +0000</pubDate><dc:creator>FirewallSync Editorial</dc:creator><category>Security Operations</category><description>Fortinet says an unauthenticated file-write flaw in FortiMail is being exploited, and as of October 4, 2026 its advisory still lists the fixed builds as upcoming. The workaround is one setting. The compromise check takes longer.</description><enclosure url="https://firewallsync.com/posts/fortimail-zero-day-cve-2026-104286-no-patch-yet-what-to-do/cover_hu7787959317508176642.jpg" type="image/jpeg" length="0"/><media:content url="https://firewallsync.com/posts/fortimail-zero-day-cve-2026-104286-no-patch-yet-what-to-do/cover_hu7787959317508176642.jpg" medium="image" type="image/jpeg" width="1200" height="630"/><content:encoded><![CDATA[<p><img src="https://firewallsync.com/posts/fortimail-zero-day-cve-2026-104286-no-patch-yet-what-to-do/cover_hu7787959317508176642.jpg" alt="Mail app icon showing a notification badge on a phone screen" width="1200" height="630"></p><p>If you run Fortinet FortiMail and the IBE service is switched on, switch it off today or take the webmail interface off the internet. Fortinet says the flaw tracked as CVE-2026-104286 is being exploited, and as of October 4, 2026 its advisory still describes the fixed builds as &ldquo;upcoming&rdquo;. Then check whether someone has already used it, because the attacks Fortinet describes change the appliance&rsquo;s mail archiving settings.</p>
<p>This article covers what Fortinet has confirmed, where the public records disagree with each other, and the order to work in.</p>
<h2 id="what-fortinet-disclosed">What Fortinet disclosed</h2>
<p>On October 1, 2026, Fortinet published advisory <a href="https://fortiguard.fortinet.com/psirt/FG-IR-26-175">FG-IR-26-175</a>. It describes the flaw as a path traversal weakness (CWE-22) combined with improper neutralization of a NULL byte (CWE-158) that &ldquo;may allow an unauthenticated attacker to write arbitrary files on the underlying system via crafted HTTP or HTTPS requests.&rdquo;</p>
<p>The advisory adds: &ldquo;This has been reported to be exploited in the wild, customers are urged to apply the workaround below.&rdquo;</p>
<table>
  <thead>
      <tr>
          <th></th>
          <th>CVE-2026-104286</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Product</td>
          <td>Fortinet FortiMail (email security gateway)</td>
      </tr>
      <tr>
          <td>Weakness</td>
          <td>Path traversal (CWE-22) and NULL byte handling (CWE-158)</td>
      </tr>
      <tr>
          <td>Access needed</td>
          <td>None. The attacker does not need an account</td>
      </tr>
      <tr>
          <td>What the attacker gains</td>
          <td>The ability to write arbitrary files on the appliance. Fortinet lists the impact as &ldquo;Execute unauthorized code or commands&rdquo;</td>
      </tr>
      <tr>
          <td>CVSS 3.1 base score</td>
          <td>9.8 (Critical), as assigned by Fortinet</td>
      </tr>
      <tr>
          <td>Advisory published</td>
          <td>October 1, 2026</td>
      </tr>
      <tr>
          <td>Found by</td>
          <td>Fortinet&rsquo;s own product security team, per the advisory</td>
      </tr>
  </tbody>
</table>
<p>CVSS (Common Vulnerability Scoring System) is the industry-standard 0 to 10 severity scale; this score uses version 3.1.</p>
<p>The workaround and the indicators both point at one feature: IBE, or identity-based encryption. Fortinet&rsquo;s administration guide describes it as a scheme that &ldquo;uses identities (such as email addresses) to calculate encryption keys.&rdquo; In practice it is the feature that lets FortiMail send an encrypted message to an outside recipient, who then opens it through a web link. That web-facing piece is what the workaround turns off.</p>
<p>Fortinet&rsquo;s advisory does not say whether IBE is enabled by default, and we could not confirm it from the documentation we read. Check your own configuration rather than assuming either way.</p>
<h3 id="affected-and-fixed-builds-according-to-fortinets-advisory">Affected and fixed builds, according to Fortinet&rsquo;s advisory</h3>
<table>
  <thead>
      <tr>
          <th>Branch</th>
          <th>Affected</th>
          <th>Fortinet&rsquo;s stated solution</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>FortiMail 8.0</td>
          <td>8.0.0 through 8.0.1</td>
          <td>Upgrade to upcoming 8.0.2 or above</td>
      </tr>
      <tr>
          <td>FortiMail 7.6</td>
          <td>7.6.0 through 7.6.6</td>
          <td>Upgrade to upcoming 7.6.7 or above</td>
      </tr>
      <tr>
          <td>FortiMail 7.4</td>
          <td>7.4.0 through 7.4.8</td>
          <td>Upgrade to upcoming 7.4.9 or above</td>
      </tr>
      <tr>
          <td>FortiMail 7.2</td>
          <td>7.2.0 through 7.2.9</td>
          <td>Upgrade to branch 7.4 or above</td>
      </tr>
  </tbody>
</table>
<p>We read the advisory on October 4, 2026. Its timeline showed a single entry, &ldquo;2026-10-01: Initial publication&rdquo;, and the solution column still used the word &ldquo;upcoming&rdquo;. We found no Fortinet statement giving a release date. That status can change at any time, so read the advisory itself before you plan around it.</p>
<p>Note what this means for the 7.2 branch: Fortinet lists no fixed 7.2 build. The stated path is a migration to 7.4 or later, which is a larger change than a patch release.</p>
<h2 id="the-cve-record-does-not-match-the-advisory">The CVE record does not match the advisory</h2>
<p>This is the part most likely to cause a wrong decision this week.</p>
<p>The <a href="https://www.cve.org/CVERecord?id=CVE-2026-104286">CVE record</a> is published by Fortinet as the CVE Numbering Authority (the organization authorized to describe CVE IDs for its own products). We retrieved it on October 4, 2026; it was last updated on October 2, 2026. It disagrees with the advisory, and with itself:</p>
<table>
  <thead>
      <tr>
          <th>Field</th>
          <th>8.0 branch</th>
          <th>7.6 branch</th>
          <th>7.4 branch</th>
          <th>7.2 branch</th>
          <th>7.0 branch</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Advisory FG-IR-26-175: affected</td>
          <td>8.0.0 to 8.0.1</td>
          <td>7.6.0 to 7.6.6</td>
          <td>7.4.0 to 7.4.8</td>
          <td>7.2.0 to 7.2.9</td>
          <td>Not listed</td>
      </tr>
      <tr>
          <td>CVE record, text description: affected</td>
          <td>8.0.0 to 8.0.1</td>
          <td>7.6.0 to 7.6.6</td>
          <td>7.4.0 to 7.4.8</td>
          <td>7.2.0 to 7.2.9</td>
          <td>Not listed</td>
      </tr>
      <tr>
          <td>CVE record, structured version data: affected</td>
          <td>8.0.0 only</td>
          <td>7.6.0 to 7.6.5</td>
          <td>7.4.0 to 7.4.6</td>
          <td>7.2.0 to 7.2.9</td>
          <td>7.0.0 to 7.0.9</td>
      </tr>
      <tr>
          <td>Advisory: fixed in</td>
          <td>8.0.2</td>
          <td>7.6.7</td>
          <td>7.4.9</td>
          <td>None (move to 7.4)</td>
          <td>Not listed</td>
      </tr>
      <tr>
          <td>CVE record, solutions field: fixed in</td>
          <td>8.0.1</td>
          <td>7.6.6</td>
          <td>7.4.8</td>
          <td>7.2.10</td>
          <td>Not listed</td>
      </tr>
  </tbody>
</table>
<p>The CVE record&rsquo;s solutions field also mentions FortiRecorder, a different product that the advisory does not mention at all.</p>
<p>Why this matters: vulnerability scanners and asset inventories usually match on the structured version data, not on the advisory text. A tool reading that data could report FortiMail 8.0.1, 7.6.6, 7.4.7 or 7.4.8 as not affected, while Fortinet&rsquo;s advisory lists all four as affected. The record&rsquo;s solutions field would also lead you to treat 7.6.6 as the fix when the advisory says 7.6.7.</p>
<p>We do not know which source Fortinet will correct. Until it does, the cautious reading is the advisory&rsquo;s wider range, plus the 7.0 branch that only the CVE record lists. If your scanner says a FortiMail build on these branches is clean, verify the build number by hand.</p>
<h2 id="what-attackers-have-been-doing">What attackers have been doing</h2>
<p>Fortinet&rsquo;s advisory lists indicators of compromise rather than a narrative, but the indicators tell a story. Three kinds of entry appear in the system event log examples it publishes:</p>
<ul>
<li>A scheduled job running as root: a log line beginning <code>msg=&quot;(root) CMD (/bin/sh -c 'O=/migadmin ...</code>, with <code>ui=cron</code>.</li>
<li>An administrator logout with no interface recorded: <code>msg=&quot;User admin logged out from (null).&quot;</code></li>
<li>A new mail archive account pointing off the appliance: <code>msg=&quot;Added 'archive234' to 'archive account'&quot;</code> with <code>destination[remote]</code>, <code>remote-ip[79.141.169.187]</code> and <code>remote-directory[/uploads]</code>.</li>
</ul>
<p>The third one is the consequence to worry about. An archive account with a remote destination sends copies of mail to another server. Beazley Security, summarizing the same indicators, describes &ldquo;attackers creating a remote mail archive account&rdquo; that &ldquo;sends archived mail&rdquo; to that address. For a mail gateway that sees an organization&rsquo;s inbound and outbound email, that is a continuing leak of message content, not a one-time break-in.</p>
<p>The advisory also lists two entries from the encryption logs: an IBE decryption error ending <code>'Invalid Base64 Encoding at pos 0. Character=0x2a'</code>, and a failed login for an internal user written as <code>*@domain.tld</code>.</p>
<p>Fortinet names two IP addresses: <code>79.141.169.187</code> and <code>45.129.0.192</code>. Attacker addresses change, so treat a match as strong evidence and a non-match as weak evidence.</p>
<p>Two security firms, Truesec and Beazley Security, additionally list files they say were added or modified on compromised appliances. Their lists overlap but are not identical. Beazley Security presents the files as Fortinet&rsquo;s indicators and publishes hashes for each; we did not see a file list in the advisory text we were able to read, so we attribute them to those firms:</p>
<table>
  <thead>
      <tr>
          <th>File</th>
          <th>Reported as</th>
          <th>Listed by</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>/data/lib/liblog.so</code></td>
          <td>Added</td>
          <td>Truesec, Beazley Security</td>
      </tr>
      <tr>
          <td><code>/data/bin/webconsole</code></td>
          <td>Added</td>
          <td>Truesec, Beazley Security</td>
      </tr>
      <tr>
          <td><code>/data/bin/mailservice</code></td>
          <td>Added</td>
          <td>Truesec, Beazley Security</td>
      </tr>
      <tr>
          <td><code>/data/etc/ld.so.preload</code></td>
          <td>Added</td>
          <td>Beazley Security</td>
      </tr>
      <tr>
          <td><code>/bin/smit</code></td>
          <td>Modified</td>
          <td>Truesec, Beazley Security</td>
      </tr>
      <tr>
          <td><code>/data/migadmin.tar.gz</code></td>
          <td>Modified</td>
          <td>Beazley Security</td>
      </tr>
      <tr>
          <td><code>/data/etc/httpd.conf</code></td>
          <td>Modified</td>
          <td>Beazley Security</td>
      </tr>
  </tbody>
</table>
<p>No source we read attributes the activity to a named group, gives a count of affected organizations, or says when exploitation began. CISA&rsquo;s catalog entry lists ransomware use as &ldquo;Unknown&rdquo;.</p>
<h2 id="what-to-do-in-order">What to do, in order</h2>
<h3 id="1-find-out-whether-you-are-exposed">1. Find out whether you are exposed</h3>
<p>Treat the appliance as exposed if it runs a build on the 8.0, 7.6, 7.4, 7.2 or 7.0 branch at or below the versions in the tables above and its web interface accepts requests from networks you do not control. Record the exact build number and whether the IBE service is on. Fortinet&rsquo;s advisory does not spell out the exact conditions for exploitation, so do not rule an appliance out on the IBE setting alone until you have confirmed it in the configuration.</p>
<h3 id="2-preserve-logs-before-you-change-the-configuration">2. Preserve logs before you change the configuration</h3>
<p>The indicators Fortinet published are log entries. Export the system event logs and encryption logs off the appliance first, and take a snapshot if FortiMail runs as a virtual machine. A compromised appliance can have its local logs altered, and a later upgrade or rebuild may discard them. Our piece on <a href="/posts/logging-for-incidents-not-for-dashboards/">logging for incidents rather than dashboards</a> covers why off-device copies matter.</p>
<h3 id="3-apply-the-workaround">3. Apply the workaround</h3>
<p>Fortinet&rsquo;s primary workaround is to disable IBE feature support. In the GUI, the advisory gives the path as Encryption, then IBE, then set IBE Service to off. From the CLI:</p>
<pre tabindex="0"><code>config system encryption ibe
set status disable
end
</code></pre><p>The trade-off is functional: with the service off, FortiMail stops providing IBE encrypted delivery. If your organization relies on it for outside recipients, tell the people who use it before you switch it off, and decide what they should use in the meantime.</p>
<p>The advisory lists two alternatives:</p>
<ul>
<li>Disable access to the FortiMail webmail interface from the internet, or limit access to a trusted private network.</li>
<li>If a web application firewall sits in front of FortiMail, block POST requests to <code>/ibe</code> that contain <code>../</code>.</li>
</ul>
<p>Our assessment, not Fortinet&rsquo;s: treat the firewall rule as the weakest of the three. A rule that matches the literal string <code>../</code> depends on how the firewall decodes and normalizes a request before matching, and this flaw involves a second trick (the NULL byte) alongside the traversal. Removing the exposed feature or the exposed interface does not depend on matching the attacker&rsquo;s exact input.</p>
<h3 id="4-check-for-compromise">4. Check for compromise</h3>
<p>Search the exported logs for the patterns above:</p>
<ul>
<li>Any archive account you did not create, especially one with a remote destination. <code>archive234</code> is the name in Fortinet&rsquo;s example; an attacker can choose a different one, so review every archive account, not only that name. Beazley Security gives the GUI location as Email Archiving, then Archive Account.</li>
<li>Cron entries running shell commands as root.</li>
<li>Administrator logouts recorded as coming from <code>(null)</code>.</li>
<li>IBE decryption errors mentioning <code>Invalid Base64 Encoding</code>.</li>
<li>Connections to or from <code>79.141.169.187</code> and <code>45.129.0.192</code> in firewall and proxy logs, not only on the appliance.</li>
</ul>
<p>If you have shell-level visibility through Fortinet support, compare against the file list above. A clean result lowers the likelihood of this specific activity. It does not prove the appliance is clean.</p>
<h3 id="5-if-you-find-indicators">5. If you find indicators</h3>
<p>Fortinet&rsquo;s advisory gives no recovery procedure, so this is general incident response practice rather than vendor guidance:</p>
<ul>
<li>Isolate the appliance and open a case with Fortinet support.</li>
<li>Remove the unauthorized archive account, and work out from its creation time in the logs how long mail was being copied. That period defines what may need to be reported under your breach notification obligations.</li>
<li>Rotate credentials the appliance holds or has seen: administrator passwords, LDAP bind accounts, API keys and TLS private keys.</li>
<li>Plan a rebuild from known good firmware rather than cleaning files by hand. Several of the reported files, including an <code>ld.so.preload</code> entry, are the kind used to reload attacker code after a restart.</li>
</ul>
<h3 id="6-upgrade-when-the-builds-ship">6. Upgrade when the builds ship</h3>
<p>Watch the advisory for the release of 8.0.2, 7.6.7 and 7.4.9, and upgrade when your branch is available. Keep the workaround in place until then. If you run 7.2, start planning the move to 7.4 now, since that is the only path the advisory gives.</p>
<h2 id="what-the-cisa-deadline-means-for-you">What the CISA deadline means for you</h2>
<p>CISA added CVE-2026-104286 to its Known Exploited Vulnerabilities (KEV) catalog on October 1, 2026, the same day Fortinet published. The catalog entry sets a due date of October 4, 2026 and marks forensic triage as required.</p>
<p>Two points of scope. First, the due date comes from Binding Operational Directive 26-04, which, according to Tenable&rsquo;s analysis of the directive, applies to US Federal Civilian Executive Branch agencies and is not binding on private companies. Second, the required action in the entry is to &ldquo;apply mitigations in accordance with vendor instructions&rdquo; or to &ldquo;discontinue use of the product if mitigations are unavailable.&rdquo; With the fixed builds listed as upcoming, the vendor instruction available today is the workaround.</p>
<p>For everyone outside the US federal government, read the three-day window as a statement of urgency, and note that CISA paired the mitigation with a compromise check. That is the same sequence as the steps above.</p>
<h2 id="the-pattern-worth-fixing-afterward">The pattern worth fixing afterward</h2>
<p>This section is editorial analysis rather than reported fact.</p>
<p>A mail gateway is an unusually valuable thing to compromise. It reads every message, it is trusted by the mail servers behind it, and it is expected to accept connections from anywhere. Three habits reduce the cost of the next advisory like this one:</p>
<ul>
<li><strong>Turn off web-facing features you do not use.</strong> The exposed surface here was one optional feature. An inventory of which optional services are enabled on each edge device turns &ldquo;are we affected?&rdquo; into a lookup.</li>
<li><strong>Alert on configuration changes that redirect data.</strong> A new archive destination, a new forwarding rule or a new administrator account on a mail system should raise an alert whoever makes the change.</li>
<li><strong>Do not let one data source decide exposure.</strong> This week the advisory and the CVE record disagree. A process that checks the vendor advisory for any actively exploited flaw would catch that.</li>
</ul>
<p>We covered the same patch-then-hunt sequence for a different edge device in <a href="/posts/citrix-netscaler-zero-days-cve-2026-88771-cve-2026-88772-patch-and-hunt/">the Citrix NetScaler zero-days</a>, and the general response order in <a href="/posts/what-is-a-zero-day-vulnerability-and-how-should-you-actually-respond-to-one/">what a zero-day is and how to respond to one</a>. For where this belongs in your queue, see <a href="/posts/the-vulnerability-backlog-that-never-shrinks/">the vulnerability backlog that never shrinks</a>.</p>
<h2 id="sources-and-verification">Sources and verification</h2>
<p>Checked on October 4, 2026. We did not test the workaround or the indicators on a FortiMail appliance; the commands and log patterns are quoted from Fortinet&rsquo;s advisory.</p>
<table>
  <thead>
      <tr>
          <th>Important claim</th>
          <th>Source</th>
          <th>Verification</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Unauthenticated attacker can write arbitrary files via crafted HTTP or HTTPS requests; exploited in the wild</td>
          <td><a href="https://fortiguard.fortinet.com/psirt/FG-IR-26-175">Fortinet advisory FG-IR-26-175</a>, published October 1, 2026</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Affected: 8.0.0 to 8.0.1, 7.6.0 to 7.6.6, 7.4.0 to 7.4.8, 7.2.0 to 7.2.9</td>
          <td>Fortinet advisory FG-IR-26-175</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Fixed builds 8.0.2, 7.6.7 and 7.4.9 described as upcoming</td>
          <td>Fortinet advisory FG-IR-26-175, as read October 4, 2026</td>
          <td>Qualified: status can change after this date</td>
      </tr>
      <tr>
          <td>Workaround: disable IBE; alternatives are restricting webmail access or a firewall rule</td>
          <td>Fortinet advisory FG-IR-26-175</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>CVSS 3.1 base score 9.8</td>
          <td><a href="https://www.cve.org/CVERecord?id=CVE-2026-104286">CVE record, Fortinet CNA</a>, updated October 2, 2026</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>CVE record lists different affected and fixed versions than the advisory, and adds the 7.0 branch</td>
          <td>CVE record as retrieved October 4, 2026, compared with the advisory</td>
          <td>Verified: describes the record on that date</td>
      </tr>
      <tr>
          <td>Log indicators and IP addresses 79.141.169.187 and 45.129.0.192</td>
          <td>Fortinet advisory FG-IR-26-175</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Added and modified files on compromised appliances</td>
          <td><a href="https://www.truesec.com/hub/blog/cve-2026-104286-fortimail-path-traversal-vulnerability-actively-exploited">Truesec</a>, <a href="https://beazley.security/alerts-advisories/critical-path-traversal-in-fortinet-fortimail-under-active-exploitation">Beazley Security</a></td>
          <td>Qualified: reported by these firms; not seen in the advisory text we read</td>
      </tr>
      <tr>
          <td>Added to CISA KEV October 1, 2026; due October 4, 2026; forensic triage required; ransomware use unknown</td>
          <td><a href="https://github.com/cisagov/kev-data">CISA KEV catalog data</a>, catalog version 2026.10.02</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>BOD 26-04 binds US federal civilian agencies only</td>
          <td><a href="https://www.tenable.com/blog/cisa-bod-26-04-FAQ-vulnerability-remediation-impact">Tenable&rsquo;s analysis of BOD 26-04</a></td>
          <td>Qualified: secondary source</td>
      </tr>
      <tr>
          <td>What IBE is</td>
          <td><a href="https://docs.fortinet.com/document/fortimail/7.4.2/administration-guide/286643">FortiMail administration guide, Configuring IBE encryption</a></td>
          <td>Verified</td>
      </tr>
  </tbody>
</table>
]]></content:encoded></item><item><title>Citrix NetScaler Zero-Days (CVE-2026-88771, CVE-2026-88772): Patch, Then Hunt</title><link>https://firewallsync.com/posts/citrix-netscaler-zero-days-cve-2026-88771-cve-2026-88772-patch-and-hunt/</link><guid>https://firewallsync.com/posts/citrix-netscaler-zero-days-cve-2026-88771-cve-2026-88772-patch-and-hunt/</guid><pubDate>Sat, 03 Oct 2026 08:00:00 +0000</pubDate><dc:creator>FirewallSync Editorial</dc:creator><category>Security Operations</category><description>Two NetScaler ADC and Gateway flaws were exploited before Citrix disclosed them on September 27, 2026. Upgrading closes the hole. It does not tell you whether someone already came through it.</description><enclosure url="https://firewallsync.com/posts/citrix-netscaler-zero-days-cve-2026-88771-cve-2026-88772-patch-and-hunt/cover_hu11562816909962696335.jpg" type="image/jpeg" length="0"/><media:content url="https://firewallsync.com/posts/citrix-netscaler-zero-days-cve-2026-88771-cve-2026-88772-patch-and-hunt/cover_hu11562816909962696335.jpg" medium="image" type="image/jpeg" width="1200" height="630"/><content:encoded><![CDATA[<p><img src="https://firewallsync.com/posts/citrix-netscaler-zero-days-cve-2026-88771-cve-2026-88772-patch-and-hunt/cover_hu11562816909962696335.jpg" alt="Fiber optic cables connected to a network switch in a server rack" width="1200" height="630"></p><p>If you run Citrix NetScaler ADC or NetScaler Gateway and are not yet on one of the fixed builds listed below, upgrade now. If the appliance was reachable from the internet at any point in September, also assume the upgrade is only half the job: both flaws were being exploited before Citrix disclosed them, and none of the vendor reports says an upgrade removes what attackers installed.</p>
<p>This article covers what is confirmed, where the vendor reports differ, and the order to work in.</p>
<h2 id="what-citrix-disclosed">What Citrix disclosed</h2>
<p>On September 27, 2026, Citrix published security bulletin <a href="https://support.citrix.com/support-home/kbsearch/article?articleNumber=CTX697096">CTX697096</a> covering eight vulnerabilities, CVE-2026-88771 through CVE-2026-88778. Two of them were already under attack. BleepingComputer quotes the bulletin as saying exploits of CVE-2026-88771 and CVE-2026-88772 &ldquo;on unmitigated NetScaler deployments have been observed.&rdquo;</p>
<p>The details below come from the CVE records that NetScaler itself published as the CVE Numbering Authority (the organization authorized to assign and describe CVE IDs for its own products).</p>
<table>
  <thead>
      <tr>
          <th></th>
          <th>CVE-2026-88771</th>
          <th>CVE-2026-88772</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Weakness</td>
          <td>Improper input validation (CWE-20)</td>
          <td>Memory buffer bounds error (CWE-119)</td>
      </tr>
      <tr>
          <td>Impact</td>
          <td>Unauthenticated attacker can execute arbitrary commands</td>
          <td>Remote code execution or denial of service</td>
      </tr>
      <tr>
          <td>CVSS 4.0 base score</td>
          <td>9.5 (Critical)</td>
          <td>9.5 (Critical)</td>
      </tr>
      <tr>
          <td>Attack complexity</td>
          <td>Low</td>
          <td>High</td>
      </tr>
      <tr>
          <td>Privileges required</td>
          <td>None</td>
          <td>None</td>
      </tr>
      <tr>
          <td>Record published</td>
          <td>September 27, 2026</td>
          <td>September 27, 2026</td>
      </tr>
  </tbody>
</table>
<p>CVSS (Common Vulnerability Scoring System) is the industry-standard 0 to 10 severity scale; these scores use version 4.0.</p>
<p>The other six CVEs in the bulletin, CVE-2026-88773 through CVE-2026-88778, carry CVSS 4.0 base scores between 7.0 and 9.3 in their CVE records. As of October 3, 2026, none of the six is in CISA&rsquo;s Known Exploited Vulnerabilities catalog. All eight records list the same fixed builds.</p>
<h3 id="affected-and-fixed-builds">Affected and fixed builds</h3>
<table>
  <thead>
      <tr>
          <th>Product branch</th>
          <th>Affected</th>
          <th>Fixed in</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>NetScaler ADC and Gateway 14.1</td>
          <td>Before 14.1-73.37</td>
          <td>14.1-73.37 and later</td>
      </tr>
      <tr>
          <td>NetScaler ADC and Gateway 13.1</td>
          <td>Before 13.1-64.23</td>
          <td>13.1-64.23 and later</td>
      </tr>
      <tr>
          <td>NetScaler ADC 14.1-FIPS</td>
          <td>Before 14.1-73.37 FIPS</td>
          <td>14.1-73.37 FIPS and later</td>
      </tr>
      <tr>
          <td>NetScaler ADC 13.1-FIPS and 13.1-NDcPP</td>
          <td>Before 13.1-37.279</td>
          <td>13.1-37.279 and later</td>
      </tr>
  </tbody>
</table>
<p>A formatting note: seven of the eight CVE records write the last build as &ldquo;13.1.37.279&rdquo;, while the record for CVE-2026-88773 and Tenable&rsquo;s summary write &ldquo;13.1-37.279&rdquo;, the format NetScaler build numbers normally use. We read these as the same build; confirm the exact build string on the Citrix download page before upgrading a FIPS or NDcPP appliance.</p>
<p>Versions 12.1 and 13.0 are end-of-life and receive no security updates. Tenable noted on September 27 that Citrix had not said whether they are affected. If you still run either, the absence of a statement is not evidence of safety; plan the migration rather than waiting for one.</p>
<h3 id="the-dtls-precondition">The DTLS precondition</h3>
<p>Rapid7 and Tenable both report that CVE-2026-88771 affects default configurations, while CVE-2026-88772 requires DTLS to be enabled. DTLS (Datagram Transport Layer Security) is TLS adapted for UDP, and NetScaler Gateway uses it on UDP port 443 alongside the usual TCP port 443.</p>
<p>That precondition narrows less than it sounds. <a href="https://docs.netscaler.com/en-us/netscaler-gateway/current-release/configure-dtls-virtual-server-using-ssl-virtual-server">NetScaler&rsquo;s own documentation</a> states: &ldquo;By default, the DTLS functionality is set to ON for the existing SSL VPN virtual server.&rdquo; Unless someone turned it off, a Gateway deployment meets the condition.</p>
<h2 id="what-is-known-about-exploitation">What is known about exploitation</h2>
<p>Three security vendors have published observations. They do not contradict each other, but each describes only what its own telemetry or incident response work showed, so the dates differ.</p>
<table>
  <thead>
      <tr>
          <th>Source</th>
          <th>What it reports</th>
          <th>Dates</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Palo Alto Networks Unit 42</td>
          <td>Requests that fingerprint NetScaler Gateway appliances</td>
          <td>From August 21, 2026</td>
      </tr>
      <tr>
          <td>Unit 42</td>
          <td>Repeated requests to files in the appliance&rsquo;s <code>/vpn/scripts/linux/</code> folder</td>
          <td>September 4 to 24, 2026</td>
      </tr>
      <tr>
          <td>Google Threat Intelligence Group and Mandiant</td>
          <td>Exploitation campaign against organizations in North America and Europe</td>
          <td>Since at least early September 2026</td>
      </tr>
      <tr>
          <td>Rapid7</td>
          <td>Earliest exploitation it reports: a command that archived the configuration directory into a web-readable path</td>
          <td>September 20, 2026, 14:28 UTC</td>
      </tr>
      <tr>
          <td>Unit 42</td>
          <td>PHP web shell dropped in three stages against a US-based target</td>
          <td>September 21, 2026</td>
      </tr>
  </tbody>
</table>
<p>The practical reading: the exposure window for an unpatched, internet-facing appliance opened weeks before the bulletin, not on the day of it. Unit 42 does not attribute the activity to a named group.</p>
<p>On scale, Unit 42 says its Cortex Xpanse scanning &ldquo;identified 50,277 exposed instances that could potentially be vulnerable&rdquo; as of September 27, 2026. That is a count of exposed appliances, not of confirmed compromises.</p>
<p>Tenable reported no public proof-of-concept exploit for either flaw as of September 27, 2026. Rapid7 reports that exploitation widened after disclosure. Treat the September 27 statement as a point in time, not a current guarantee.</p>
<h3 id="what-attackers-did-after-getting-in">What attackers did after getting in</h3>
<p>The behavior described by Google and Rapid7 explains why patching alone is not enough:</p>
<ul>
<li><strong>Configuration theft.</strong> Rapid7 observed <code>tar czf /var/netscaler/gui/vpn/c -C /flash nsconfig</code>, which packs the configuration directory into a location the web server will hand out. Rapid7 notes that directory holds encrypted administrator passwords, SSL certificates and private keys, and SSH host keys.</li>
<li><strong>Web shells behind innocent-looking extensions.</strong> Google documented changes to <code>/etc/httpd.conf</code> that make Apache run <code>.deb</code> and <code>.sig</code> files as PHP, plus an <code>AliasMatch</code> rule that maps <code>.ico</code> requests under <code>/vpn/media/</code> onto those files. The shells answer with HTTP 404, so they look like misses in a casual log review.</li>
<li><strong>Root persistence.</strong> Google observed <code>chmod u+s /bin/sh</code>, which sets the SUID bit so later web requests execute with root privileges.</li>
<li><strong>Tunneling into the network.</strong> Google named two tools: WHIPSHOT, a PHP web shell acting as a tunnel front end, and SLAPSHOT, a Python proxy that listens on a loopback port and records it in <code>/tmp/.uxdport</code>.</li>
</ul>
<h2 id="what-to-do-in-order">What to do, in order</h2>
<h3 id="1-preserve-evidence-before-you-change-anything">1. Preserve evidence before you change anything</h3>
<p>If the appliance is a virtual machine, take a snapshot that includes memory before rebooting or upgrading. Google recommends this explicitly, and <a href="https://support.citrix.com/external/article/CTX694799/steps-to-take-if-netscaler-adc-is-suspec.html">Citrix&rsquo;s guidance for a suspected compromise</a> lists a snapshot, a technical support bundle and a packet engine core dump as the first step. An upgrade reboots the device and discards memory-only evidence.</p>
<h3 id="2-upgrade-to-a-fixed-build">2. Upgrade to a fixed build</h3>
<p>Move to the fixed build for your branch from the table above. Google lists the upgrade as its recommended option and advises opening a Severity 1 support case with Citrix if you cannot locate the right build.</p>
<p>If you cannot upgrade immediately, Google describes compensating controls for CVE-2026-88772 only:</p>
<ul>
<li>Disable DTLS on internet-facing Gateway virtual servers where you do not need it. The documented command is <code>set vpn vserver &lt;name&gt; -dtls off</code>.</li>
<li>Block inbound UDP port 443 on the perimeter firewall or edge router. Google warns that ACLs on the appliance are not sufficient, because the traffic reaches the vulnerable packet engine first.</li>
</ul>
<p>Neither control addresses CVE-2026-88771. They buy time for one of the two bugs; they are not a substitute for the upgrade.</p>
<h3 id="3-hunt-for-compromise">3. Hunt for compromise</h3>
<p>Run these on the appliance shell. All commands are taken from <a href="https://cloud.google.com/blog/topics/threat-intelligence/defending-against-active-exploitation-of-citrix-netscaler-adc-and-gateway-appliances">Google&rsquo;s published hunting guidance</a>. A clean result reduces the likelihood of this specific tooling; it does not prove the device is clean.</p>
<p>Check for tampering in the web server configuration:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>grep -En -i <span style="color:#e6db74">&#34;application/x-httpd-php|php_flag|AliasMatch&#34;</span> /etc/httpd.conf
</span></span></code></pre></div><p>Look for handlers that register non-PHP extensions such as <code>.deb</code> or <code>.sig</code> as PHP, and for <code>AliasMatch</code> rules pointing <code>/vpn/media/</code>, <code>/vpn/theme/</code> or <code>/vpn/images/</code> at script directories.</p>
<p>Search the web directories for PHP where none belongs:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>grep -rlE <span style="color:#e6db74">&#34;&lt;\?php|eval\(|base64_decode\(|shell_exec\(&#34;</span> /var/netscaler/gui/ /netscaler/ns_gui/ /var/vpn/ /netscaler/portal/ 2&gt;/dev/null
</span></span></code></pre></div><p>Check for the tunneling tool&rsquo;s files, the SUID shell and stray Python processes:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>ls -la /tmp/.uxdport* /tmp/.uxdlock
</span></span><span style="display:flex;"><span>ls -l /bin/sh
</span></span><span style="display:flex;"><span>ps aux | grep -E <span style="color:#e6db74">&#34;python.*(\.uxd|uxdport|uxdlock|base64)&#34;</span>
</span></span></code></pre></div><p>Permissions of <code>-rwsr-xr-x</code> on <code>/bin/sh</code> indicate the SUID change. Either <code>/tmp/.uxd*</code> file means the proxy is running or ran recently.</p>
<p>Also check for two artifacts from Rapid7&rsquo;s report: a file at <code>/var/netscaler/gui/vpn/c</code>, which is the output path of the archive command it observed, and a web shell at <code>/var/netscaler/logon/LogonPoint/custom/.ctxs.receiver</code>.</p>
<p>In logs, Google flags two patterns worth alerting on. The first is a DTLS handshake failure with <code>ClientVersion DTLSv1.0</code> and the reason &ldquo;Handshake failure-Internal Error&rdquo;, followed within minutes by a crash of NSPPE (the NetScaler Packet Processing Engine) in <code>/var/log/messages</code>. The second is HTTP 404 responses to <code>/vpn/media/*.ico</code> that carry multi-kilobyte bodies.</p>
<p>Network indicators such as IP addresses and file hashes change quickly. Pull current lists from the <a href="https://cloud.google.com/blog/topics/threat-intelligence/defending-against-active-exploitation-of-citrix-netscaler-adc-and-gateway-appliances">Google</a>, <a href="https://www.rapid7.com/blog/post/etr-zero-day-exploitation-of-citrix-netscaler-adc-and-gateway-cve-2026-88771-and-cve-2026-88772/">Rapid7</a> and <a href="https://unit42.paloaltonetworks.com/netscaler-zero-days-exploited/">Unit 42</a> reports rather than a copy in an article. Google also publishes YARA rules for the web shells and the configuration tampering.</p>
<h3 id="4-if-you-find-anything-rebuild-rather-than-clean">4. If you find anything, rebuild rather than clean</h3>
<p>Citrix&rsquo;s guidance for a suspected compromise is to remove the appliance from the network, erase and reinstall firmware, upgrade to the latest version, and restore a known good backup that predates the compromise. Google adds one step that is easy to miss in a high-availability pair: disable HA synchronization and assess each node on its own, so a tampered configuration is not replicated to the healthy node.</p>
<p>Given the early September exploitation dates above, a &ldquo;known good&rdquo; backup should predate early September 2026 at a minimum, not merely the bulletin. That is our inference from the reported timeline, not vendor guidance.</p>
<h3 id="5-rotate-what-the-appliance-knew">5. Rotate what the appliance knew</h3>
<p>Because the configuration directory was a target, Google advises assuming credentials on a compromised appliance are exposed, and rotating them after the appliance is patched:</p>
<ul>
<li>NetScaler administrator and local account passwords, and SSH keys</li>
<li>TLS certificates and their private keys</li>
<li>LDAP bind and service accounts, RADIUS shared secrets, TACACS credentials</li>
<li>SNMP community strings and NITRO API credentials</li>
</ul>
<p>Invalidate active administrative, Gateway and VPN sessions as well. Citrix&rsquo;s guidance goes further on restored devices: rotate the Key Encryption Keys and replace all SSL certificates.</p>
<p>Then look downstream. Google recommends reviewing StoreFront servers, Delivery Controllers and virtual desktop hosts for unexpected interactive logons, RDP activity and signs of credential dumping, since the appliance sits directly in front of them.</p>
<h2 id="what-the-cisa-deadline-means-for-you">What the CISA deadline means for you</h2>
<p>CISA added both CVEs to its Known Exploited Vulnerabilities (KEV) catalog on September 27, 2026, with a due date of September 30, 2026. The catalog entry also requires forensic triage, noting that &ldquo;customers must conduct forensic triage as directed by BOD 26-04.&rdquo;</p>
<p>Two points of scope. First, according to Tenable&rsquo;s analysis of Binding Operational Directive 26-04, CISA issued the directive on June 10, 2026, it applies to US Federal Civilian Executive Branch agencies, and it is not binding on the private sector, though CISA encourages adoption. Second, the due date has already passed. For an organization outside the federal government, the deadline is useful as a signal: three days is the shortest remediation window in the directive as Tenable describes it, and CISA paired the patch with a mandatory compromise check, which is the same sequence recommended above.</p>
<h2 id="the-pattern-worth-fixing-after-the-incident">The pattern worth fixing after the incident</h2>
<p>This section is editorial analysis rather than reported fact.</p>
<p>Edge appliances are attractive targets for structural reasons: they face the internet by design, they hold credentials for the directory and authentication systems behind them, and most cannot run the endpoint detection agents that cover servers and laptops. Three changes reduce the cost of the next advisory of this kind:</p>
<ul>
<li><strong>Ship appliance logs off the device.</strong> The hunting steps above depend on <code>ns.log</code>, <code>/var/log/messages</code> and the HTTP access and error logs. Logs that live only on the appliance are available to whoever compromises it. Our piece on <a href="/posts/logging-for-incidents-not-for-dashboards/">logging for incidents rather than dashboards</a> covers what to retain.</li>
<li><strong>Default-deny outbound traffic from the appliance.</strong> Google recommends permitting only approved destinations such as DNS, NTP, certificate status checks and the backend applications. A tunneling tool is far less useful on a device that cannot open arbitrary connections.</li>
<li><strong>Keep management interfaces off the internet.</strong> Restrict the NSIP management address, SSH and the NITRO API to administrative networks.</li>
</ul>
<p>For triage of the rest of your queue, an actively exploited flaw on an internet-facing device is the case that should jump every line. We cover that prioritization in <a href="/posts/the-vulnerability-backlog-that-never-shrinks/">the vulnerability backlog that never shrinks</a>, and the general response sequence in <a href="/posts/what-is-a-zero-day-vulnerability-and-how-should-you-actually-respond-to-one/">what a zero-day is and how to respond to one</a>.</p>
<h2 id="sources-and-verification">Sources and verification</h2>
<p>Checked on October 3, 2026. We could not load the Citrix bulletin page directly, so bulletin details are taken from the CVE records NetScaler published and from vendors quoting the bulletin; those rows are marked Qualified.</p>
<table>
  <thead>
      <tr>
          <th>Important claim</th>
          <th>Source</th>
          <th>Verification</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>CVE-2026-88771 lets an unauthenticated attacker execute arbitrary commands; CVSS 4.0 base score 9.5</td>
          <td><a href="https://www.cve.org/CVERecord?id=CVE-2026-88771">CVE record, NetScaler CNA</a>, published September 27, 2026</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>CVE-2026-88772 can lead to remote code execution or denial of service; CVSS 4.0 base score 9.5</td>
          <td><a href="https://www.cve.org/CVERecord?id=CVE-2026-88772">CVE record, NetScaler CNA</a>, published September 27, 2026</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Fixed builds: 14.1-73.37, 13.1-64.23, 14.1-73.37 FIPS, 13.1-37.279 FIPS/NDcPP</td>
          <td>Same CVE records</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Citrix states exploitation of both CVEs has been observed</td>
          <td>Bulletin <a href="https://support.citrix.com/support-home/kbsearch/article?articleNumber=CTX697096">CTX697096</a>, as quoted by <a href="https://www.bleepingcomputer.com/news/security/citrix-admins-warned-to-shut-down-netscalers-over-2-exploited-zero-days/">BleepingComputer</a></td>
          <td>Qualified: quoted secondhand</td>
      </tr>
      <tr>
          <td>CVE-2026-88772 requires DTLS to be enabled</td>
          <td>Bulletin, as reported by <a href="https://www.rapid7.com/blog/post/etr-zero-day-exploitation-of-citrix-netscaler-adc-and-gateway-cve-2026-88771-and-cve-2026-88772/">Rapid7</a> and <a href="https://www.tenable.com/blog/frequently-asked-questions-about-reported-citrix-netscaler-zero-day-vulnerabilities">Tenable</a></td>
          <td>Qualified: reported secondhand</td>
      </tr>
      <tr>
          <td>DTLS is on by default for an SSL VPN virtual server</td>
          <td><a href="https://docs.netscaler.com/en-us/netscaler-gateway/current-release/configure-dtls-virtual-server-using-ssl-virtual-server">NetScaler Gateway documentation</a></td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>Both CVEs added to CISA KEV on September 27, 2026, due September 30, 2026</td>
          <td><a href="https://www.cisa.gov/known-exploited-vulnerabilities-catalog?field_cve=CVE-2026-88771">CISA KEV catalog</a>, catalog version 2026.10.02</td>
          <td>Verified</td>
      </tr>
      <tr>
          <td>BOD 26-04 binds US federal civilian agencies only</td>
          <td><a href="https://www.tenable.com/blog/cisa-bod-26-04-FAQ-vulnerability-remediation-impact">Tenable analysis of BOD 26-04</a></td>
          <td>Qualified: secondary source</td>
      </tr>
      <tr>
          <td>Exploitation activity predates disclosure</td>
          <td><a href="https://cloud.google.com/blog/topics/threat-intelligence/defending-against-active-exploitation-of-citrix-netscaler-adc-and-gateway-appliances">Google</a>, <a href="https://www.rapid7.com/blog/post/etr-zero-day-exploitation-of-citrix-netscaler-adc-and-gateway-cve-2026-88771-and-cve-2026-88772/">Rapid7</a>, <a href="https://unit42.paloaltonetworks.com/netscaler-zero-days-exploited/">Unit 42</a></td>
          <td>Qualified: each vendor reports its own visibility; dates differ</td>
      </tr>
      <tr>
          <td>50,277 exposed instances potentially vulnerable</td>
          <td><a href="https://unit42.paloaltonetworks.com/netscaler-zero-days-exploited/">Unit 42</a>, as of September 27, 2026</td>
          <td>Qualified: one vendor&rsquo;s scan, exposure not compromise</td>
      </tr>
      <tr>
          <td>Hunting commands and post-exploitation behavior</td>
          <td><a href="https://cloud.google.com/blog/topics/threat-intelligence/defending-against-active-exploitation-of-citrix-netscaler-adc-and-gateway-appliances">Google Threat Intelligence Group and Mandiant</a>, September 29, 2026</td>
          <td>Verified against the source; not run by us</td>
      </tr>
      <tr>
          <td>Steps for a suspected compromise</td>
          <td><a href="https://support.citrix.com/external/article/CTX694799/steps-to-take-if-netscaler-adc-is-suspec.html">Citrix CTX694799</a></td>
          <td>Verified</td>
      </tr>
  </tbody>
</table>
<p>FirewallSync has not tested these vulnerabilities or run the hunting commands against a compromised appliance. This is research-based analysis of the sources above.</p>
]]></content:encoded></item><item><title>Logging for Incidents, Not for Dashboards</title><link>https://firewallsync.com/posts/logging-for-incidents-not-for-dashboards/</link><guid>https://firewallsync.com/posts/logging-for-incidents-not-for-dashboards/</guid><pubDate>Wed, 30 Sep 2026 09:00:00 +0000</pubDate><dc:creator>FirewallSync Editorial</dc:creator><category>Security Operations</category><description>Most logging strategies optimize for building dashboards, then fail the one test that matters: can you reconstruct what happened during an actual incident?</description><enclosure url="https://firewallsync.com/posts/logging-for-incidents-not-for-dashboards/cover_hu14905193143568732667.jpg" type="image/jpeg" length="0"/><media:content url="https://firewallsync.com/posts/logging-for-incidents-not-for-dashboards/cover_hu14905193143568732667.jpg" medium="image" type="image/jpeg" width="1200" height="630"/><content:encoded><![CDATA[<p><img src="https://firewallsync.com/posts/logging-for-incidents-not-for-dashboards/cover_hu14905193143568732667.jpg" alt="Computer screen filled with data" width="1200" height="630"></p><p>Most logging strategies get built to answer &ldquo;what does normal look like&rdquo; — the questions a dashboard needs. Incident response needs the opposite: enough detail to reconstruct exactly what an attacker did, in order, across systems that don&rsquo;t share a clock or a request ID. Those are different design goals, and optimizing for one quietly starves the other.</p>
<h2 id="correlation-ids-matter-more-than-log-volume">Correlation IDs matter more than log volume</h2>
<p>Teams often respond to &ldquo;we couldn&rsquo;t reconstruct the incident&rdquo; by logging more of everything, which mostly adds noise. The actual gap is usually that a request touching five services produces five sets of logs with no shared identifier linking them. A consistent correlation ID propagated through every service call turns a volume problem into a query problem — you can pull the full story in one search instead of manually time-correlating timestamps across systems that drift by seconds.</p>
<h2 id="log-the-auth-decision-not-just-the-auth-attempt">Log the auth decision, not just the auth attempt</h2>
<p>Most systems log &ldquo;login succeeded&rdquo; or &ldquo;login failed&rdquo; but not <em>why</em> an authorization check passed or failed for a specific resource — which role, which policy, which condition matched. During an incident, &ldquo;did this account have access to this resource, and under what policy&rdquo; is one of the first questions asked, and without decision-level logging, answering it means reverse-engineering the access control logic from scratch under time pressure.</p>
<h2 id="retention-matters-more-than-most-teams-budget-for">Retention matters more than most teams budget for</h2>
<p>Attackers increasingly wait weeks or months between initial access and objective — meaning the logs you need to reconstruct the intrusion may have already rolled off retention by the time you&rsquo;re investigating. Check your actual log retention against your industry&rsquo;s typical dwell time, not against your storage budget&rsquo;s comfort zone; a shorter retention window than your realistic detection lag means some incidents are unreconstructable by design, regardless of how good your logging schema is.</p>
]]></content:encoded></item><item><title>The Tabletop Exercise Gap: Testing Incident Response for Real</title><link>https://firewallsync.com/posts/the-tabletop-exercise-gap-testing-incident-response-for-real/</link><guid>https://firewallsync.com/posts/the-tabletop-exercise-gap-testing-incident-response-for-real/</guid><pubDate>Sun, 27 Sep 2026 09:00:00 +0000</pubDate><dc:creator>FirewallSync Editorial</dc:creator><category>Security Operations</category><description>Tabletop exercises satisfy the audit requirement but rarely test whether your team can actually execute under pressure. Here's the gap and how to close it.</description><enclosure url="https://firewallsync.com/posts/the-tabletop-exercise-gap-testing-incident-response-for-real/cover_hu582100228981122759.jpg" type="image/jpeg" length="0"/><media:content url="https://firewallsync.com/posts/the-tabletop-exercise-gap-testing-incident-response-for-real/cover_hu582100228981122759.jpg" medium="image" type="image/jpeg" width="1200" height="630"/><content:encoded><![CDATA[<p><img src="https://firewallsync.com/posts/the-tabletop-exercise-gap-testing-incident-response-for-real/cover_hu582100228981122759.jpg" alt="Team with laptops watching a colleague at a whiteboard" width="1200" height="630"></p><p>A tabletop exercise where everyone sits in a conference room and narrates what they&rsquo;d do tests whether people remember the runbook. It doesn&rsquo;t test whether the runbook survives contact with a real incident — degraded communication tools, a key person on vacation, or an attacker who doesn&rsquo;t follow the scenario&rsquo;s script.</p>
<h2 id="run-at-least-one-exercise-with-a-communication-channel-down">Run at least one exercise with a communication channel down</h2>
<p>The single most common real-incident failure mode isn&rsquo;t a missing step in the runbook — it&rsquo;s that Slack, your usual coordination tool, is either compromised or unavailable (because it&rsquo;s hosted on the infrastructure that&rsquo;s on fire). If your tabletop always assumes normal tooling, you&rsquo;ve never actually tested your incident response — you&rsquo;ve tested your ability to read a document out loud. Run one exercise per year with the primary comms channel explicitly ruled out of scope.</p>
<h2 id="inject-a-wrong-turn-not-just-a-scenario">Inject a wrong turn, not just a scenario</h2>
<p>Most tabletop scripts hand the team accurate information and let them respond correctly. Real incidents include red herrings — a misleading log entry, an alert that points at the wrong service, a well-meaning engineer who changes something mid-incident without telling anyone. Build at least one deliberate wrong signal into your next exercise and see how long it takes the team to notice and correct course; that recovery time is a more useful metric than whether they reached the &ldquo;right&rdquo; answer eventually.</p>
<h2 id="test-the-decision-makers-availability-not-just-their-competence">Test the decision-maker&rsquo;s availability, not just their competence</h2>
<p>Plans routinely name a single incident commander with no tested backup. Pick a tabletop date and explicitly remove that person from the exercise without warning the rest of the team beforehand — if response quality collapses, you&rsquo;ve found a single point of failure that a real 2am incident will find for you anyway, just with worse timing.</p>
]]></content:encoded></item><item><title>Alert Fatigue Is a Security Metric, Not a Morale Problem</title><link>https://firewallsync.com/posts/alert-fatigue-is-a-security-metric-not-a-morale-problem/</link><guid>https://firewallsync.com/posts/alert-fatigue-is-a-security-metric-not-a-morale-problem/</guid><pubDate>Sat, 26 Sep 2026 09:00:00 +0000</pubDate><dc:creator>FirewallSync Editorial</dc:creator><category>Security Operations</category><description>Teams treat alert fatigue as a burnout issue to manage around. It's actually a leading indicator that your detection pipeline is broken.</description><enclosure url="https://firewallsync.com/posts/alert-fatigue-is-a-security-metric-not-a-morale-problem/cover_hu10577196946262886676.jpg" type="image/jpeg" length="0"/><media:content url="https://firewallsync.com/posts/alert-fatigue-is-a-security-metric-not-a-morale-problem/cover_hu10577196946262886676.jpg" medium="image" type="image/jpeg" width="1200" height="630"/><content:encoded><![CDATA[<p><img src="https://firewallsync.com/posts/alert-fatigue-is-a-security-metric-not-a-morale-problem/cover_hu10577196946262886676.jpg" alt="Monitoring screen showing live metrics" width="1200" height="630"></p><p>Most orgs respond to alert fatigue with rotation schedules, mental health check-ins, or hiring more analysts. All reasonable, none of them fix the actual problem: a detection pipeline generating more noise than signal, which is a tuning failure, not a staffing shortfall.</p>
<h2 id="track-signal-to-action-ratio-not-alert-volume">Track signal-to-action ratio, not alert volume</h2>
<p>Counting total alerts tells you nothing useful — it doesn&rsquo;t distinguish between 10,000 alerts that each require a decision and 10,000 that are auto-closeable duplicates. The metric that matters is what fraction of alerts result in an actual action (escalation, ticket, remediation) versus a dismiss-and-forget. If that ratio is under 5%, your rules are too broad, and adding headcount just spreads the same noise across more people instead of removing it.</p>
<h2 id="kill-rules-before-you-tune-them">Kill rules before you tune them</h2>
<p>The instinct when a rule is noisy is to tighten its thresholds. Often the faster fix is deleting it and confirming nothing important was riding on it — most legacy detection rules were written for an environment that no longer exists, and nobody owns the decision to retire them. Run a 90-day audit of which rules have never once led to a real action, and sunset them explicitly rather than letting them quietly erode trust in the rest of the pipeline.</p>
<h2 id="separate-needs-a-human-now-from-needs-a-human-eventually">Separate &ldquo;needs a human now&rdquo; from &ldquo;needs a human eventually&rdquo;</h2>
<p>A huge share of fatigue comes from routing informational alerts through the same channel as ones requiring immediate triage. If a Slack channel or pager gets both &ldquo;unusual login from a new device, self-resolved&rdquo; and &ldquo;ransomware indicator on a production host,&rdquo; analysts learn to skim everything — including the alert that actually mattered. Split your routing by required response time, not by source system, and the urgent channel becomes trustworthy again.</p>
]]></content:encoded></item><item><title>Why Your Incident Postmortems Aren't Preventing Repeats</title><link>https://firewallsync.com/posts/why-your-incident-postmortems-arent-preventing-repeats/</link><guid>https://firewallsync.com/posts/why-your-incident-postmortems-arent-preventing-repeats/</guid><pubDate>Wed, 12 Aug 2026 00:00:00 +0000</pubDate><dc:creator>FirewallSync Editorial</dc:creator><category>Security Operations</category><description>Blameless postmortems became standard practice for good reasons, but most teams stopped halfway through adopting them — and it shows in the repeat incidents.</description><enclosure url="https://firewallsync.com/posts/why-your-incident-postmortems-arent-preventing-repeats/cover_hu5203005822613407080.jpg" type="image/jpeg" length="0"/><media:content url="https://firewallsync.com/posts/why-your-incident-postmortems-arent-preventing-repeats/cover_hu5203005822613407080.jpg" medium="image" type="image/jpeg" width="1200" height="630"/><content:encoded><![CDATA[<p><img src="https://firewallsync.com/posts/why-your-incident-postmortems-arent-preventing-repeats/cover_hu5203005822613407080.jpg" alt="People taking notes around a table during a meeting" width="1200" height="630"></p><p>Blameless postmortems are now the default at most engineering orgs, which is progress. But a document being blameless doesn&rsquo;t automatically make it useful. The most common failure mode isn&rsquo;t blame creeping back in — it&rsquo;s that the postmortem produces a list of action items that never get prioritized against feature work, so the same root cause resurfaces in six months wearing a different symptom.</p>
<h2 id="the-action-item-graveyard">The action item graveyard</h2>
<p>If your postmortem template has an &ldquo;action items&rdquo; section with no owner, no deadline, and no forcing function to revisit it, you don&rsquo;t have a prevention process — you have a documentation exercise. Action items from incidents need to compete for sprint capacity the same way any other ticket does, with a visible cost to deferring them repeatedly.</p>
<h2 id="root-cause-is-rarely-singular">Root cause is rarely singular</h2>
<p>Most postmortems stop at the first plausible technical explanation: a bad deploy, a missing rate limit, an expired certificate. The more useful question is what allowed that technical failure to become a customer-facing incident — was there no monitoring on that path, no runbook, no one on call who knew the system well enough to catch it early? Fixing the technical trigger without fixing the detection gap guarantees a different trigger produces the same outcome later.</p>
<h2 id="track-recurrence-not-just-resolution">Track recurrence, not just resolution</h2>
<p>Most incident tracking measures time-to-resolution and calls it done. Add one more metric: how many incidents this quarter share a root cause category with an incident from last quarter. If that number isn&rsquo;t trending toward zero, your postmortem process is documenting problems, not solving them.</p>
<h2 id="what-a-working-process-looks-like">What a working process looks like</h2>
<ul>
<li>Every action item gets a named owner and a sprint, not a someday-list</li>
<li>Postmortems ask what let the failure surface to users, not just what failed technically</li>
<li>Recurrence rate is tracked as a metric leadership actually looks at</li>
</ul>
<p>The blameless part was never the hard part. Follow-through is.</p>
]]></content:encoded></item></channel></rss>