Skip to content

Commit c4b91a5

Browse files
algoriddlefacebook-github-bot
authored andcommitted
Replace pickle serialization to address security vulnerability
Summary: This diff replaces the use of pickle serialization with json to address a security vulnerability. Adding a warning message that this code is for demonstration purposes only. Reviewed By: mdouze Differential Revision: D52777650 fbshipit-source-id: d9d6a00fd341b29ac854adcbf675d2cd303d2f29
1 parent a30fd74 commit c4b91a5

File tree

1 file changed

+18
-16
lines changed

1 file changed

+18
-16
lines changed

contrib/rpc.py

+18-16
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@
77
Simplistic RPC implementation.
88
Exposes all functions of a Server object.
99
10-
Uses pickle for serialization and the socket interface.
10+
This code is for demonstration purposes only, and does not include certain
11+
security protections. It is not meant to be run on an untrusted network or
12+
in a production environment.
1113
"""
1214

15+
import importlib
1316
import os
1417
import pickle
1518
import sys
@@ -23,22 +26,21 @@
2326
# default
2427
PORT = 12032
2528

29+
safe_modules = {
30+
'numpy',
31+
'numpy.core.multiarray',
32+
}
2633

27-
#########################################################################
28-
# simple I/O functions
2934

35+
class RestrictedUnpickler(pickle.Unpickler):
3036

31-
def inline_send_handle(f, conn):
32-
st = os.fstat(f.fileno())
33-
size = st.st_size
34-
pickle.dump(size, conn)
35-
conn.write(f.read(size))
36-
37-
38-
def inline_send_string(s, conn):
39-
size = len(s)
40-
pickle.dump(size, conn)
41-
conn.write(s)
37+
def find_class(self, module, name):
38+
# Only allow safe modules.
39+
if module in safe_modules:
40+
return getattr(importlib.import_module(module), name)
41+
# Forbid everything else.
42+
raise pickle.UnpicklingError("global '%s.%s' is forbidden" %
43+
(module, name))
4244

4345

4446
class FileSock:
@@ -123,7 +125,7 @@ def one_function(self):
123125
"""
124126

125127
try:
126-
(fname,args)=pickle.load(self.fs)
128+
(fname, args) = RestrictedUnpickler(self.fs).load()
127129
except EOFError:
128130
raise ClientExit("read args")
129131
self.log("executing method %s"%(fname))
@@ -214,7 +216,7 @@ def generic_fun(self, fname, args):
214216
return self.get_result()
215217

216218
def get_result(self):
217-
(st, ret) = pickle.load(self.fs)
219+
(st, ret) = RestrictedUnpickler(self.fs).load()
218220
if st!=None:
219221
raise ServerException(st)
220222
else:

0 commit comments

Comments
 (0)