--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eric6/Plugins/CheckerPlugins/CodeStyleChecker/Security/Checks/awsHardcodedPassword.py Tue Jun 16 17:45:12 2020 +0200 @@ -0,0 +1,110 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2020 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing checks for potentially hardcoded AWS passwords. +""" + +# +# This is a modified version of the one found at +# https://pypi.org/project/bandit-aws/. +# +# Original Copyright 2020 CMCRC (devcdt@cmcrc.com) +# +# License: GPLv3 +# + +from collections import Counter +import math +import re +import string + +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 + """ + return { + "Str": [ + (checkHardcodedAwsKey, ("S801", "S802")), + ], + } + +AWS_ACCESS_KEY_ID_SYMBOLS = string.ascii_uppercase + string.digits +AWS_ACCESS_KEY_ID_REGEX = re.compile( + '[' + AWS_ACCESS_KEY_ID_SYMBOLS + ']{20}' +) +AWS_ACCESS_KEY_ID_MAX_ENTROPY = 3 + +AWS_SECRET_ACCESS_KEY_SYMBOLS = string.ascii_letters + string.digits + '/+=' +AWS_SECRET_ACCESS_KEY_REGEX = re.compile( + '[' + AWS_SECRET_ACCESS_KEY_SYMBOLS + ']{40}' +) +AWS_SECRET_ACCESS_KEY_MAX_ENTROPY = 4.5 + + +def shannonEntropy(data, symbols): + """ + Function to caclculate the Shannon entropy of some given data. + + Source: + http://blog.dkbza.org/2007/05/scanning-data-for-entropy-anomalies.html + + @param data data to calculate the entropy for + @type str + @param symbols allowed symbols + @type str + @return Shannon entropy of the given data + @rtype float + """ + if not data: + return 0 + entropy = 0 + counts = Counter(data) + for x in symbols: + p_x = float(counts[x]) / len(data) + if p_x > 0: + entropy += - p_x * math.log(p_x, 2) + return entropy + + +def checkHardcodedAwsKey(reportError, context, config): + """ + Function to check for potentially hardcoded AWS passwords. + + @param reportError function to be used to report errors + @type func + @param context security context object + @type SecurityContext + @param config dictionary with configuration data + @type dict + """ + node = context.node + if AWS_ACCESS_KEY_ID_REGEX.fullmatch(node.s): + entropy = shannonEntropy(node.s, AWS_ACCESS_KEY_ID_SYMBOLS) + if entropy > AWS_ACCESS_KEY_ID_MAX_ENTROPY: + reportError( + context.node.lineno - 1, + context.node.col_offset, + "S801", + "L", + "M", + node.s + ) + + elif AWS_SECRET_ACCESS_KEY_REGEX.fullmatch(node.s): + entropy = shannonEntropy(node.s, AWS_SECRET_ACCESS_KEY_SYMBOLS) + if entropy > AWS_SECRET_ACCESS_KEY_MAX_ENTROPY: + reportError( + context.node.lineno - 1, + context.node.col_offset, + "S802", + "M", + "M", + node.s + )