Beispiel #1
0
def _hashlib_func(context):
    if isinstance(context.call_function_name_qual, str):
        qualname_list = context.call_function_name_qual.split(".")

        if "hashlib" in qualname_list:
            func = qualname_list[-1]
            keywords = context.call_keywords

            if func in WEAK_HASHES:
                if keywords.get("usedforsecurity", "True") == "True":
                    return bandit.Issue(
                        severity=bandit.HIGH,
                        confidence=bandit.HIGH,
                        cwe=issue.Cwe.BROKEN_CRYPTO,
                        text=f"Use of weak {func.upper()} hash for security. "
                        "Consider usedforsecurity=False",
                        lineno=context.node.lineno,
                    )
            elif func == "new":
                args = context.call_args
                name = args[0] if args else keywords.get("name", None)
                if isinstance(name, str) and name.lower() in WEAK_HASHES:
                    if keywords.get("usedforsecurity", "True") == "True":
                        return bandit.Issue(
                            severity=bandit.HIGH,
                            confidence=bandit.HIGH,
                            cwe=issue.Cwe.BROKEN_CRYPTO,
                            text=f"Use of weak {name.upper()} hash for "
                            "security. Consider usedforsecurity=False",
                            lineno=context.node.lineno,
                        )
Beispiel #2
0
def exec_issue(level, members=""):
    if level == bandit.LOW:
        return bandit.Issue(
            severity=bandit.LOW,
            confidence=bandit.LOW,
            cwe=issue.Cwe.PATH_TRAVERSAL,
            text="Usage of tarfile.extractall(members=function(tarfile)). "
            "Make sure your function properly discards dangerous members "
            "{members}).".format(members=members),
        )
    elif level == bandit.MEDIUM:
        return bandit.Issue(
            severity=bandit.MEDIUM,
            confidence=bandit.MEDIUM,
            cwe=issue.Cwe.PATH_TRAVERSAL,
            text="Found tarfile.extractall(members=?) but couldn't "
            "identify the type of members. "
            "Check if the members were properly validated "
            "{members}).".format(members=members),
        )
    else:
        return bandit.Issue(
            severity=bandit.HIGH,
            confidence=bandit.HIGH,
            cwe=issue.Cwe.PATH_TRAVERSAL,
            text="tarfile.extractall used without any validation. "
            "Please check and discard dangerous members.",
        )
Beispiel #3
0
def ssl_with_bad_version(context, config):
    bad_ssl_versions = get_bad_proto_versions(config)
    if (context.call_function_name_qual == 'ssl.wrap_socket'):
        if context.check_call_arg_value('ssl_version', bad_ssl_versions):
            return bandit.Issue(
                severity=bandit.HIGH,
                confidence=bandit.HIGH,
                text="ssl.wrap_socket call with insecure SSL/TLS protocol "
                "version identified, security issue.  %s" %
                context.call_args_string)
    elif (context.call_function_name_qual == 'pyOpenSSL.SSL.Context'):
        if context.check_call_arg_value('method', bad_ssl_versions):
            return bandit.Issue(
                severity=bandit.HIGH,
                confidence=bandit.HIGH,
                text="SSL.Context call with insecure SSL/TLS protocol "
                "version identified, security issue.  %s" %
                context.call_args_string)

    elif (context.call_function_name_qual != 'ssl.wrap_socket'
          and context.call_function_name_qual != 'pyOpenSSL.SSL.Context'):
        if (context.check_call_arg_value('method', bad_ssl_versions) or
                context.check_call_arg_value('ssl_version', bad_ssl_versions)):
            return bandit.Issue(
                severity=bandit.MEDIUM,
                confidence=bandit.MEDIUM,
                text="Function call with insecure SSL/TLS protocol "
                "identified, possible security issue.  %s" %
                context.call_args_string)
Beispiel #4
0
def password_config_option_not_marked_secret(context, config):

    if (context.call_function_name_qual in config['function_names']
            and context.get_call_arg_at_position(0) is not None
            and context.get_call_arg_at_position(0).endswith('password')):

        # Checks whether secret=False or secret is not set (None).
        # Returns True if argument found, and matches supplied values
        # and None if argument not found at all.
        if context.check_call_arg_value(
                'secret', constants.FALSE_VALUES) in [True, None]:
            return bandit.Issue(
                severity=bandit.MEDIUM,
                confidence=bandit.MEDIUM,
                text="oslo config option not marked secret=True "
                "identified, security issue.",
                lineno=context.get_lineno_for_call_arg('secret'),
            )
        # Checks whether secret is not True, for example when its set to a
        # variable, secret=secret.
        elif not context.check_call_arg_value('secret', 'True'):
            return bandit.Issue(
                severity=bandit.MEDIUM,
                confidence=bandit.LOW,
                text="oslo config option possibly not marked secret=True "
                "identified.",
                lineno=context.get_lineno_for_call_arg('secret'),
            )
Beispiel #5
0
def jinja2_autoescape_false(context):
    # check type just to be safe
    if isinstance(context.call_function_name_qual, str):
        qualname_list = context.call_function_name_qual.split(".")
        func = qualname_list[-1]
        if "jinja2" in qualname_list and func == "Environment":
            for node in ast.walk(context.node):
                if isinstance(node, ast.keyword):
                    # definite autoescape = False
                    if getattr(node, "arg", None) == "autoescape" and (
                        getattr(node.value, "id", None) == "False"
                        or getattr(node.value, "value", None) is False
                    ):
                        return bandit.Issue(
                            severity=bandit.HIGH,
                            cwe=cwemap.CWEMAP["B701"],
                            confidence=bandit.HIGH,
                            text="Using jinja2 templates with autoescape="
                            "False is dangerous and can lead to XSS. "
                            "Use autoescape=True or use the "
                            "select_autoescape function to mitigate XSS "
                            "vulnerabilities.",
                        )
                    # found autoescape
                    if getattr(node, "arg", None) == "autoescape":
                        value = getattr(node, "value", None)
                        if (
                            getattr(value, "id", None) == "True"
                            or getattr(value, "value", None) is True
                        ):
                            return
                        # Check if select_autoescape function is used.
                        elif (
                            isinstance(value, ast.Call)
                            and getattr(value.func, "id", None)
                            == "select_autoescape"
                        ):
                            return
                        else:
                            return bandit.Issue(
                                severity=bandit.HIGH,
                                cwe=cwemap.CWEMAP["B701"],
                                confidence=bandit.MEDIUM,
                                text="Using jinja2 templates with autoescape="
                                "False is dangerous and can lead to XSS. "
                                "Ensure autoescape=True or use the "
                                "select_autoescape function to mitigate "
                                "XSS vulnerabilities.",
                            )
            # We haven't found a keyword named autoescape, indicating default
            # behavior
            return bandit.Issue(
                severity=bandit.HIGH,
                cwe=cwemap.CWEMAP["B701"],
                confidence=bandit.HIGH,
                text="By default, jinja2 sets autoescape to False. Consider "
                "using autoescape=True or use the select_autoescape "
                "function to mitigate XSS vulnerabilities.",
            )
Beispiel #6
0
def start_process_with_a_shell(context, config):
    if config and context.call_function_name_qual in config['shell']:
        return bandit.Issue(
            severity=bandit.MEDIUM,
            confidence=bandit.MEDIUM,
            text="Starting a process with a shell: check for injection."
        )
Beispiel #7
0
def dynamic_cmd_dispatch(context):
    call_node = context.node
    if not (isinstance(call_node.func, ast.Name)
            and call_node.func.id == 'getattr' and len(call_node.args) >= 2):
        return
    arg0, arg1 = call_node.args[:2]
    if not isinstance(arg0, ast.Name):
        return
    arg0 = context._context['import_aliases'].get(arg0.id, arg0.id)
    methods = SUBPROCESS.get(arg0)
    if methods is None:
        return
    confidence = bandit.LOW
    arg1_values = tuple(
        s_utils.iter_expr_literal_values(s_utils.get_top_parent_node(
            context.node),
                                         arg1,
                                         child=call_node))
    if arg1_values:
        if all((name in methods for name in arg1_values)):
            confidence = bandit.HIGH
        elif any((name in methods for name in arg1_values)):
            confidence = bandit.MEDIUM
        else:
            return

    return bandit.Issue(
        severity=bandit.HIGH,
        confidence=confidence,
        text="Retrieved a function through which os commands can be executed.")
Beispiel #8
0
def insecure_hashlib_new_algorithm(context):
    call_node = context.node
    if not (context.call_function_name_qual == 'hashlib.new'
            and len(call_node.args)):
        return
    arg0 = call_node.args[0]
    parent = s_utils.get_top_parent_node(call_node)
    insecure_algorithms = ('md2', 'md4', 'md5')
    confidence = None
    if isinstance(arg0, ast.Str) and arg0.s.lower() in insecure_algorithms:
        confidence = bandit.HIGH
    elif isinstance(arg0, ast.Name):
        algorithms = tuple(
            s_utils.iter_expr_literal_values(parent, arg0, call_node))
        if algorithms and all(algo.lower() in insecure_algorithms
                              for algo in algorithms):
            confidence = bandit.HIGH
        elif algorithms and any(algo.lower() in insecure_algorithms
                                for algo in algorithms):
            confidence = bandit.MEDIUM
    if confidence is None:
        return
    return bandit.Issue(severity=bandit.MEDIUM,
                        confidence=confidence,
                        text='Use of insecure MD2, MD4, or MD5 hash function.')
Beispiel #9
0
def snmp_insecure_version_check(context):
    """**B508: Checking for insecure SNMP versions**

    This test is for checking for the usage of insecure SNMP version like
      v1, v2c

    Using the pysnmp documentation:
      http://snmplabs.com/pysnmp/examples/hlapi/asyncore/sync/manager/cmdgen/snmp-versions.html

    Please update your code to use more secure versions of SNMP.

    .. versionadded:: 1.7.2
    """

    if context.call_function_name_qual == "CommunityData":
        # We called community data. Lets check our args
        if context.check_call_arg_value(
            "mpModel", 0
        ) or context.check_call_arg_value("mpModel", 1):
            return bandit.Issue(
                severity=bandit.MEDIUM,
                confidence=bandit.HIGH,
                text="The use of SNMPv1 and SNMPv2 is insecure. "
                "You should use SNMPv3 if able.",
                lineno=context.get_lineno_for_call_arg("CommunityData"),
            )
Beispiel #10
0
def ssl_with_no_version(context):
    """Test for SSL use with no version specified

    This plugin is part of a family of tests that detect the use of known bad
    versions of SSL/TLS, please see :doc:`../plugins/ssl_with_bad_version` for
    a complete discussion. Specifically, This plugin test scans for specific
    methods in Python's native SSL/TLS support and the pyOpenSSL module that
    configure the version of SSL/TLS protocol to use. These methods are known
    to provide default value that maximize compatibility, but permit use of the
    aforementioned broken protocol versions. A LOW severity warning will be
    reported whenever this is detected.

    See also:

    - :doc:`../plugins/ssl_with_bad_version`
    - :doc:`../plugins/ssl_with_bad_defaults`


    Config Options:

    This test shares the configuration provided for the standard
    :doc:`../plugins/ssl_with_bad_version` test, please refer to its
    documentation.

    Sample Output:

    .. code-block:: none

        >> Issue: ssl.wrap_socket call with no SSL/TLS protocol version
        specified, the default SSLv23 could be insecure, possible security
        issue.
           Severity: Low   Confidence: Medium
           Location: ./examples/ssl-insecure-version.py:23
        22
        23  ssl.wrap_socket()
        24

    References:

    - http://heartbleed.com/
    - https://poodlebleed.com/
    - https://security.openstack.org/
    - https://security.openstack.org/guidelines/dg_move-data-securely.html

    .. versionadded:: 0.9.0
    """
    if (context.call_function_name_qual == 'ssl.wrap_socket'):
        if context.check_call_arg_value('ssl_version') is None:
            # check_call_arg_value() returns False if the argument is found
            # but does not match the supplied value (or the default None).
            # It returns None if the arg_name passed doesn't exist. This
            # tests for that (ssl_version is not specified).
            return bandit.Issue(
                severity=bandit.LOW,
                confidence=bandit.MEDIUM,
                text="ssl.wrap_socket call with no SSL/TLS protocol version "
                "specified, the default SSLv23 could be insecure, "
                "possible security issue.",
                lineno=context.get_lineno_for_call_arg('ssl_version'),
            )
def _report(value):
    return bandit.Issue(
        severity=bandit.LOW,
        confidence=bandit.MEDIUM,
        cwe=issue.Cwe.HARD_CODED_PASSWORD,
        text=("Possible hardcoded password: '******'" % value),
    )
def hardcoded_password(context, config):
    word_list_file = None
    word_list = []
    # try to read the word list file from config
    if (config is not None and 'word_list' in config):
        try:
            word_list_file = find_word_list(config['word_list'])
        except RuntimeError as e:
            warnings.warn(e.message)
            return

    # try to open the word list file and read passwords from it
    try:
        f = open(word_list_file, 'r')
    except (OSError, IOError):
        raise RuntimeError("Could not open word_list (from config"
                           " file): %s" % word_list_file)
    else:
        for word in f:
            word_list.append(word.strip())
        f.close()

    # for every password in the list, check against the current string
    for word in word_list:
        if context.string_val and context.string_val == word:
            return bandit.Issue(
                severity=bandit.LOW,
                confidence=bandit.LOW,
                text="Possible hardcoded password '(%s)'" % word
            )
Beispiel #13
0
def hardcoded_bind_all_interfaces(context):
    if context.string_val == '0.0.0.0':
        return bandit.Issue(
            severity=bandit.MEDIUM,
            confidence=bandit.MEDIUM,
            text="Possible binding to all interfaces."
        )
def key_generation_module_test(context):
    if isinstance(context.call_function_name_qual, str):
        qualname_list = context.call_function_name_qual.split('.')
        func = qualname_list[-1]
        if 'key_generation' in qualname_list and func == 'key_generation_def':

            with open("./policy/policy.json", "r") as policy:
                policy_dict = json.load(policy)
            if policy_dict['policy']['identity_and_access']['identity'][
                    'authenticator']['key']:
                key_generation_module = policy_dict['policy'][
                    'identity_and_access']['identity']['authenticator']['key'][
                        'key_generation_module']

            args = context.call_args
            keywords = context.call_keywords
            #name = args[0] if args else keywords['name']

            return bandit.Issue(
                severity=bandit.LOW,
                confidence=bandit.LOW,
                text=
                'INFORMATIONAL:  The approved modules for secure pseudorandom number generation are: '
                + str(key_generation_module) +
                ' Please review to validate you are using one.  If so, please consider this informational.',
                lineno=context.node.lineno)
Beispiel #15
0
def key_generation_length_test(context):
    if isinstance(context.call_function_name_qual, str):
        qualname_list = context.call_function_name_qual.split('.')
        func = qualname_list[-1]
        if 'key_generation' in qualname_list and func == 'key_generation_def':

            with open("./policy/policy.json", "r") as policy:
                policy_dict = json.load(policy)
            if policy_dict['policy']['identity_and_access']['identity'][
                    'authenticator']['key']:
                key_generation_length = policy_dict['policy'][
                    'identity_and_access']['identity']['authenticator']['key'][
                        'key_generation_length']

            args = context.call_args
            keywords = context.call_keywords
            #name = args[0] if args else keywords['name']

            return bandit.Issue(
                severity=bandit.LOW,
                confidence=bandit.LOW,
                text='INFORMATIONAL:  Cryptographic keys must be at least ' +
                str(key_generation_length) +
                ' bytes to be considered secure.  Please review to validate.',
                lineno=context.node.lineno)
Beispiel #16
0
def blacklist_calls(context, config):
    if config is not None and 'bad_name_sets' in config:
        sets = config['bad_name_sets']
    else:
        sets = []

    checks = []

    # load all the checks from the config file
    for cur_item in sets:
        for blacklist_item in cur_item:
            blacklist_object = cur_item[blacklist_item]
            cur_check = _get_tuple_for_item(blacklist_object)
            # skip bogus checks
            if cur_check:
                checks.append(cur_check)

    # for each check, go through and see if it matches all qualifications
    for check in checks:
        confidence = 'HIGH'
        does_match = True
        # item 0=qualnames, 1=names, 2=message, 3=level, 4=params
        if does_match and check[0]:
            matched_qn = False
            for qn in check[0]:
                if context.call_function_name_qual == qn:
                    matched_qn = True
            if not matched_qn:
                does_match = False

        if does_match and check[1]:
            matched_n = False
            for n in check[1]:
                if context.call_function_name == n:
                    matched_n = True
            if not matched_n:
                does_match = False

        if does_match and check[4]:
            matched_p = False
            for p in check[4]:
                for arg_num in range(0, context.call_args_count - 1):
                    if p == context.get_call_arg_at_position(arg_num):
                        matched_p = True
            if not matched_p:
                does_match = False

        if does_match:
            level = None
            if check[3] == 'HIGH':
                level = bandit.HIGH
            elif check[3] == 'MEDIUM':
                level = bandit.MEDIUM
            elif check[3] == 'LOW':
                level = bandit.LOW

            return bandit.Issue(
                severity=level, confidence=confidence,
                text="%s  %s" % (check[2], context.call_args_string)
            )
def _report(value):
    return bandit.Issue(
        severity=bandit.LOW,
        cwe=cwemap.CWEMAP["B105"],
        confidence=bandit.MEDIUM,
        text=("Possible hardcoded password: '******'" % value),
    )
Beispiel #18
0
def linux_commands_wildcard_injection(context, config):
    if not ("shell" in config and "subprocess" in config):
        return

    vulnerable_funcs = ["chown", "chmod", "tar", "rsync"]
    if context.call_function_name_qual in config["shell"] or (
            context.call_function_name_qual in config["subprocess"]
            and context.check_call_arg_value("shell", "True")):
        if context.call_args_count >= 1:
            call_argument = context.get_call_arg_at_position(0)
            argument_string = ""
            if isinstance(call_argument, list):
                for li in call_argument:
                    argument_string = argument_string + " %s" % li
            elif isinstance(call_argument, str):
                argument_string = call_argument

            if argument_string != "":
                for vulnerable_func in vulnerable_funcs:
                    if (vulnerable_func in argument_string
                            and "*" in argument_string):
                        return bandit.Issue(
                            severity=bandit.HIGH,
                            confidence=bandit.MEDIUM,
                            text="Possible wildcard injection in call: %s" %
                            context.call_function_name_qual,
                            lineno=context.get_lineno_for_call_arg("shell"),
                        )
Beispiel #19
0
def start_process_with_no_shell(context, config):
    if config and context.call_function_name_qual in config['no_shell']:
        return bandit.Issue(
            severity=bandit.LOW,
            confidence=bandit.MEDIUM,
            text="Starting a process without a shell."
        )
Beispiel #20
0
def linux_commands_wildcard_injection(context, config):
    if not ('shell' in config and 'subprocess' in config):
        return

    vulnerable_funcs = ['chown', 'chmod', 'tar', 'rsync']
    if context.call_function_name_qual in config['shell'] or (
            context.call_function_name_qual in config['subprocess'] and
            context.check_call_arg_value('shell', 'True')):
        if context.call_args_count >= 1:
            call_argument = context.get_call_arg_at_position(0)
            argument_string = ''
            if isinstance(call_argument, list):
                for li in call_argument:
                    argument_string = argument_string + ' %s' % li
            elif isinstance(call_argument, str):
                argument_string = call_argument

            if argument_string != '':
                for vulnerable_func in vulnerable_funcs:
                    if(
                            vulnerable_func in argument_string and
                            '*' in argument_string
                    ):
                        return bandit.Issue(
                            severity=bandit.HIGH,
                            confidence=bandit.MEDIUM,
                            text="Possible wildcard injection in call: %s" %
                            context.call_function_name_qual,
                            lineno=context.get_lineno_for_call_arg('shell'),
                        )
Beispiel #21
0
def blacklist_calls(context, config):
    _ensure_cache(config)
    checks = _cached_blacklist_checks

    # for each check, go through and see if it matches all qualifications
    for qualnames, names, message_tpl, level, params in checks:
        confidence = 'HIGH'
        does_match = True
        # item 0=qualnames, 1=names, 2=message, 3=level, 4=params
        if does_match and qualnames:
            # match the qualname - respect wildcards if present
            does_match = any(
                fnmatch.fnmatch(context.call_function_name_qual, qn)
                for qn in qualnames)

        if does_match and names:
            does_match = any(context.call_function_name == n for n in names)

        if does_match and params:
            matched_p = False
            for p in params:
                for arg_num in range(0, context.call_args_count - 1):
                    if p == context.get_call_arg_at_position(arg_num):
                        matched_p = True
            if not matched_p:
                does_match = False

        if does_match:
            message = message_tpl.replace("{func}",
                                          context.call_function_name_qual)

            return bandit.Issue(severity=level,
                                confidence=confidence,
                                text=message,
                                ident=context.call_function_name_qual)
Beispiel #22
0
def snmp_crypto_check(context):
    """**B509: Checking for weak cryptography**

    This test is for checking for the usage of insecure SNMP cryptography:
      v3 using noAuthNoPriv.

    Using the pysnmp documentation:
      http://snmplabs.com/pysnmp/examples/hlapi/asyncore/sync/manager/cmdgen/snmp-versions.html

    Please update your code to use more secure versions of SNMP. For example:

    Instead of:
      `CommunityData('public', mpModel=0)`

    Use (Defaults to usmHMACMD5AuthProtocol and usmDESPrivProtocol
      `UsmUserData("securityName", "authName", "privName")`

    .. versionadded:: 1.7.2
    """

    if context.call_function_name_qual == "UsmUserData":
        if context.call_args_count < 3:
            return bandit.Issue(
                severity=bandit.MEDIUM,
                confidence=bandit.HIGH,
                text="You should not use SNMPv3 without encryption. "
                "noAuthNoPriv & authNoPriv is insecure",
                lineno=context.get_lineno_for_call_arg("UsmUserData"),
            )
Beispiel #23
0
def exec_issue():
    return bandit.Issue(
        severity=bandit.MEDIUM,
        cwe=cwemap.CWEMAP["B102"],
        confidence=bandit.HIGH,
        text="Use of exec detected.",
    )
Beispiel #24
0
def string_encode(context):
    #import pdb; pdb.set_trace()
    if isinstance(context.node._bandit_parent, ast.Attribute):
        if context.node._bandit_parent.attr == 'encode':
            return bandit.Issue(severity=bandit.MEDIUM,
                                confidence=bandit.MEDIUM,
                                text="string_encode")
Beispiel #25
0
def _classify_key_size(config, key_type, key_size):
    if isinstance(key_size, str):
        # size provided via a variable - can't process it at the moment
        return

    key_sizes = {
        "DSA": [
            (config["weak_key_size_dsa_high"], bandit.HIGH),
            (config["weak_key_size_dsa_medium"], bandit.MEDIUM),
        ],
        "RSA": [
            (config["weak_key_size_rsa_high"], bandit.HIGH),
            (config["weak_key_size_rsa_medium"], bandit.MEDIUM),
        ],
        "EC": [
            (config["weak_key_size_ec_high"], bandit.HIGH),
            (config["weak_key_size_ec_medium"], bandit.MEDIUM),
        ],
    }

    for size, level in key_sizes[key_type]:
        if key_size < size:
            return bandit.Issue(
                severity=level,
                confidence=bandit.HIGH,
                cwe=issue.Cwe.INADEQUATE_ENCRYPTION_STRENGTH,
                text="%s key sizes below %d bits are considered breakable. "
                % (key_type, size),
            )
Beispiel #26
0
def exec_issue():
    return bandit.Issue(
        severity=bandit.MEDIUM,
        confidence=bandit.HIGH,
        cwe=issue.Cwe.OS_COMMAND_INJECTION,
        text="Use of exec detected.",
    )
def set_bad_file_permissions(context):
    if "chmod" in context.call_function_name:
        if context.call_args_count == 2:
            mode = context.get_call_arg_at_position(1)

            if (
                mode is not None
                and isinstance(mode, int)
                and _stat_is_dangerous(mode)
            ):
                # world writable is an HIGH, group executable is a MEDIUM
                if mode & stat.S_IWOTH:
                    sev_level = bandit.HIGH
                else:
                    sev_level = bandit.MEDIUM

                filename = context.get_call_arg_at_position(0)
                if filename is None:
                    filename = "NOT PARSED"
                return bandit.Issue(
                    severity=sev_level,
                    confidence=bandit.HIGH,
                    cwe=issue.Cwe.INCORRECT_PERMISSION_ASSIGNMENT,
                    text="Chmod setting a permissive mask %s on file (%s)."
                    % (oct(mode), filename),
                )
Beispiel #28
0
def secure_hash_test(context):
    if isinstance(context.call_function_name_qual, str):
        qualname_list = context.call_function_name_qual.split('.')
        func = qualname_list[-1]
        if ('secure_hash' in qualname_list and func == 'secure_hash_def'):
            args = context.call_args
            keywords = context.call_keywords
            name = args[0] if args else keywords['name']

            with open("./policy/policy.json", "r") as policy:
                policy_dict = json.load(policy)

            if policy_dict['policy']['data']['data_transformation'][
                    'data_confidentiality']['hash']['secure_hash']:
                secure_hash_algorithm = policy_dict['policy']['data'][
                    'data_transformation']['data_confidentiality']['hash'][
                        'secure_hash']

            if name.lower() not in secure_hash_algorithm:
                return bandit.Issue(
                    severity=bandit.HIGH,
                    confidence=bandit.HIGH,
                    text='Cryptographically weak hash algorithm detected. ' +
                    name +
                    ' is considered weak and should not be used for cryptographic purposes. '
                    +
                    'Please consult policy for acceptable secure hash algorithms.',
                    lineno=context.node.lineno)
Beispiel #29
0
def assert_used(context):
    return bandit.Issue(
        severity=bandit.LOW,
        confidence=bandit.HIGH,
        text=("Use of assert detected. The enclosed code "
              "will be removed when compiling to optimised byte code.")
    )
def django_extra_used(context):
    """**B610: Potential SQL injection on extra function**

    .. seealso::

     - https://docs.djangoproject.com/en/dev/topics/security/\
#sql-injection-protection

    .. versionadded:: 1.5.0

    """
    description = "Use of extra potential SQL attack vector."
    if context.call_function_name == "extra":
        kwargs = keywords2dict(context.node.keywords)
        args = context.node.args
        if args:
            if len(args) >= 1:
                kwargs["select"] = args[0]
            if len(args) >= 2:
                kwargs["where"] = args[1]
            if len(args) >= 3:
                kwargs["params"] = args[2]
            if len(args) >= 4:
                kwargs["tables"] = args[3]
            if len(args) >= 5:
                kwargs["order_by"] = args[4]
            if len(args) >= 6:
                kwargs["select_params"] = args[5]
        insecure = False
        for key in ["where", "tables"]:
            if key in kwargs:
                if isinstance(kwargs[key], ast.List):
                    for val in kwargs[key].elts:
                        if not isinstance(val, ast.Str):
                            insecure = True
                            break
                else:
                    insecure = True
                    break
        if not insecure and "select" in kwargs:
            if isinstance(kwargs["select"], ast.Dict):
                for k in kwargs["select"].keys:
                    if not isinstance(k, ast.Str):
                        insecure = True
                        break
                if not insecure:
                    for v in kwargs["select"].values:
                        if not isinstance(v, ast.Str):
                            insecure = True
                            break
            else:
                insecure = True

        if insecure:
            return bandit.Issue(
                severity=bandit.MEDIUM,
                cwe=cwemap.CWEMAP["B611"],
                confidence=bandit.MEDIUM,
                text=description,
            )