--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eric6/Plugins/CheckerPlugins/CodeStyleChecker/Security/Checks/blackListCalls.py Mon Jun 08 08:17:14 2020 +0200 @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2020 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing checks for blacklisted methods and functions. +""" + +import ast +import fnmatch + + +_blacklists = { + 'S301': ([ + 'pickle.loads', + 'pickle.load', + 'pickle.Unpickler', + 'cPickle.loads', + 'cPickle.load', + 'cPickle.Unpickler', + 'dill.loads', + 'dill.load', + 'dill.Unpickler', + 'shelve.open', + 'shelve.DbfilenameShelf'], + "M"), + 'S302': ([ + 'marshal.load', + 'marshal.loads'], + "M"), + 'S303': ([ + 'hashlib.md5', + 'hashlib.sha1', + 'Crypto.Hash.MD2.new', + 'Crypto.Hash.MD4.new', + 'Crypto.Hash.MD5.new', + 'Crypto.Hash.SHA.new', + 'Cryptodome.Hash.MD2.new', + 'Cryptodome.Hash.MD4.new', + 'Cryptodome.Hash.MD5.new', + 'Cryptodome.Hash.SHA.new', + 'cryptography.hazmat.primitives.hashes.MD5', + 'cryptography.hazmat.primitives.hashes.SHA1'], + "M"), +} + + +def getChecks(): + """ + Public method to get a dictionary with checks handled by this module. + + @return dictionary containing checker lists containing checker function and + list of codes + @rtype dict + """ + # TODO: should be list of tuples + return { + "Call": (checkBlacklist, tuple(_blacklists.keys())), + } + + +def checkBlacklist(reportError, context, config): + nodeType = context.node.__class__.__name__ + + if nodeType == 'Call': + func = context.node.func + if isinstance(func, ast.Name) and func.id == '__import__': + if len(context.node.args): + if isinstance(context.node.args[0], ast.Str): + name = context.node.args[0].s + else: + name = "UNKNOWN" + else: + name = "" # handle '__import__()' + else: + name = context.callFunctionNameQual + # In the case the Call is an importlib.import, treat the first + # argument name as an actual import module name. + # Will produce None if argument is not a literal or identifier. + if name in ["importlib.import_module", "importlib.__import__"]: + name = context.call_args[0] + + for code in _blacklists: + qualnames, severity = _blacklists[code] + for qualname in qualnames: + if name and fnmatch.fnmatch(name, qualname): + return reportError( + context.node.lineno, + context.node.col_offset, + code, + "M", + "H" + ) + + return None