File CVE-2025-61765-replace-pickle-with-json.patch of Package python-python-socketio.41063

From 333349c14a614cf5e29f64e9461eb27f9ac2f670 Mon Sep 17 00:00:00 2001
From: Miguel Grinberg <miguel.grinberg@gmail.com>
Date: Wed, 24 Sep 2025 23:56:30 +0100
Subject: [PATCH 1/2] Replace pickle with json

---
 src/socketio/async_aiopika_manager.py |  6 +++---
 src/socketio/async_pubsub_manager.py  | 15 ++++-----------
 src/socketio/async_redis_manager.py   |  4 ++--
 src/socketio/kafka_manager.py         |  6 +++---
 src/socketio/kombu_manager.py         |  4 ++--
 src/socketio/pubsub_manager.py        | 15 ++++-----------
 src/socketio/redis_manager.py         |  4 ++--
 src/socketio/zmq_manager.py           | 10 +++++-----
 tests/async/test_pubsub_manager.py    | 13 ++++++-------
 tests/common/test_pubsub_manager.py   | 13 ++++++-------
 10 files changed, 37 insertions(+), 53 deletions(-)

Index: python-socketio-5.7.2/src/socketio/kafka_manager.py
===================================================================
--- python-socketio-5.7.2.orig/src/socketio/kafka_manager.py
+++ python-socketio-5.7.2/src/socketio/kafka_manager.py
@@ -1,11 +1,11 @@
 import logging
-import pickle
 
 try:
     import kafka
 except ImportError:
     kafka = None
 
+from engineio import json
 from .pubsub_manager import PubSubManager
 
 logger = logging.getLogger('socketio')
@@ -54,7 +54,7 @@ class KafkaManager(PubSubManager):  # pr
                                             bootstrap_servers=self.kafka_urls)
 
     def _publish(self, data):
-        self.producer.send(self.channel, value=pickle.dumps(data))
+        self.producer.send(self.channel, value=json.dumps(data))
         self.producer.flush()
 
     def _kafka_listen(self):
@@ -64,4 +64,4 @@ class KafkaManager(PubSubManager):  # pr
     def _listen(self):
         for message in self._kafka_listen():
             if message.topic == self.channel:
-                yield pickle.loads(message.value)
+                yield message.value
Index: python-socketio-5.7.2/src/socketio/kombu_manager.py
===================================================================
--- python-socketio-5.7.2.orig/src/socketio/kombu_manager.py
+++ python-socketio-5.7.2/src/socketio/kombu_manager.py
@@ -1,4 +1,3 @@
-import pickle
 import uuid
 
 try:
@@ -6,6 +5,7 @@ try:
 except ImportError:
     kombu = None
 
+from engineio import json
 from .pubsub_manager import PubSubManager
 
 
@@ -103,7 +103,7 @@ class KombuManager(PubSubManager):  # pr
         connection = self._connection()
         publish = connection.ensure(self.producer, self.producer.publish,
                                     errback=self.__error_callback)
-        publish(pickle.dumps(data))
+        publish(json.dumps(data))
 
     def _listen(self):
         reader_queue = self._queue()
Index: python-socketio-5.7.2/src/socketio/pubsub_manager.py
===================================================================
--- python-socketio-5.7.2.orig/src/socketio/pubsub_manager.py
+++ python-socketio-5.7.2/src/socketio/pubsub_manager.py
@@ -2,7 +2,6 @@ from functools import partial
 import uuid
 
 from engineio import json
-import pickle
 
 from .base_manager import BaseManager
 
@@ -154,16 +153,10 @@ class PubSubManager(BaseManager):
             if isinstance(message, dict):
                 data = message
             else:
-                if isinstance(message, bytes):  # pragma: no cover
-                    try:
-                        data = pickle.loads(message)
-                    except:
-                        pass
-                if data is None:
-                    try:
-                        data = json.loads(message)
-                    except:
-                        pass
+                try:
+                    data = json.loads(message)
+                except:
+                    pass
             if data and 'method' in data:
                 self._get_logger().info('pubsub message: {}'.format(
                     data['method']))
Index: python-socketio-5.7.2/src/socketio/redis_manager.py
===================================================================
--- python-socketio-5.7.2.orig/src/socketio/redis_manager.py
+++ python-socketio-5.7.2/src/socketio/redis_manager.py
@@ -1,5 +1,4 @@
 import logging
-import pickle
 import time
 
 try:
@@ -7,6 +6,7 @@ try:
 except ImportError:
     redis = None
 
+from engineio import json
 from .pubsub_manager import PubSubManager
 
 logger = logging.getLogger('socketio')
@@ -78,7 +78,7 @@ class RedisManager(PubSubManager):  # pr
             try:
                 if not retry:
                     self._redis_connect()
-                return self.redis.publish(self.channel, pickle.dumps(data))
+                return self.redis.publish(self.channel, json.dumps(data))
             except redis.exceptions.RedisError:
                 if retry:
                     logger.error('Cannot publish to redis... retrying')
Index: python-socketio-5.7.2/src/socketio/zmq_manager.py
===================================================================
--- python-socketio-5.7.2.orig/src/socketio/zmq_manager.py
+++ python-socketio-5.7.2/src/socketio/zmq_manager.py
@@ -1,4 +1,3 @@
-import pickle
 import re
 
 try:
@@ -6,6 +5,7 @@ try:
 except ImportError:
     zmq = None
 
+from engineio import json
 from .pubsub_manager import PubSubManager
 
 
@@ -80,14 +80,14 @@ class ZmqManager(PubSubManager):  # prag
                                          logger=logger)
 
     def _publish(self, data):
-        pickled_data = pickle.dumps(
+        packed_data = json.dumps(
             {
                 'type': 'message',
                 'channel': self.channel,
                 'data': data
             }
-        )
-        return self.sink.send(pickled_data)
+        ).encode()
+        return self.sink.send(packed_data)
 
     def zmq_listen(self):
         while True:
@@ -99,7 +99,7 @@ class ZmqManager(PubSubManager):  # prag
         for message in self.zmq_listen():
             if isinstance(message, bytes):
                 try:
-                    message = pickle.loads(message)
+                    message = json.loads(message)
                 except Exception:
                     pass
             if isinstance(message, dict) and \
Index: python-socketio-5.7.2/tests/common/test_pubsub_manager.py
===================================================================
--- python-socketio-5.7.2.orig/tests/common/test_pubsub_manager.py
+++ python-socketio-5.7.2/tests/common/test_pubsub_manager.py
@@ -1,4 +1,5 @@
 import functools
+import json
 import logging
 import unittest
 from unittest import mock
@@ -372,16 +373,14 @@ class TestPubSubManager(unittest.TestCas
         self.pm._handle_close_room = mock.MagicMock()
 
         def messages():
-            import pickle
-
             yield {'method': 'emit', 'value': 'foo'}
             yield {'missing': 'method'}
             yield '{"method": "callback", "value": "bar"}'
             yield {'method': 'disconnect', 'sid': '123', 'namespace': '/foo'}
             yield {'method': 'bogus'}
-            yield pickle.dumps({'method': 'close_room', 'value': 'baz'})
+            yield json.dumps({'method': 'close_room', 'value': 'baz'})
             yield 'bad json'
-            yield b'bad pickled'
+            yield b'bad data'
 
         self.pm._listen = mock.MagicMock(side_effect=messages)
         try:
Index: python-socketio-5.7.2/src/socketio/asyncio_aiopika_manager.py
===================================================================
--- python-socketio-5.7.2.orig/src/socketio/asyncio_aiopika_manager.py
+++ python-socketio-5.7.2/src/socketio/asyncio_aiopika_manager.py
@@ -1,6 +1,6 @@
 import asyncio
-import pickle
 
+from engineio import json
 from socketio.asyncio_pubsub_manager import AsyncPubSubManager
 
 try:
@@ -70,7 +70,7 @@ class AsyncAioPikaManager(AsyncPubSubMan
         channel = await self._channel(connection)
         exchange = await self._exchange(channel)
         await exchange.publish(
-            aio_pika.Message(body=pickle.dumps(data),
+            aio_pika.Message(body=json.dumps(data),
                              delivery_mode=aio_pika.DeliveryMode.PERSISTENT),
             routing_key='*'
         )
@@ -94,7 +94,7 @@ class AsyncAioPikaManager(AsyncPubSubMan
                 async with self.listener_queue.iterator() as queue_iter:
                     async for message in queue_iter:
                         async with message.process():
-                            yield pickle.loads(message.body)
+                            yield message.body
             except Exception:
                 self._get_logger().error('Cannot receive from rabbitmq... '
                                          'retrying in '
Index: python-socketio-5.7.2/src/socketio/asyncio_pubsub_manager.py
===================================================================
--- python-socketio-5.7.2.orig/src/socketio/asyncio_pubsub_manager.py
+++ python-socketio-5.7.2/src/socketio/asyncio_pubsub_manager.py
@@ -3,7 +3,6 @@ from functools import partial
 import uuid
 
 from engineio import json
-import pickle
 
 from .asyncio_manager import AsyncManager
 
@@ -160,16 +159,10 @@ class AsyncPubSubManager(AsyncManager):
                     if isinstance(message, dict):
                         data = message
                     else:
-                        if isinstance(message, bytes):  # pragma: no cover
-                            try:
-                                data = pickle.loads(message)
-                            except:
-                                pass
-                        if data is None:
-                            try:
-                                data = json.loads(message)
-                            except:
-                                pass
+                        try:
+                            data = json.loads(message)
+                        except:
+                            pass
                     if data and 'method' in data:
                         self._get_logger().info('pubsub message: {}'.format(
                             data['method']))
Index: python-socketio-5.7.2/src/socketio/asyncio_redis_manager.py
===================================================================
--- python-socketio-5.7.2.orig/src/socketio/asyncio_redis_manager.py
+++ python-socketio-5.7.2/src/socketio/asyncio_redis_manager.py
@@ -1,5 +1,4 @@
 import asyncio
-import pickle
 
 try:  # pragma: no cover
     from redis import asyncio as aioredis
@@ -12,6 +11,7 @@ except ImportError:  # pragma: no cover
         aioredis = None
         RedisError = None
 
+from engineio import json
 from .asyncio_pubsub_manager import AsyncPubSubManager
 
 
@@ -65,7 +65,7 @@ class AsyncRedisManager(AsyncPubSubManag
                 if not retry:
                     self._redis_connect()
                 return await self.redis.publish(
-                    self.channel, pickle.dumps(data))
+                    self.channel, json.dumps(data))
             except RedisError:
                 if retry:
                     self._get_logger().error('Cannot publish to redis... '
Index: python-socketio-5.7.2/tests/asyncio/test_asyncio_pubsub_manager.py
===================================================================
--- python-socketio-5.7.2.orig/tests/asyncio/test_asyncio_pubsub_manager.py
+++ python-socketio-5.7.2/tests/asyncio/test_asyncio_pubsub_manager.py
@@ -1,5 +1,6 @@
 import asyncio
 import functools
+import json
 import sys
 import unittest
 from unittest import mock
@@ -431,16 +432,14 @@ class TestAsyncPubSubManager(unittest.Te
         self.pm._handle_close_room = AsyncMock()
 
         async def messages():
-            import pickle
-
             yield {'method': 'emit', 'value': 'foo'}
             yield {'missing': 'method'}
             yield '{"method": "callback", "value": "bar"}'
             yield {'method': 'disconnect', 'sid': '123', 'namespace': '/foo'}
             yield {'method': 'bogus'}
-            yield pickle.dumps({'method': 'close_room', 'value': 'baz'})
+            yield json.dumps({'method': 'close_room', 'value': 'baz'})
             yield 'bad json'
-            yield b'bad pickled'
+            yield b'bad data'
             raise asyncio.CancelledError()  # force the thread to exit
 
         self.pm._listen = messages
openSUSE Build Service is sponsored by