--- a/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Security/Checks/insecureHashlibNew.py Tue Jan 16 14:35:46 2024 +0100 +++ b/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Security/Checks/insecureHashlibNew.py Tue Jan 16 18:24:06 2024 +0100 @@ -36,7 +36,7 @@ } -def _hashlibFunc(reportError, context, config): +def _hashlibFunc(reportError, context, func, config): """ Function to check for use of insecure md4, md5, sha or sha1 hash functions in hashlib.new() if 'usedforsecurity' is not set to 'False'. @@ -45,6 +45,8 @@ @type func @param context security context object @type SecurityContext + @param func name of the hash function + @type str @param config dictionary with configuration data @type dict """ @@ -55,41 +57,37 @@ ) if isinstance(context.callFunctionNameQual, str): - qualnameList = context.callFunctionNameQual.split(".") - - if "hashlib" in qualnameList: - func = qualnameList[-1] - keywords = context.callKeywords + keywords = context.callKeywords - if func in insecureHashes: - if keywords.get("usedforsecurity", "True") == "True": - reportError( - context.node.lineno - 1, - context.node.col_offset, - "S332", - "H", - "H", - func.upper(), - ) - elif func == "new": - args = context.callArgs - name = args[0] if args else keywords.get("name") - if ( - isinstance(name, str) - and name.lower() in insecureHashes - and keywords.get("usedforsecurity", "True") == "True" - ): - reportError( - context.node.lineno - 1, - context.node.col_offset, - "S332", - "H", - "H", - name.upper(), - ) + if func in insecureHashes: + if keywords.get("usedforsecurity", "True") == "True": + reportError( + context.node.lineno - 1, + context.node.col_offset, + "S332", + "H", + "H", + func.upper(), + ) + elif func == "new": + args = context.callArgs + name = args[0] if args else keywords.get("name") + if ( + isinstance(name, str) + and name.lower() in insecureHashes + and keywords.get("usedforsecurity", "True") == "True" + ): + reportError( + context.node.lineno - 1, + context.node.col_offset, + "S332", + "H", + "H", + name.upper(), + ) -def _hashlibNew(reportError, context, config): +def _hashlibNew(reportError, context, func, config): """ Function to check for use of insecure md4, md5, sha or sha1 hash functions in hashlib.new(). @@ -98,6 +96,8 @@ @type func @param context security context object @type SecurityContext + @param func name of the hash function + @type str @param config dictionary with configuration data @type dict """ @@ -107,22 +107,67 @@ else SecurityDefaults["insecure_hashes"] ) - if isinstance(context.callFunctionNameQual, str): - qualnameList = context.callFunctionNameQual.split(".") - func = qualnameList[-1] - if "hashlib" in qualnameList and func == "new": - args = context.callArgs - keywords = context.callKeywords - name = args[0] if args else keywords.get("name") - if isinstance(name, str) and name.lower() in insecureHashes: - reportError( - context.node.lineno - 1, - context.node.col_offset, - "S331", - "M", - "H", - name.upper(), - ) + if func == "new": + args = context.callArgs + keywords = context.callKeywords + name = args[0] if args else keywords.get("name") + if isinstance(name, str) and name.lower() in insecureHashes: + reportError( + context.node.lineno - 1, + context.node.col_offset, + "S331", + "M", + "H", + name.upper(), + ) + + +def _cryptCrypt(reportError, context, func, config): + """ + Function to check for use of insecure md4, md5, sha or sha1 hash functions + in crypt.crypt(). + + @param reportError function to be used to report errors + @type func + @param context security context object + @type SecurityContext + @param func name of the hash function + @type str + @param config dictionary with configuration data + @type dict + """ + insecureHashes = ( + [h.lower() for h in config["insecure_hashes"]] + if config and "insecure_hashes" in config + else SecurityDefaults["insecure_hashes"] + ) + + args = context.callArgs + keywords = context.callKeywords + + if func == "crypt": + name = args[1] if len(args) > 1 else keywords.get("salt") + if isinstance(name, str) and name in insecureHashes: + reportError( + context.node.lineno - 1, + context.node.col_offset, + "S331", + "M", + "H", + name.upper(), + ) + + elif func == "mksalt": + name = args[0] if args else keywords.get("method") + if isinstance(name, str) and name in insecureHashes: + reportError( + context.node.lineno - 1, + context.node.col_offset, + "S331", + "M", + "H", + name.upper(), + ) def checkHashlib(reportError, context, config): @@ -137,7 +182,14 @@ @param config dictionary with configuration data @type dict """ - if sys.version_info >= (3, 9): - _hashlibFunc(reportError, context, config) - else: - _hashlibNew(reportError, context, config) + if isinstance(context.callFunctionNameQual, str): + qualnameList = context.callFunctionNameQual.split(".") + func = qualnameList[-1] + + if "hashlib" in qualnameList: + if sys.version_info >= (3, 9): + _hashlibFunc(reportError, context, func, config) + else: + _hashlibNew(reportError, context, func, config) + elif "crypt" in qualnameList and func in ("crypt", "mksalt"): + _cryptCrypt(reportError, context, func, config)