Full Disclosure mailing list archives
Chronicle Wire v2026.8 Insecure Reflection Allows Unvalidated Method Invocation
From: Ron E <ronaldjedgerson () gmail com>
Date: Sat, 22 Aug 2026 08:42:03 -0400
Chronicle Wire's MethodReader implements message dispatch by dynamically
mapping serialized wire events to Java handler methods. During
initialization, the framework discovers public methods exposed by the
registered handler interfaces and registers those methods as callable wire
events.
When a message is processed, the event name supplied within the wire data
determines which registered handler method is selected. Method arguments
are then deserialized from the corresponding message content, and Chronicle
Wire invokes the selected method using Java Reflection.
As a result, when untrusted wire data reaches a MethodReader, externally
controlled input can determine both the handler method selected for
invocation and the arguments supplied to that method.
The dispatch surface is derived automatically from the handler's public
interface rather than from an explicit list of individually registered
operations. Public methods added to a registered handler interface can
therefore become dispatchable wire events without separate method-level
registration.
This behavior becomes security-sensitive when a handler interface contains
privileged or security-sensitive operations and its MethodReader processes
data from an untrusted source. In such deployments, methods intended for
file access, network operations, key management, maintenance,
administrative functionality, or other privileged actions may become
reachable through externally controlled event names.
Vulnerability Details
VanillaMethodReader constructs its dispatch surface from the handlers
supplied by the application:
addParsersForComponents(handler);
During initialization, Chronicle Wire enumerates the public methods
associated with the handler:
for (Method method : handlerClass.getMethods()) {
addParseletForMethod(method);
}
Eligible methods are subsequently registered for wire-event dispatch.
The method name and parameter types are used to construct the corresponding
wire key:
MethodWireKey key =
new MethodWireKey(
method.getName(),
parameterTypes);
This means the set of methods callable through the wire protocol is derived
from the public methods exposed by the registered handler interface.
When incoming wire data is processed, the supplied event name is matched
against the registered method dispatch table. The corresponding argument
values are then deserialized according to the selected method's declared
parameter types:
arguments[i] =
valueIn.object(parameterTypes[i]);
After argument deserialization, the selected Java method is invoked
reflectively:
method.invoke(target, arguments);
Consequently, externally controlled wire data participates directly in two
security-sensitive decisions: selecting which registered handler method is
executed and supplying the arguments passed to that method.
The dispatch mechanism itself does not introduce a method-level
authorization decision between event selection and invocation. The
effective security boundary is therefore determined by which interfaces are
registered with MethodReader, which public methods those interfaces expose,
and whether the application permits untrusted data to reach the reader.
Root Cause
The security issue arises from automatically deriving the externally
dispatchable method surface from public methods exposed by registered
handler interfaces.
Chronicle Wire:
-
Discovers public methods associated with registered handlers.
-
Registers eligible methods as wire-event handlers.
-
Resolves incoming event names to those methods.
-
Deserializes method parameters from the corresponding wire input.
-
Invokes the selected methods using Java Reflection.
The dispatch model does not require each callable operation to be
independently exported or registered at the method level. Consequently, the
security boundary of a MethodReader can expand when additional public
methods are introduced into an interface already used for wire dispatch.
This creates a risk in applications where the registered handler interface
contains operations that should not be reachable by the party controlling
the wire input.
The issue is particularly significant when interfaces evolve over time.
Adding a new public operation to an existing MethodReader-facing interface
can simultaneously add that operation to the wire dispatch surface without
a separate dispatch registration step.
Impact
When untrusted input reaches a MethodReader, an attacker can select among
the public operations exposed through the registered handler interface and
provide serialized arguments for the selected operation.
The resulting security impact depends on the functionality implemented by
those handlers.
Security-sensitive methods may include:
-
file access and file modification;
-
outbound network communication;
-
administrative operations;
-
key rotation or key-management operations;
-
configuration changes;
-
maintenance functionality;
-
state-changing business operations; and
-
other privileged application functionality.
If such operations are exposed through a registered handler interface,
externally controlled event names can cause those methods to be invoked
with externally supplied arguments.
The attack surface can also change as the application evolves. A public
method added to an interface already participating in MethodReader dispatch
may become a new wire operation without requiring separate registration of
that individual method.
Methods accepting broad or polymorphic argument types introduce an
additional concern. Arguments are processed through Chronicle Wire's object
deserialization mechanisms:
arguments[i] =
valueIn.object(parameterTypes[i]);
Where the declared parameter type permits serialized type information to
influence runtime object selection, externally controlled input may affect
both the *method selected for invocation* and the *runtime object
instantiated as its argument*.
The resulting vulnerability therefore combines an externally controlled
method-dispatch surface with attacker-controlled argument deserialization.
The ultimate impact depends on the operations exposed by the registered
handler and the trust boundary through which wire messages are received.
Proof of Concept
The proof of concept demonstrates that Chronicle Wire's MethodReader allows
serialized event names to select public methods exposed by a registered
handler and supplies those methods with arguments deserialized from the
corresponding wire message.
The tests exercise several handler operations to demonstrate method
selection, privileged-operation reachability, automatic expansion of the
dispatch surface, and typed argument deserialization.
Administrative Method Invocation
The registered handler exposes an administrative demonstration method named
deleteAll.
The following wire event was supplied:
deleteAll: pwned-method-invocation
Observed output:
MethodReader invoked event-selected method:
deleteAll:pwned-method-invocation
This confirms that the event name supplied in the wire message selected the
corresponding public handler method and that the attacker-controlled
argument was delivered to that method.
The demonstration method does not perform destructive deletion. Its purpose
is to establish that an operation exposed by the registered handler can be
selected directly through the incoming event name.
File-Reading Method Invocation
The handler additionally exposes a demonstration method that reads a
caller-specified system file.
The supplied event was:
readSystemFile: /etc/hosts
Observed invocation:
MethodReader invoked file-reading method:
readSystemFile:/etc/hosts
The handler successfully accessed the supplied file and recorded:
MethodReader file-read evidence:
/etc/hosts:bytes=279:first-line=##
The test therefore demonstrates more than method-name resolution. The
externally supplied event selected a file-access operation and the
externally supplied argument controlled the path processed by that
operation.
Automatic Exposure of Newly Added Handler Methods
A new public method was added to the registered handler interface:
void pingLocalhost(int port);
No individual MethodReader registration was added for pingLocalhost.
The following wire event was then supplied:
pingLocalhost: 61866
Observed output:
MethodReader invoked loopback ping method:
pingLocalhost:61866
The test additionally recorded the resulting loopback interaction:
MethodReader loopback ping evidence:
pingLocalhost:127.0.0.1:61866
This confirms that adding the method to the registered handler interface
was sufficient for the operation to become part of the MethodReader
dispatch surface.
The test is significant because it demonstrates that the callable surface
can expand as the handler interface evolves. A newly introduced public
handler operation does not require separate method-level registration
before it can be selected by a corresponding wire event.
Process-Execution Demonstration
The automatic dispatch behavior was further tested with a deliberately
introduced handler method containing a process-execution operation:
void runtimeExecEcho(String command);
The following event was supplied:
runtimeExecEcho: pwned-runtime-exec
Observed invocation:
MethodReader invoked Runtime.exec method:
runtimeExecEcho:pwned-runtime-exec
The test recorded successful process execution:
MethodReader Runtime.exec evidence:
command=/bin/echo pwned-runtime-exec, exit=0
Process output:
pwned-runtime-exec
This test does not establish that Chronicle Wire itself contains a built-in
command-execution method or universal RCE gadget. The runtimeExecEcho
method was intentionally introduced as a controlled demonstration of the
security consequence when a privileged operation exists on a registered
handler interface.
The result confirms the underlying dispatch property: once the public
method was present on the handler interface, the corresponding wire event
could select and invoke it without separate method-level registration.
Typed Object Argument Deserialization
The PoC additionally demonstrates that MethodReader dispatch can interact
with Chronicle Wire's typed object deserialization when a handler accepts a
sufficiently broad parameter type.
The supplied event contained a tagged object:
acceptObject:
!net.openhft.chronicle.wire.SecurityAdditionalPoCTest$MethodReaderProbe {
marker: proof
}
Observed output:
MethodReader typed argument instantiated class:
net.openhft.chronicle.wire.SecurityAdditionalPoCTest$MethodReaderProbe
MethodReader typed argument constructor calls: 1
MethodReader typed argument readMarshallable calls: 1
This confirms that MethodReader did not simply pass a textual
representation of the supplied argument to the handler.
The argument entered Chronicle Wire's object deserialization path, the
class identified by the serialized type information was instantiated, its
constructor executed, and its readMarshallable() callback was invoked.
For handler methods accepting broad or polymorphic parameter types,
externally controlled wire input may therefore influence both the handler
operation selected for invocation and the runtime object created as its
argument.
PoC Results
The runtime evidence confirms the following MethodReader behaviors:
[CONFIRMED] Wire event selected deleteAll handler method
[CONFIRMED] Attacker-controlled argument delivered to selected method
[CONFIRMED] Wire event selected readSystemFile handler method
[CONFIRMED] Supplied /etc/hosts path processed by handler
[CONFIRMED] File contents successfully read
[CONFIRMED] Newly added pingLocalhost method became dispatchable
[CONFIRMED] No separate method-level registration was required
[CONFIRMED] Loopback network interaction occurred
[CONFIRMED] Newly added runtimeExecEcho method became dispatchable
[CONFIRMED] Demonstration process executed successfully
[CONFIRMED] /bin/echo exited with status 0
[CONFIRMED] Process output contained pwned-runtime-exec
[CONFIRMED] Typed MethodReader argument instantiated selected class
[CONFIRMED] Constructor executed: 1 invocation
[CONFIRMED] readMarshallable() executed: 1 invocation
The PoC therefore establishes that externally controlled wire events can
select operations from the public dispatch surface of a registered
MethodReader handler and supply arguments to those operations.
It also demonstrates that adding new public methods to a registered handler
interface can expand the available dispatch surface without separate
method-level registration.
The runtimeExecEcho, readSystemFile, and similar privileged demonstration
methods were intentionally implemented to establish the consequence of
placing security-sensitive functionality on a MethodReader-facing
interface. They should not be interpreted as built-in Chronicle Wire
functionality.
Finally, the typed argument test confirms that MethodReader can combine
externally controlled method selection with Chronicle Wire's object
deserialization behavior when the selected handler accepts a broad or
polymorphic parameter type.
Ron Edgerson
Vulnerability Researcher & Exploit Developer
CVE Research | Binary Exploitation | Application & Systems Security
Responsible Disclosure • Proof-of-Concept Development
🌐 https://github.com/ob1sec
🔗 https://www.linkedin.com/in/ronedgerson1
<https://linkedin.com/in/yourhandle>
_______________________________________________
Sent through the Full Disclosure mailing list
https://nmap.org/mailman/listinfo/fulldisclosure
Web Archives & RSS: https://seclists.org/fulldisclosure/
Current thread:
- Chronicle Wire v2026.8 Insecure Reflection Allows Unvalidated Method Invocation Ron E (Aug 26)
