CVE-2026-12118 - IBM webMethods Integration Server: Pre-Auth RCE via WmServiceMock
Bring Your Own Bytecode
Bottom Line Up Front (BLUF)
IBM webMethods Integration Server (IS) ships with a development testing utility called WmServiceMock. When this package is installed and active on a production node, an unauthenticated remote attacker can upload and execute arbitrary Java bytecode through the server’s built-in deserialization endpoint - no credentials required, no gadget chain needed. IBM has assigned CVE-2026-12118 a Common Vulnerability Scoring System (CVSS) 3.1 score of 9.8 (Critical). IBM has not released a code-level patch; IBM’s guidance is to remove the WmServiceMock package from all production and internet-facing deployments. Organizations running IBM webMethods IS 10.11 or 10.15 should audit their installations immediately.
Background
IBM webMethods IS is an enterprise integration platform used to connect business systems, APIs, and business-to-business partners. The server exposes a public HTTP endpoint (/invoke/) through which services are called. This endpoint is core to its function and is typically accessible in partner-facing deployment scenarios.
Internally, IS uses a proprietary binary serialization format called IDataBin, with Content-Type application/x-wmidatabin. Among the type codes in this format is DT_IDATCODABLE, a one-byte type tag (0x12) in the IDataBin stream. When the deserializer reads this tag, it treats the next value as an object to rebuild from a supplied class name. A component called WhiteListClassChecker gates which classes the server can instantiate through this mechanism.
This deserialization mechanism has seen previous attention. CVE-2025-36072 documented an allowlist bypass affecting the same endpoint, which prompted IBM to add additional mitigations. With that prior work as context, we examined whether additional exposure existed.
The Discovery
During one of our assessments, we identified that the WmServiceMock package was active on a production IS instance. IBM designed WmServiceMock as a development-time testing utility that configures and exposes mock services for integration testing. IBM does not intend it for production use, but we find it deployed there with some regularity.
When reviewing the classes registered by WmServiceMock, we noted that the class com.wm.ps.serviceMock.MockObject implements the IDataCodable interface and provides a public no-arg constructor. This matters for two reasons. First, IDataCodable is precisely the interface that the DT_IDATCODABLE tag targets: when the deserializer reads that tag, it rebuilds the named class as an IDataCodable. Second, the deserializer instantiates that class by reflection, which requires a public no-arg constructor (here, “public” is a Java access modifier, unrelated to authentication). When the WmServiceMock package is active, MockObject passes the WhiteListClassChecker check because the package registers its own allowlist entries at runtime, independently of the stock whitelistclasses.xml configuration file.
This raised a question: what does MockObject do when it receives attacker-controlled data?
Following the Code Path
The MockObject.setIData() method reads a field called KEY_TYPE from the incoming data. When this value is 3, execution branches into a path that calls this.getDataFactory():
int typeOfMockObject = IDataUtil.getInt(cursor, “KEY_TYPE”, 1);
switch(typeOfMockObject) {
case 3: {
IData inner = IDataUtil.getIData(cursor, “KEY_IDATA”);
this.setData(_cloneData(inner));
MockDataFactory f = this.getDataFactory();
...
}
}getDataFactory() creates an IDataClassLoader - a child-first ClassLoader whose loadClass() implementation does something unexpected: it looks for a Base64-encoded value in the current IData document, keyed by the class name being loaded. If found, it calls defineClass() with the decoded bytes:
String base64 = IDataUtil.getString(cursor, name);
byte[] buf = Base64.decode(base64.getBytes(”ASCII”));
Class<?> c = this.defineClass(name, buf, 0, buf.length);
return c;The attacker supplies a class name and its compiled bytecode, both embedded in the request body. The server defines and instantiates that class. newInstance() then triggers the class’s static initializer (<clinit>) and constructor, giving an attacker full code execution in the IS process.
Critically, WhiteListClassChecker is never consulted for the bytecode upload step. The allowlist check only gatekeeps the initial MockObject instantiation. Once inside MockObject, the IDataClassLoader path loads attacker-controlled class bytecode entirely outside the allowlist mechanism.
Impact
The combination of the following factors produces a severe risk:
- The /invoke/wm.server/connect endpoint accepts unauthenticated connections by default. The IDataBin deserialization path is reachable without credentials.
- The attack requires no allowlist bypass; the WmServiceMock package already registers MockObject to the allowlist.
- The attacker defines and runs arbitrary Java bytecode in the IS process - not a gadget chain through existing library classes. This provides execution as the user running the service.
IBM assigned a CVSS 3.1 score of 9.8 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H), reflecting a fully remote, zero-interaction attack with complete impact across confidentiality, integrity, and availability.
Remediation
IBM’s guidance is to remove the WmServiceMock package from any production IS node:
1. Log in to Integration Server.
2. Navigate to Packages > Management.
3. Locate WmServiceMock and click the Delete icon.
4. Confirm the deletion and restart Integration Server.
IBM has not released a code-level patch. Organizations that require WmServiceMock for development testing should deploy it only in isolated non-production environments with network access strictly controlled.
Timeline
2026/03/24 - Discovery of vulnerability
2026/04/21 - Responsible disclosure communicated to IBM
2026/06/02 - IBM confirmed receipt and investigating report
2026/07/14 - IBM confirmed resolution and CVE published
2026/XX/XX - Blog published






