1010# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
1111# ANY KIND, either express or implied. See the License for the specific
1212# language governing permissions and limitations under the License.
13- from botocore .compat import six
13+ import io as _io
14+ import pickle
1415
1516from ebcli .containers .envvarcollector import EnvvarCollector
1617from ebcli .containers .pathconfig import PathConfig
1718from ebcli .core import fileoperations , io
1819from ebcli .lib import utils
1920from ebcli .operations import commonops , envvarops
2021from ebcli .resources .strings import strings
21- cPickle = six .moves .cPickle
22+
23+
24+ class _SafeUnpickler (pickle .Unpickler ):
25+ """Only allow deserializing LocalState and EnvvarCollector."""
26+ _ALLOWED = {
27+ ('ebcli.operations.localops' , 'LocalState' ),
28+ ('ebcli.containers.envvarcollector' , 'EnvvarCollector' ),
29+ ('__builtin__' , 'set' ),
30+ ('builtins' , 'set' ),
31+ }
32+
33+ def find_class (self , module , name ):
34+ if (module , name ) in self ._ALLOWED :
35+ return super ().find_class (module , name )
36+ raise pickle .UnpicklingError (f"Forbidden: { module } .{ name } " )
2237
2338
2439class LocalState (object ):
@@ -30,15 +45,15 @@ def __init__(self, envvarcollector):
3045 self .envvarcollector = envvarcollector
3146
3247 def dumps (self , path ):
33- fileoperations .write_to_data_file (data = cPickle .dumps (self , protocol = 2 ),
48+ fileoperations .write_to_data_file (data = pickle .dumps (self , protocol = 2 ),
3449 location = path )
3550
3651 @classmethod
3752 def loads (cls , path ):
3853 try :
3954 data = fileoperations .read_from_data_file (path )
40- return cPickle . loads (data )
41- except IOError :
55+ return _SafeUnpickler ( _io . BytesIO (data )). load ( )
56+ except ( IOError , pickle . UnpicklingError ) :
4257 return cls (EnvvarCollector ())
4358
4459 @classmethod
0 commit comments