Description
The worker process accepts class initialization requests from a remote client and directly deserializes attacker-controlled data using cloudpickle.loads. Since cloudpickle deserialization can execute arbitrary code, this introduces a critical remote code execution (RCE) vulnerability when the input originates from an untrusted or compromised client.
class Job(object):
def wait_for_connection(self, reply_socket):
if tag == remote_constants.INIT_OBJECT_TAG:
try:
if self.gpu:
os.environ['CUDA_VISIBLE_DEVICES'] = self.gpu
del os.environ['XPARL_igonre_core']
importlib.reload(parl)
# wait_for_connection
cls = load_remote_class(message[1])
# codes...
def load_remote_class(remote_class_info):
# load_remote_class
in_notebook, dumped_class_info = cloudpickle.loads(remote_class_info)
The deserialization happens immediately after receiving data from a socket, without any authentication, validation, or trust boundary enforcement.
Attack Scenario
An attacker can connect to the worker endpoint and send a crafted remote_class_info payload containing a malicious cloudpickle object. The payload is executed during deserialization, before any class loading logic is reached.
No user interaction is required beyond establishing the connection.
Note:
This deserialization path is also reachable via
parl.remote.master.Master._receive_message → cloudpickle.loads,
meaning attacker-controlled data received directly from a socket is deserialized without any authentication or trust boundary enforcement, further expanding the RCE attack surface.
Recommendation
Require an explicit trust_code / trust_remote flag to enable deserialization.
Description
The worker process accepts class initialization requests from a remote client and directly deserializes attacker-controlled data using
cloudpickle.loads. Since cloudpickle deserialization can execute arbitrary code, this introduces a critical remote code execution (RCE) vulnerability when the input originates from an untrusted or compromised client.The deserialization happens immediately after receiving data from a socket, without any authentication, validation, or trust boundary enforcement.
Attack Scenario
An attacker can connect to the worker endpoint and send a crafted remote_class_info payload containing a malicious cloudpickle object. The payload is executed during deserialization, before any class loading logic is reached.
No user interaction is required beyond establishing the connection.
Note:
This deserialization path is also reachable via
parl.remote.master.Master._receive_message → cloudpickle.loads,meaning attacker-controlled data received directly from a socket is deserialized without any authentication or trust boundary enforcement, further expanding the RCE attack surface.
Recommendation
Require an explicit trust_code / trust_remote flag to enable deserialization.