Ejemplo n.º 1
0
 def test_parser(self):
     parser = SonarQubeApiImporter()
     findings = parser.get_findings(None, self.test)
     self.assertEqual(2, len(findings))
     finding = findings[0]
     self.assertEqual('Remove this useless assignment to local variable "currentValue".', finding.title)
     self.assertEqual(None, finding.cwe)
     self.assertEqual('', finding.description)
     self.assertEqual('', finding.references)
     self.assertEqual('Medium', finding.severity)
     self.assertEqual(242, finding.line)
     self.assertEqual('internal.dummy.project:src/main/javascript/TranslateDirective.ts', finding.file_path)
Ejemplo n.º 2
0
 def test_parser(self):
     parser = SonarQubeApiImporter()
     findings = parser.get_findings(None, self.test)
     self.assertEqual(
         findings[0].title,
         '"password" detected here, make sure this is not a hard-coded credential.'
     )
     self.assertEqual(findings[0].cwe, 798)
     self.assertMultiLineEqual(
         '**Ask Yourself Whether**'
         '\n\n  '
         '* Credentials allows access to a sensitive component like a database, a file storage, an API or a service. '
         '\n  '
         '* Credentials are used in production environments. '
         '\n  '
         '* Application re-distribution is required before updating the credentials. '
         '\n\n'
         'There is a risk if you answered yes to any of those questions.'
         '\n\n', findings[0].description)
     self.assertEqual(str(findings[0].severity), 'Info')
     self.assertMultiLineEqual(
         '[CVE-2019-13466](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-13466)'
         '\n'
         '[CVE-2018-15389](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-15389)'
         '\n'
         '[OWASP Top 10 2017 Category A2](https://www.owasp.org/index.php/Top_10-2017_A2-Broken_Authentication)'
         '\n'
         '[MITRE, CWE-798](http://cwe.mitre.org/data/definitions/798)'
         '\n'
         '[MITRE, CWE-259](http://cwe.mitre.org/data/definitions/259)'
         '\n'
         '[CERT, MSC03-J.](https://wiki.sei.cmu.edu/confluence/x/OjdGBQ)'
         '\n'
         '[SANS Top 25](https://www.sans.org/top25-software-errors/#cat3)'
         '\n'
         '[Hard Coded Password](http://h3xstream.github.io/find-sec-bugs/bugs.htm#HARD_CODE_PASSWORD)'
         '\n', findings[0].references)
     self.assertEqual(
         str(findings[0].file_path),
         'internal.dummy.project:spec/support/user_fixture.rb')
     self.assertEqual(findings[0].line, 9)
     self.assertEqual(findings[0].active, True)
     self.assertEqual(findings[0].verified, False)
     self.assertEqual(findings[0].false_p, False)
     self.assertEqual(findings[0].duplicate, False)
     self.assertEqual(findings[0].out_of_scope, False)
     self.assertEqual(findings[0].static_finding, True)
     self.assertEqual(findings[0].scanner_confidence, 1)
     self.assertEqual(str(findings[0].sonarqube_issue),
                      'AXgm6Z-ophPPY0C1qhRq')
Ejemplo n.º 3
0
    def update_sonarqube_finding(self, finding):

        sonarqube_issue = finding.sonarqube_issue
        if not sonarqube_issue:
            return

        logger.debug(
            "Checking if finding '{}' needs to be updated in SonarQube".format(
                finding))

        client, _ = SonarQubeApiImporter.prepare_client(finding.test)
        # we don't care about config, each finding knows which config was used during import

        target_status = self.get_sonarqube_status_for(finding)

        issue = client.get_issue(sonarqube_issue.key)
        if issue:  # Issue could have disappeared in SQ because a previous scan has resolved the issue as fixed
            if issue.get('resolution'):
                current_status = '{} / {}'.format(issue.get('status'),
                                                  issue.get('resolution'))
            else:
                current_status = issue.get('status')

            logger.debug(
                "--> SQ Current status: {}. Current target status: {}".format(
                    current_status, target_status))

            transitions = self.get_sonarqube_required_transitions_for(
                current_status, target_status)
            if transitions:
                logger.info(
                    "Updating finding '{}' in SonarQube".format(finding))

                for transition in transitions:
                    client.transition_issue(sonarqube_issue.key, transition)

                # Track Defect Dojo has updated the SonarQube issue
                Sonarqube_Issue_Transition.objects.create(
                    sonarqube_issue=finding.sonarqube_issue,
                    # not sure if this is needed, but looks like the original author decided to send display status to sonarcube
                    # we changed Accepted into Risk Accepted, but we change it back to be sure we don't break the integration
                    finding_status=finding.status().replace(
                        'Risk Accepted', 'Accepted')
                    if finding.status() else finding.status(),
                    sonarqube_status=current_status,
                    transitions=','.join(transitions),
                )
Ejemplo n.º 4
0
    def update(self, finding):
        sonarqube_issue = finding.sonarqube_issue
        if not sonarqube_issue:
            return

        client, _ = SonarQubeApiImporter.prepare_client(finding.test)
        # we don't care about config, each finding knows which config was used during import

        issue = client.get_issue(sonarqube_issue.key)
        if issue:  # Issue could have disappeared in SQ because a previous scan has resolved the issue as fixed
            current_status = issue.get('resolution') or issue.get('status')
            current_finding_status = self.get_sonarqube_status_for(finding)
            logger.debug("--> SQ Current status: {}. Finding status: {}".format(current_status, current_finding_status))

            if current_status != "OPEN" and current_finding_status != current_status:
                logger.info("Original SonarQube issue '{}' has changed. Updating DefectDojo finding '{}'...".format(
                    sonarqube_issue, finding
                ))
                self.update_finding_status(finding, current_status)
Ejemplo n.º 5
0
def import_parser_factory(file, test, active, verified, scan_type=None):
    if scan_type is None:
        scan_type = test.test_type.name
    if scan_type == "Burp Scan":
        parser = BurpXmlParser(file, test)
    elif scan_type == "Burp Enterprise Scan":
        parser = BurpEnterpriseHtmlParser(file, test)
    elif scan_type == "Nessus Scan":
        filename = file.name.lower()
        if filename.endswith("csv"):
            parser = NessusCSVParser(file, test)
        elif filename.endswith("xml") or filename.endswith("nessus"):
            parser = NessusXMLParser(file, test)
    elif scan_type == "Clair Scan":
        parser = ClairParser(file, test)
    elif scan_type == "Nmap Scan":
        parser = NmapXMLParser(file, test)
    elif scan_type == "Nikto Scan":
        parser = NiktoXMLParser(file, test)
    elif scan_type == "Nexpose Scan":
        parser = NexposeFullXmlParser(file, test)
    elif scan_type == "Veracode Scan":
        parser = VeracodeXMLParser(file, test)
    elif scan_type == "Checkmarx Scan":
        parser = CheckmarxXMLParser(file, test)
    elif scan_type == "Checkmarx Scan detailed":
        parser = CheckmarxXMLParser(file, test, 'detailed')
    elif scan_type == "Contrast Scan":
        parser = ContrastCSVParser(file, test)
    elif scan_type == "Crashtest Security JSON File":
        parser = CrashtestSecurityJsonParser(file, test)
    elif scan_type == "Crashtest Security XML File":
        parser = CrashtestSecurityXmlParser(file, test)
    elif scan_type == "Bandit Scan":
        parser = BanditParser(file, test)
    elif scan_type == "ESLint Scan":
        parser = ESLintParser(file, test)
    elif scan_type == "ZAP Scan":
        parser = ZapXmlParser(file, test)
    elif scan_type == "AppSpider Scan":
        parser = AppSpiderXMLParser(file, test)
    elif scan_type == "Arachni Scan":
        parser = ArachniJSONParser(file, test)
    elif scan_type == 'VCG Scan':
        parser = VCGParser(file, test)
    elif scan_type == 'Dependency Check Scan':
        parser = DependencyCheckParser(file, test)
    elif scan_type == 'Dependency Track Finding Packaging Format (FPF) Export':
        parser = DependencyTrackParser(file, test)
    elif scan_type == 'Retire.js Scan':
        parser = RetireJsParser(file, test)
    elif scan_type == 'Node Security Platform Scan':
        parser = NspParser(file, test)
    elif scan_type == 'NPM Audit Scan':
        parser = NpmAuditParser(file, test)
    elif scan_type == 'PHP Symfony Security Check':
        parser = PhpSymfonySecurityCheckParser(file, test)
    elif scan_type == 'Generic Findings Import':
        parser = GenericFindingUploadCsvParser(file, test, active, verified)
    elif scan_type == 'Qualys Scan':
        parser = QualysParser(file, test)
    elif scan_type == 'Qualys Infrastructure Scan (WebGUI XML)':
        parser = QualysInfraScanParser(file, test)
    elif scan_type == 'Qualys Webapp Scan':
        parser = QualysWebAppParser(file, test)
    elif scan_type == "OpenVAS CSV":
        parser = OpenVASUploadCsvParser(file, test)
    elif scan_type == 'Snyk Scan':
        parser = SnykParser(file, test)
    elif scan_type == 'SKF Scan':
        parser = SKFCsvParser(file, test)
    elif scan_type == 'SSL Labs Scan':
        parser = SSLlabsParser(file, test)
    elif scan_type == 'Trufflehog Scan':
        parser = TruffleHogJSONParser(file, test)
    elif scan_type == 'Clair Klar Scan':
        parser = ClairKlarParser(file, test)
    elif scan_type == 'Gosec Scanner':
        parser = GosecScannerParser(file, test)
    elif scan_type == 'Trustwave Scan (CSV)':
        parser = TrustwaveUploadCsvParser(file, test)
    elif scan_type == 'Netsparker Scan':
        parser = NetsparkerParser(file, test)
    elif scan_type == 'PHP Security Audit v2':
        parser = PhpSecurityAuditV2(file, test)
    elif scan_type == 'Acunetix Scan':
        parser = AcunetixScannerParser(file, test)
    elif scan_type == 'Fortify Scan':
        parser = FortifyXMLParser(file, test)
    elif scan_type == 'SonarQube Scan':
        parser = SonarQubeHtmlParser(file, test)
    elif scan_type == 'SonarQube Scan detailed':
        parser = SonarQubeHtmlParser(file, test, 'detailed')
    elif scan_type == SCAN_SONARQUBE_API:
        parser = SonarQubeApiImporter(test)
    elif scan_type == 'MobSF Scan':
        parser = MobSFParser(file, test)
    elif scan_type == 'AWS Scout2 Scan':
        parser = AWSScout2Parser(file, test)
    elif scan_type == 'AWS Prowler Scan':
        parser = AWSProwlerParser(file, test)
    elif scan_type == 'Brakeman Scan':
        parser = BrakemanScanParser(file, test)
    elif scan_type == 'SpotBugs Scan':
        parser = SpotbugsXMLParser(file, test)
    elif scan_type == 'Safety Scan':
        parser = SafetyParser(file, test)
    elif scan_type == 'DawnScanner Scan':
        parser = DawnScannerParser(file, test)
    elif scan_type == 'Anchore Engine Scan':
        parser = AnchoreEngineScanParser(file, test)
    elif scan_type == 'Bundler-Audit Scan':
        parser = BundlerAuditParser(file, test)
    elif scan_type == 'Twistlock Image Scan':
        parser = TwistlockParser(file, test)
    elif scan_type == 'IBM AppScan DAST':
        parser = IbmAppScanDASTXMLParser(file, test)
    elif scan_type == 'Kiuwan Scan':
        parser = KiuwanCSVParser(file, test)
    elif scan_type == 'Blackduck Hub Scan':
        parser = BlackduckHubCSVParser(file, test)
    elif scan_type == 'Blackduck Component Risk':
        parser = BlackduckHubParser(file, test)
    elif scan_type == 'Sonatype Application Scan':
        parser = SonatypeJSONParser(file, test)
    elif scan_type == 'Openscap Vulnerability Scan':
        parser = OpenscapXMLParser(file, test)
    elif scan_type == 'Immuniweb Scan':
        parser = ImmuniwebXMLParser(file, test)
    elif scan_type == 'Wapiti Scan':
        parser = WapitiXMLParser(file, test)
    elif scan_type == 'Cobalt.io Scan':
        parser = CobaltCSVParser(file, test)
    elif scan_type == 'Mozilla Observatory Scan':
        parser = MozillaObservatoryJSONParser(file, test)
    elif scan_type == 'Whitesource Scan':
        parser = WhitesourceJSONParser(file, test)
    elif scan_type == 'Microfocus Webinspect Scan':
        parser = MicrofocusWebinspectXMLParser(file, test)
    elif scan_type == 'Wpscan':
        parser = WpscanJSONParser(file, test)
    elif scan_type == 'Sslscan':
        parser = SslscanXMLParser(file, test)
    elif scan_type == 'JFrog Xray Scan':
        parser = XrayJSONParser(file, test)
    elif scan_type == 'Sslyze Scan':
        parser = SslyzeXmlParser(file, test)
    elif scan_type == 'Testssl Scan':
        parser = TestsslCSVParser(file, test)
    elif scan_type == 'Hadolint Dockerfile check':
        parser = HadolintParser(file, test)
    elif scan_type == 'Aqua Scan':
        parser = AquaJSONParser(file, test)
    elif scan_type == 'HackerOne Cases':
        parser = HackerOneJSONParser(file, test)
    elif scan_type == 'Xanitizer Scan':
        parser = XanitizerXMLParser(file, test)
    elif scan_type == 'Trivy Scan':
        parser = TrivyParser(file, test)
    elif scan_type == 'Outpost24 Scan':
        parser = Outpost24Parser(file, test)
    elif scan_type == 'DSOP Scan':
        parser = DsopParser(file, test)
    elif scan_type == 'Anchore Enterprise Policy Check':
        parser = AnchoreEnterprisePolicyCheckParser(file, test)
    elif scan_type == 'Gitleaks Scan':
        parser = GitleaksJSONParser(file, test)
    elif scan_type == 'Harbor Vulnerability Scan':
        parser = HarborVulnerabilityParser(file, test)
    elif scan_type == 'Github Vulnerability Scan':
        parser = GithubVulnerabilityParser(file, test)
    elif scan_type == 'Choctaw Hog Scan':
        parser = ChoctawhogParser(file, test)
    elif scan_type == 'GitLab SAST Report':
        parser = GitlabSastReportParser(file, test)
    elif scan_type == 'Yarn Audit Scan':
        parser = YarnAuditParser(file, test)
    elif scan_type == 'BugCrowd Scan':
        parser = BugCrowdCSVParser(file, test)
    elif scan_type == 'HuskyCI Report':
        parser = HuskyCIReportParser(file, test)
    elif scan_type == 'CCVS Report':
        parser = CCVSReportParser(file, test)
    else:
        raise ValueError('Unknown Test Type')

    return parser
Ejemplo n.º 6
0
 def test_parse_file_with_one_cwe_and_one_no_cwe_vulns(self):
     parser = SonarQubeApiImporter()
     findings = parser.get_findings(None, self.test)
     self.assertEqual(2, len(findings))
Ejemplo n.º 7
0
 def test_parser(self):
     parser = SonarQubeApiImporter()
     findings = parser.get_findings(None, self.test)
     self.assertEqual(2, len(findings))
Ejemplo n.º 8
0
 def test_parser(self):
     with self.assertRaisesRegex(Exception, 'No SonarQube tool is configured.'):
         SonarQubeApiImporter.prepare_client(self.test)
Ejemplo n.º 9
0
 def test_product_mismatch(self):
     with self.assertRaisesRegex(Exception, 'Product API Scan Configuration and Product do not match.'):
         SonarQubeApiImporter.prepare_client(self.other_test)
Ejemplo n.º 10
0
 def test_parser(self):
     with self.assertRaisesRegex(Exception, 'More than one Product API Scan Configuration has been configured, but none of them has been chosen.'):
         SonarQubeApiImporter.prepare_client(self.test)
Ejemplo n.º 11
0
 def test_parser(self):
     with self.assertRaisesRegex(Exception, 'More than one Tool Configuration for SonarQube exists.'):
         SonarQubeApiImporter.prepare_client(self.test)
 def test_parser(self):
     with self.assertRaisesRegex(
             Exception, 'It has configured more than one SonarQube tool.'):
         SonarQubeApiImporter.prepare_client(self.test)
 def test_product_mismatch(self):
     with self.assertRaisesRegex(
             Exception,
             'Product SonarQube Configuration and "Product" mismatch'):
         SonarQubeApiImporter.prepare_client(self.other_test)
 def test_parser(self):
     with self.assertRaisesRegex(
             Exception,
             'It has configured more than one Product SonarQube Configuration but non of them has been choosen.'
     ):
         SonarQubeApiImporter.prepare_client(self.test)
Ejemplo n.º 15
0
 def test_parse_file_with_one_cwe_and_one_no_cwe_vulns(self):
     parser = SonarQubeApiImporter(self.test)
     self.assertEqual(2, len(parser.items))