Exemple #1
0
def add_findings(title, scan_rules, line_no, lines, full_file_path):
    """Add Findings"""
    filename = ntpath.basename(full_file_path)
    finding = {}
    finding["title"] = title
    finding["description"] = scan_rules["desc"][title]
    finding["tag"] = scan_rules["tag"][title]
    finding["line"] = line_no + 1
    finding["lines"] = get_lines(line_no, lines)
    finding["filename"] = filename
    finding["path"] = full_file_path.replace(settings.UPLOAD_FOLDER, "", 1)
    finding["sha2"] = utils.gen_sha256_hash(finding["lines"])
    return finding
Exemple #2
0
def general_code_analysis(paths):
    """Static Code Analysis"""
    try:
        scan_results = {}
        scan_rules = read_rules()
        security_issues = []
        good_finding = []
        missing_header = []
        all_files = []
        # Initializing Security Header flag as not present
        header_found = {}
        sec_issues_by_tag = {}
        good_finding_by_tag = {}
        missing_header_by_tag = {}
        vuln_n_count = {}
        count = {}
        # Sort By Tag
        tags = {'rce': 'Remote Command Execution',
                'rci': 'Remote Code Injection',
                'ssrf': 'Server Side Request Forgery',
                'module': 'Vulnerable Node Module',
                'node': 'Application Related',
                'web': 'Web Security',
                'dir': 'Directory Traversal',
                'opr': 'Open Redirect Vulnerability',
                'sqli': 'SQL Injection (SQLi)',
                'xss': 'Cross Site Scripting (XSS)',
                'nosqli': 'NoSQL Injection',
                'hhi': 'HTTP Header Injection',
                }
        for path in paths:
            for header in scan_rules["missing_sec_header"].iterkeys():
                header_found[header] = 0
            print "\n[INFO] Running Static Analyzer Running on - " + path + "\n"
            for root, _, files in os.walk(path):
                for filename in files:
                    full_file_path = os.path.join(root, filename)
                    relative_path = full_file_path.replace(path, "")
                    all_files.append({relative_path.replace("/", "", 1): full_file_path.replace(settings.UPLOAD_FOLDER, "", 1)})
                    data = is_valid_node(filename, full_file_path)
                    if data is not None:
                        # print relative_path
                        beautified_data = None
                        lines = data.splitlines()
                        if len(lines) <= 2:
                            # Possible Minified Single Line Code
                            try:
                                # Try Because of Possible Bug in JS Beautifier
                                beautified_data = jsbeautifier.beautify(data)
                                lines = beautified_data.splitlines()
                            except:
                                pass
                        for line_no, line in enumerate(lines):
                            # Avoid Comments - Multiline is a problem still
                            if not line.lstrip().startswith("//") and not line.lstrip().startswith("/*"):
                                # Limit the no of caracters in a line to 2000
                                line = line[0:2000]
                                # Vulnerability String Match
                                for rule_key in scan_rules["vuln_rules"].iterkeys():
                                    if scan_rules["vuln_rules"][rule_key] in line:
                                        finding = {}
                                        finding["title"] = rule_key
                                        finding["description"] = scan_rules[
                                            "desc"][rule_key]
                                        finding["tag"] = scan_rules[
                                            "tag"][rule_key]
                                        finding["line"] = line_no + 1
                                        finding["lines"] = get_lines(
                                            line_no, lines)
                                        finding["filename"] = filename
                                        finding["path"] = full_file_path.replace(settings.UPLOAD_FOLDER,"",1)
                                        finding["sha2"] = utils.gen_sha256_hash(
                                            str(finding["lines"]))
                                        security_issues.append(finding)
                                # Vulnerability Regex Match
                                for regex in scan_rules["vuln_regex"].iterkeys():
                                    if re.search(scan_rules["vuln_regex"][regex], line):
                                        finding = {}
                                        finding["title"] = regex
                                        finding["description"] = scan_rules[
                                            "desc"][regex]
                                        finding["tag"] = scan_rules[
                                            "tag"][regex]
                                        finding["line"] = line_no + 1
                                        finding["lines"] = get_lines(
                                            line_no, lines)
                                        finding["filename"] = filename
                                        finding["path"] = full_file_path.replace(settings.UPLOAD_FOLDER,"",1)
                                        finding["sha2"] = utils.gen_sha256_hash(
                                            str(finding["lines"]))
                                        security_issues.append(finding)
                                # Vulnerability Multi Regex Match
                                for mulregex in scan_rules["vuln_mul_regex"].iterkeys():
                                    sig_source = scan_rules["vuln_mul_regex"][
                                        mulregex]["sig_source"]
                                    sig_line = scan_rules["vuln_mul_regex"][
                                        mulregex]["sig_line"]
                                    if re.search(sig_source, data):
                                        if re.search(sig_line, line):
                                            finding = {}
                                            finding["title"] = mulregex
                                            finding["description"] = scan_rules[
                                                "desc"][mulregex]
                                            finding["tag"] = scan_rules[
                                                "tag"][mulregex]
                                            finding["line"] = line_no + 1
                                            finding["lines"] = get_lines(
                                                line_no, lines)
                                            finding["filename"] = filename
                                            finding["path"] = full_file_path.replace(settings.UPLOAD_FOLDER,"",1)
                                            finding["sha2"] = utils.gen_sha256_hash(
                                                str(finding["lines"]))
                                            security_issues.append(finding)
                                # Dynamic Regex
                                for dynregex in scan_rules["vuln_dyn_regex"].iterkeys():
                                    signature = scan_rules["vuln_dyn_regex"][
                                        dynregex]["signature"]
                                    dyn_sig = scan_rules["vuln_dyn_regex"][
                                        dynregex]["dyn_sig"]
                                    sig = re.search(signature, line)
                                    if sig:
                                        index = line.find(sig.group())
                                        dyn_variable = line[0:index]
                                        dyn_variable = dyn_variable.replace(
                                            "var", "").replace("=", "").strip()
                                        if re.match(r'^[\w]+$', dyn_variable):
                                            dyn_sig = dyn_variable + dyn_sig
                                            for line_no, nline in enumerate(lines):
                                                if re.search(dyn_sig, nline):
                                                    finding = {}
                                                    finding["title"] = dynregex
                                                    finding["description"] = scan_rules[
                                                        "desc"][dynregex]
                                                    finding["tag"] = scan_rules[
                                                        "tag"][dynregex]
                                                    finding[
                                                        "line"] = line_no + 1
                                                    finding["lines"] = get_lines(
                                                        line_no, lines)
                                                    finding[
                                                        "filename"] = filename
                                                    finding[
                                                        "path"] = full_file_path.replace(settings.UPLOAD_FOLDER,"",1)
                                                    finding["sha2"] = utils.gen_sha256_hash(
                                                        str(finding["lines"]))
                                                    security_issues.append(
                                                        finding)
                                # Good Finding String Match
                                for good_find in scan_rules["good_to_have_rgx"].iterkeys():
                                    if re.search(scan_rules["good_to_have_rgx"][good_find], line):
                                        finding = {}
                                        finding["title"] = good_find
                                        finding["description"] = scan_rules[
                                            "desc"][good_find]
                                        finding["tag"] = scan_rules[
                                            "tag"][good_find]
                                        finding["line"] = line_no + 1
                                        finding["lines"] = get_lines(
                                            line_no, lines)
                                        finding["filename"] = filename
                                        finding["path"] = full_file_path.replace(settings.UPLOAD_FOLDER,"",1)
                                        finding["sha2"] = utils.gen_sha256_hash(
                                            str(finding["lines"]))
                                        good_finding.append(finding)
                                # Missing Security Headers String Match
                                for header in scan_rules["missing_sec_header"].iterkeys():
                                    if re.search(scan_rules["missing_sec_header"][header], line, re.I):
                                        # Good Header is present
                                        header_found[header] = 1
                        # Write Beautifed Data If Any
                        if beautified_data is not None:
                            utils.unicode_safe_file_write(
                                full_file_path, beautified_data)
        # After Every Files are done.
        # Check for missing Security Headers
        for header in header_found.iterkeys():
            if header_found[header] == 0:
                finding = {}
                finding["title"] = header
                finding["description"] = scan_rules["desc"][header]
                finding["tag"] = scan_rules["tag"][header]
                missing_header.append(finding)
        #Vulnerability and Count
        for issue in security_issues:
            if not issue["title"] in vuln_n_count:
                vuln_n_count[issue["title"]] = 0
            vuln_n_count[issue["title"]] += 1

        for issue in security_issues:
            if not tags[issue["tag"]] in sec_issues_by_tag:
                sec_issues_by_tag[tags[issue["tag"]]] = []
            sec_issues_by_tag[tags[issue["tag"]]].append(issue)

        for find in good_finding:
            if not tags[find["tag"]] in good_finding_by_tag:
                good_finding_by_tag[tags[find["tag"]]] = []
            good_finding_by_tag[tags[find["tag"]]].append(find)

        for sec_header in missing_header:
            if not tags[sec_header["tag"]] in missing_header_by_tag:
                missing_header_by_tag[tags[sec_header["tag"]]] = []
            missing_header_by_tag[tags[sec_header["tag"]]].append(sec_header)

        count["sec"] = len(security_issues)
        count["mis"] = len(missing_header)
        count["good"] = len(good_finding)

        scan_results["sec_issues"] = sec_issues_by_tag
        scan_results["good_finding"] = good_finding_by_tag
        scan_results["missing_sec_header"] = missing_header_by_tag
        scan_results["total_count"] = count
        scan_results["vuln_count"] = vuln_n_count
        scan_results["files"] = all_files
        return scan_results
    except:
        utils.print_exception("Error Performing Code Analysis")