@@ -36,11 +36,13 @@ def _is_posix():
3636
3737
3838def _is_function_call (node , module , function ):
39+ if not isinstance (function , (list , tuple )):
40+ function = (function ,)
3941 return (
4042 isinstance (node .func , astroid .Attribute )
4143 and isinstance (node .func .expr , astroid .Name )
4244 and node .func .expr .name == module
43- and node .func .attrname == function
45+ and node .func .attrname in function
4446 )
4547
4648
@@ -314,6 +316,21 @@ class SecureCodingStandardChecker(BaseChecker):
314316 'os-open-unsafe-permissions' ,
315317 'Avoid using `os.open` with unsafe file permissions (by default 0 <= mode <= 0o755)' ,
316318 ),
319+ 'E8013' : (
320+ 'Avoid using `pickle.load` and `pickle.loads`' ,
321+ 'avoid-pickle-load' ,
322+ 'Use of `pickle.load` and `pickle.loads` should be avoided in favour of safer file formats' ,
323+ ),
324+ 'E8014' : (
325+ 'Avoid using `marshal.load` and `marshal.loads`' ,
326+ 'avoid-marshal-load' ,
327+ 'Use of `marshal.load` and `marshal.loads` should be avoided in favour of safer file formats' ,
328+ ),
329+ 'E8015' : (
330+ 'Avoid using `shelve.open()`' ,
331+ 'avoid-shelve-open' ,
332+ 'Use of `shelve.open()` should be avoided in favour of safer file formats' ,
333+ ),
317334 }
318335
319336 def __init__ (self , * args , ** kwargs ):
@@ -322,7 +339,7 @@ def __init__(self, *args, **kwargs):
322339 self ._prefer_os_open = False
323340 self ._os_open_modes_allowed = []
324341
325- def visit_call (self , node ):
342+ def visit_call (self , node ): # pylint: disable=too-many-branches
326343 """Visitor method called for astroid.Call nodes."""
327344 if _is_pdb_call (node ):
328345 self .add_message ('avoid-debug-stmt' , node = node )
@@ -352,6 +369,12 @@ def visit_call(self, node):
352369 and not _is_os_open_allowed_mode (node , self ._os_open_modes_allowed )
353370 ):
354371 self .add_message ('os-open-unsafe-permissions' , node = node )
372+ elif _is_function_call (node , module = 'pickle' , function = ('load' , 'loads' )):
373+ self .add_message ('avoid-pickle-load' , node = node )
374+ elif _is_function_call (node , module = 'marshal' , function = ('load' , 'loads' )):
375+ self .add_message ('avoid-marshal-load' , node = node )
376+ elif _is_function_call (node , module = 'shelve' , function = 'open' ):
377+ self .add_message ('avoid-shelve-open' , node = node )
355378
356379 def visit_import (self , node ):
357380 """Visitor method called for astroid.Import nodes."""
@@ -381,18 +404,26 @@ def visit_importfrom(self, node):
381404 self .add_message ('avoid-os-popen' , node = node )
382405 elif not _is_posix () and node .modname == 'shlex' and [name for (name , _ ) in node .names if name == 'quote' ]:
383406 self .add_message ('avoid-shlex-quote-on-non-posix' , node = node )
407+ elif node .modname == 'pickle' and [name for (name , _ ) in node .names if name in ('load' , 'loads' )]:
408+ self .add_message ('avoid-pickle-load' , node = node )
409+ elif node .modname == 'marshal' and [name for (name , _ ) in node .names if name in ('load' , 'loads' )]:
410+ self .add_message ('avoid-marshal-load' , node = node )
411+ elif node .modname == 'shelve' and [name for (name , _ ) in node .names if name == 'open' ]:
412+ self .add_message ('avoid-shelve-open' , node = node )
384413
385414 def visit_with (self , node ):
386415 """Visitor method called for astroid.With nodes."""
387- if self . _prefer_os_open :
388- for item in node . items :
389- if item and isinstance ( item [ 0 ], astroid . Call ) :
416+ for item in node . items :
417+ if item and isinstance ( item [ 0 ], astroid . Call ) :
418+ if self . _prefer_os_open :
390419 if _is_builtin_open_for_writing (item [0 ]):
391420 self .add_message ('replace-builtin-open' , node = node )
392421 elif _is_function_call (item [0 ], module = 'os' , function = 'open' ) and not _is_os_open_allowed_mode (
393422 item [0 ], self ._os_open_modes_allowed
394423 ):
395424 self .add_message ('os-open-unsafe-permissions' , node = node )
425+ elif _is_function_call (item [0 ], module = 'shelve' , function = 'open' ):
426+ self .add_message ('avoid-shelve-open' , node = node )
396427
397428 def visit_assert (self , node ):
398429 """Visitor method called for astroid.Assert nodes."""
0 commit comments