Пример #1
0
    def get_func_cfg_with_tainted_args(self, definition):
        """Build a function cfg and return it, with all arguments tainted."""
        log.debug("Getting CFG for %s", definition.name)
        func_cfg = make_cfg(definition.node, self.project_modules,
                            self.local_modules, definition.path,
                            definition.module_definitions)

        args = Arguments(definition.node.args)
        if args:
            function_entry_node = func_cfg.nodes[0]
            function_entry_node.outgoing = list()
            first_node_after_args = func_cfg.nodes[1]
            first_node_after_args.ingoing = list()

            # We are just going to give all the tainted args the lineno of the def
            definition_lineno = definition.node.lineno

            # Taint all the arguments
            for i, arg in enumerate(args):
                node_type = TaintedNode
                if i == 0 and arg == 'self':
                    node_type = AssignmentNode

                arg_node = node_type(label=arg,
                                     left_hand_side=arg,
                                     ast_node=None,
                                     right_hand_side_variables=[],
                                     line_number=definition_lineno,
                                     path=definition.path)
                function_entry_node.connect(arg_node)
                # 1 and not 0 so that Entry Node remains first in the list
                func_cfg.nodes.insert(1, arg_node)
                arg_node.connect(first_node_after_args)

        return func_cfg
Пример #2
0
    def main(self, dirname):  # noqa: C901
        command_line_args = [dirname, "-oVulnerabilityResultsTemp.txt", "-r"]
        args = parse_args(command_line_args)

        logging_level = (logging.ERROR if not args.verbose else
                         logging.WARN if args.verbose == 1 else
                         logging.INFO if args.verbose == 2 else logging.DEBUG)
        logging.basicConfig(level=logging_level,
                            format='[%(levelname)s] %(name)s: %(message)s')

        files = discover_files(args.targets, args.excluded_paths,
                               args.recursive)

        nosec_lines = defaultdict(set)

        if args.project_root:
            directory = os.path.normpath(args.project_root)
            project_modules = get_modules(
                directory, prepend_module_root=args.prepend_module_root)

        cfg_list = list()
        for path in sorted(files):
            print(path)
            log.info("Processing %s", path)
            try:
                if not args.ignore_nosec:
                    nosec_lines[path] = retrieve_nosec_lines(path)
                if not args.project_root:
                    directory = os.path.dirname(path)
                    project_modules = get_modules(
                        directory,
                        prepend_module_root=args.prepend_module_root)

                local_modules = get_directory_modules(directory)
                tree = generate_ast(path)
                connection_checker = ConnectionChecker()
                if True:  # connection_checker.check_for_connection(tree):
                    print("file passed connection check")
                    cfg = make_cfg(
                        tree,
                        project_modules,
                        local_modules,
                        path,
                        allow_local_directory_imports=args.allow_local_imports)
                    print("cfg made")
                    # draw.draw_cfg(cfg, "test_output")

                    cfg_list = [cfg]

                    framework_route_criteria = is_function  # is_user_input_function

                    # Add all the route functions to the cfg_list
                    FrameworkAdaptor(cfg_list, project_modules, local_modules,
                                     framework_route_criteria)
                    self.S += 1
                    '''
                    with open("result_cfg.txt", "w") as outFile:
                        for def_cfg in cfg_list:
                            outFile.write("New cfg in cfg_list \n")
                            outFile.write(def_cfg.__repr__())
                    '''
            except Exception as err:
                print("There was an error : " + "[" + str(path) + "] " +
                      str(err))
                traceback.print_exc()
                self.F += 1
        initialize_constraint_table(cfg_list)
        log.info("Analysing")
        print("Analysing")
        analyse(cfg_list)
        log.info("Finding vulnerabilities")
        print("Finding vulnerabilities")
        vulnerabilities = find_vulnerabilities(cfg_list,
                                               args.blackbox_mapping_file,
                                               args.trigger_word_file,
                                               args.interactive, nosec_lines)

        if args.baseline:
            vulnerabilities = get_vulnerabilities_not_in_baseline(
                vulnerabilities, args.baseline)

        args.formatter.report(vulnerabilities, args.output_file,
                              not args.only_unsanitised)
        args.output_file.close()
        has_unsanitised_vulnerabilities = any(
            not isinstance(v, SanitisedVulnerability) for v in vulnerabilities)
        if has_unsanitised_vulnerabilities:
            print("There are unsanitised vulnerabilities in " + dirname)
Пример #3
0
def main():
    """ entry point to the interpreter.

    Check arguments and run the different steps.
    parsing, printing, free variables calculation and typechecking.
    """
    arg_parser = argparse.ArgumentParser(
        description=
        'Information-flow typechecker for a simple imperative language.')
    arg_parser.add_argument("file",
                            metavar="FILE",
                            help="file to be processed",
                            nargs=1)
    arg_parser.add_argument(
        "-o",
        dest='target',
        help="specify target dot file. To be used with -g option",
        nargs=1)
    arg_parser.add_argument("-v",
                            dest='verbose',
                            action='store_true',
                            help='verbose mode. Print debug information')
    arg_parser.add_argument(
        "-g",
        dest='graph',
        action='store_true',
        help='Control flow graph. Generate control flow graph')
    args = arg_parser.parse_args()

    verbose = args.verbose
    graph = args.graph
    target = args.target

    if target and not graph:
        print('target file ignored, to be used with -g option')

    filename = args.file[0]

    # TODO(Phil) handle exception
    with open(filename, 'r') as myfile:
        input_program = myfile.read()

    if verbose:
        print("--- parsing", filename)

    prog = parser.parser().parse(input_program)

    if graph:
        g = cfg.make_cfg(prog)

        # TODO(phil) rewrite this and handle exception
        if not target:
            # no output specified, use stdout
            cfg.print_dot(g, sys.stdout)
        else:
            with open(target[0], 'w') as myfile:
                cfg.print_dot(g, myfile)
            myfile.close()

        exit(0)

    fv = free_vars.free_vars_prog(prog)

    if verbose:
        print("--- pretty print")
        ast.print_prog(prog)

    if verbose:
        print('--- typechecking')

    gamma = lat_types.create_init_env(fv)

    if verbose:
        print('initial environment:', gamma)

    new_gamma = typing.typecheck(gamma, prog)

    print('final environment:', new_gamma)
Пример #4
0
    def http_finder(self, dirname):  # noqa: C901
        command_line_args = [dirname, "-r"]
        args = parse_args(command_line_args)

        logging_level = (logging.ERROR if not args.verbose else
                         logging.WARN if args.verbose == 1 else
                         logging.INFO if args.verbose == 2 else logging.DEBUG)
        logging.basicConfig(level=logging_level,
                            format='[%(levelname)s] %(name)s: %(message)s')

        files = discover_files(args.targets, args.excluded_paths,
                               args.recursive)

        nosec_lines = defaultdict(set)

        if args.project_root:
            directory = os.path.normpath(args.project_root)
            project_modules = get_modules(
                directory, prepend_module_root=args.prepend_module_root)

        for path in sorted(files):
            print(path)
            log.info("Processing %s", path)
            try:
                if not args.ignore_nosec:
                    nosec_lines[path] = retrieve_nosec_lines(path)
                if not args.project_root:
                    directory = os.path.dirname(path)
                    project_modules = get_modules(
                        directory,
                        prepend_module_root=args.prepend_module_root)

                local_modules = get_directory_modules(directory)
                tree = generate_ast(path)
                connection_checker = ConnectionChecker()
                if connection_checker.check_for_connection(tree):
                    print("file passed connection check")
                    cfg = make_cfg(
                        tree,
                        project_modules,
                        local_modules,
                        path,
                        allow_local_directory_imports=args.allow_local_imports)
                    print("cfg made")
                    # draw.draw_cfg(cfg, "test_output")
                    call_nodes = []
                    input_nodes = []
                    for cfg_node in cfg.nodes:
                        ast_node = cfg_node.ast_node
                        if isinstance(ast_node, ast.Call):
                            if is_connection_method(ast_node):
                                call_nodes.append(cfg_node)
                            elif is_user_input(ast_node):
                                input_nodes.append(cfg_node)
                    result_set = set()
                    for node in input_nodes:
                        result_set.add(node)
                    for x, n in enumerate(call_nodes):
                        # with open("Analysis.txt", "a") as outFile:
                        # outFile.write(path + " " + str(x) + "\n")
                        result_set.update(reverse_traverse(n))
                    numHttps = 0
                    numHttp = 0
                    numUserInput = 0
                    input_finder = ArgvChecker()
                    numUserInput += input_finder.find_args(tree)
                    for node in result_set:
                        if node.label.count("https") > 0:
                            numHttps += 1
                        elif node.label.count("http") > 0:
                            numHttp += 1
                        else:
                            numUserInput += 1
                    with open("Stats.txt", "a") as output:
                        output.write(path + ": http: " + str(numHttp) +
                                     " https: " + str(numHttps) +
                                     " UserInput: " + str(numUserInput) + "\n")
                    self.S += 1
                    '''
                    with open("result_cfg.txt", "w") as outFile:
                        for def_cfg in cfg_list:
                            outFile.write("New cfg in cfg_list \n")
                            outFile.write(def_cfg.__repr__())
                    '''
            except Exception as err:
                print("There was an error : " + "[" + str(path) + "] " +
                      str(err))
                traceback.print_exc()
                self.F += 1
Пример #5
0
def main(dirname):  # noqa: C901
    global S
    global F
    command_line_args = [dirname, "-r"]
    args = parse_args(command_line_args)

    logging_level = (logging.ERROR
                     if not args.verbose else logging.WARN if args.verbose == 1
                     else logging.INFO if args.verbose == 2 else logging.DEBUG)
    logging.basicConfig(level=logging_level,
                        format='[%(levelname)s] %(name)s: %(message)s')

    files = discover_files(args.targets, args.excluded_paths, args.recursive)

    nosec_lines = defaultdict(set)

    if args.project_root:
        directory = os.path.normpath(args.project_root)
        project_modules = get_modules(
            directory, prepend_module_root=args.prepend_module_root)

    cfg_list = list()
    for path in sorted(files):
        print(path)
        log.info("Processing %s", path)
        if not args.ignore_nosec:
            nosec_lines[path] = retrieve_nosec_lines(path)
        if not args.project_root:
            directory = os.path.dirname(path)
            project_modules = get_modules(
                directory, prepend_module_root=args.prepend_module_root)

        local_modules = get_directory_modules(directory)
        tree = generate_ast(path)
        connection_checker = ConnectionChecker()
        if connection_checker.check_for_connection(tree):
            print("file passed connection check")
            cfg = make_cfg(
                tree,
                project_modules,
                local_modules,
                path,
                allow_local_directory_imports=args.allow_local_imports)
            try:
                cfg = make_cfg(
                    tree,
                    project_modules,
                    local_modules,
                    path,
                    allow_local_directory_imports=args.allow_local_imports)
                print("cfg made")
                # draw.draw_cfg(cfg, "test_output")
                S += 1
                call_nodes = []
                input_nodes = []
                for cfg_node in cfg.nodes:
                    ast_node = cfg_node.ast_node
                    if isinstance(ast_node, ast.Call):
                        if is_connection_method(ast_node):
                            call_nodes.append(cfg_node)
                        elif is_user_input(ast_node):
                            input_nodes.append(cfg_node)
                result_set = set()
                # for node in input_nodes:
                #    result_set.add(node)
                for x, n in enumerate(call_nodes):
                    # with open("Analysis.txt", "a") as outFile:
                    # outFile.write(path + " " + str(x) + "\n")
                    result_set.update(reverse_traverse(n))
                numHttps = 0
                numHttp = 0
                numUserInput = 0
                input_finder = ArgvChecker()
                # numUserInput += input_finder.find_args(tree)
                for node in result_set:
                    if node.label.count("https") > 0:
                        numHttps += 1
                    elif node.label.count("http") > 0:
                        numHttp += 1
                    else:
                        numUserInput += 1
                with open("Stats.txt", "a") as output:
                    output.write(path + ": http: " + str(numHttp) +
                                 " https: " + str(numHttps) + " UserInput: " +
                                 str(numUserInput) + "\n")
            except Exception as err:
                print("There was an error : " + "[" + str(path) + "]" +
                      str(err))
                F += 1
        cfg_list = [cfg]

        framework_route_criteria = is_function  # is_user_input_function

        # Add all the route functions to the cfg_list
        FrameworkAdaptor(cfg_list, project_modules, local_modules,
                         framework_route_criteria)
        with open("result_cfg.txt", "w") as outFile:
            for def_cfg in cfg_list:
                outFile.write("New cfg in cfg_list \n")
                outFile.write(def_cfg.__repr__())
    initialize_constraint_table(cfg_list)
    log.info("Analysing")
    analyse(cfg_list)
    log.info("Finding vulnerabilities")
    vulnerabilities = find_vulnerabilities(cfg_list,
                                           args.blackbox_mapping_file,
                                           args.trigger_word_file,
                                           args.interactive, nosec_lines)

    if args.baseline:
        vulnerabilities = get_vulnerabilities_not_in_baseline(
            vulnerabilities, args.baseline)

    args.formatter.report(vulnerabilities, args.output_file,
                          not args.only_unsanitised)

    has_unsanitised_vulnerabilities = any(
        not isinstance(v, SanitisedVulnerability) for v in vulnerabilities)
    if has_unsanitised_vulnerabilities:
        sys.exit(1)