Ejemplo n.º 1
0
    def test_import_scan(self):
        scan = open(get_unit_tests_path() + "/scans/sarif/spotbugs.sarif")
        scan_type = SarifParser().get_scan_types()[0]  # SARIF format implement the new method

        user, _ = User.objects.get_or_create(username="******")
        user_reporter, _ = User.objects.get_or_create(username="******")

        product_type, _ = Product_Type.objects.get_or_create(name="test2")
        product, _ = Product.objects.get_or_create(
            name="TestDojoDefaultImporter2",
            prod_type=product_type,
        )

        engagement, _ = Engagement.objects.get_or_create(
            name="Test Create Engagement2",
            product=product,
            target_start=timezone.now(),
            target_end=timezone.now(),
        )
        importer = Importer()
        scan_date = None
        environment, _ = Development_Environment.objects.get_or_create(name="Development")
        test, len_new_findings, len_closed_findings, _ = importer.import_scan(scan, scan_type, engagement, lead=None, environment=environment,
                    active=True, verified=True, tags=None, minimum_severity=None,
                    user=user, endpoints_to_add=None, scan_date=scan_date, version=None, branch_tag=None, build_id=None,
                    commit_hash=None, push_to_jira=None, close_old_findings=False, group_by=None, api_scan_configuration=None)

        self.assertEqual(f"SpotBugs Scan ({scan_type})", test.test_type.name)
        self.assertEqual(56, len_new_findings)
        self.assertEqual(0, len_closed_findings)
Ejemplo n.º 2
0
    def test_import_scan_without_test_scan_type(self):
        # GitLabSastParser implements get_tests but report has no scanner name
        scan = open(get_unit_tests_path() + "/scans/gitlab_sast/gl-sast-report-1-vuln.json")
        scan_type = GitlabSastParser().get_scan_types()[0]

        user, _ = User.objects.get_or_create(username="******")
        user_reporter, _ = User.objects.get_or_create(username="******")

        product_type, _ = Product_Type.objects.get_or_create(name="test2")
        product, _ = Product.objects.get_or_create(
            name="TestDojoDefaultImporter2",
            prod_type=product_type,
        )

        engagement, _ = Engagement.objects.get_or_create(
            name="Test Create Engagement2",
            product=product,
            target_start=timezone.now(),
            target_end=timezone.now(),
        )

        importer = Importer()
        scan_date = None
        environment, _ = Development_Environment.objects.get_or_create(name="Development")
        test, len_new_findings, len_closed_findings, _ = importer.import_scan(scan, scan_type, engagement, lead=None, environment=environment,
                    active=True, verified=True, tags=None, minimum_severity=None,
                    user=user, endpoints_to_add=None, scan_date=scan_date, version=None, branch_tag=None, build_id=None,
                    commit_hash=None, push_to_jira=None, close_old_findings=False, group_by=None, api_scan_configuration=None)

        self.assertEqual("GitLab SAST Report", test.test_type.name)
        self.assertEqual(1, len_new_findings)
        self.assertEqual(0, len_closed_findings)
Ejemplo n.º 3
0
    def test_parse_findings(self):
        scan_type = "Acunetix Scan"
        scan = open("dojo/unittests/scans/acunetix/one_finding.xml")

        user, created = User.objects.get_or_create(username="******")

        product_type, created = Product_Type.objects.get_or_create(name="test")
        if created:
            product_type.save()
        product, created = Product.objects.get_or_create(
            name="TestDojoDefaultImporter",
            prod_type=product_type,
        )
        if created:
            product.save()

        engagement_name = "Test Create Engagement"
        engagement, created = Engagement.objects.get_or_create(
            name=engagement_name,
            product=product,
            target_start=timezone.now(),
            target_end=timezone.now(),
        )
        if created:
            engagement.save()
        lead = None
        environment = None

        # boot
        importer = Importer()

        # create the test
        # by defaut test_type == scan_type
        test = importer.create_test(scan_type, scan_type, engagement, lead,
                                    environment)

        # parse the findings
        parser = get_parser(scan_type)
        parsed_findings = parser.get_findings(scan, test)

        # process
        minimum_severity = "Info"
        active = True
        verified = True
        new_findings = importer.process_parsed_findings(
            test,
            parsed_findings,
            scan_type,
            user,
            active,
            verified,
            minimum_severity=minimum_severity,
        )

        for finding in new_findings:
            self.assertIn(finding.numerical_severity,
                          ["S0", "S1", "S2", "S3", "S4"])
Ejemplo n.º 4
0
def import_scan_results(request, eid=None, pid=None):
    engagement = None
    form = ImportScanForm()
    cred_form = CredMappingForm()
    finding_count = 0
    jform = None
    user = request.user

    if eid:
        engagement = get_object_or_404(Engagement, id=eid)
        engagement_or_product = engagement
        cred_form.fields["cred_user"].queryset = Cred_Mapping.objects.filter(engagement=engagement).order_by('cred_id')
    elif pid:
        product = get_object_or_404(Product, id=pid)
        engagement_or_product = product
    elif not user.is_staff:
        raise PermissionDenied

    user_has_permission_or_403(user, engagement_or_product, Permissions.Import_Scan_Result)

    push_all_jira_issues = jira_helper.is_push_all_issues(engagement_or_product)

    if request.method == "POST":
        form = ImportScanForm(request.POST, request.FILES)
        cred_form = CredMappingForm(request.POST)
        cred_form.fields["cred_user"].queryset = Cred_Mapping.objects.filter(
            engagement=engagement).order_by('cred_id')

        if jira_helper.get_jira_project(engagement_or_product):
            jform = JIRAImportScanForm(request.POST, push_all=push_all_jira_issues, prefix='jiraform')
            logger.debug('jform valid: %s', jform.is_valid())
            logger.debug('jform errors: %s', jform.errors)

        if form.is_valid() and (jform is None or jform.is_valid()):
            scan = request.FILES.get('file', None)
            scan_date = form.cleaned_data['scan_date']
            minimum_severity = form.cleaned_data['minimum_severity']
            active = form.cleaned_data['active']
            verified = form.cleaned_data['verified']
            scan_type = request.POST['scan_type']
            tags = form.cleaned_data['tags']
            version = form.cleaned_data['version']
            branch_tag = form.cleaned_data.get('branch_tag', None)
            build_id = form.cleaned_data.get('build_id', None)
            commit_hash = form.cleaned_data.get('commit_hash', None)
            api_scan_configuration = form.cleaned_data.get('api_scan_configuration', None)
            service = form.cleaned_data.get('service', None)
            close_old_findings = form.cleaned_data.get('close_old_findings', None)
            # Will save in the provided environment or in the `Development` one if absent
            environment_id = request.POST.get('environment', 'Development')
            environment = Development_Environment.objects.get(id=environment_id)

            group_by = form.cleaned_data.get('group_by', None)

            # TODO move to form validation?
            if scan and is_scan_file_too_large(scan):
                messages.add_message(request,
                                     messages.ERROR,
                                     "Report file is too large. Maximum supported size is {} MB".format(settings.SCAN_FILE_MAX_SIZE),
                                     extra_tags='alert-danger')
                return HttpResponseRedirect(reverse('import_scan_results', args=(engagement,)))

            # Allows for a test to be imported with an engagement created on the fly
            if engagement is None:
                engagement = Engagement()
                engagement.name = "AdHoc Import - " + strftime("%a, %d %b %Y %X", timezone.now().timetuple())
                engagement.threat_model = False
                engagement.api_test = False
                engagement.pen_test = False
                engagement.check_list = False
                engagement.target_start = timezone.now().date()
                engagement.target_end = timezone.now().date()
                engagement.product = product
                engagement.active = True
                engagement.status = 'In Progress'
                engagement.version = version
                engagement.branch_tag = branch_tag
                engagement.build_id = build_id
                engagement.commit_hash = commit_hash
                engagement.save()

            # can't use helper as when push_all_jira_issues is True, the checkbox gets disabled and is always false
            # push_to_jira = jira_helper.is_push_to_jira(new_finding, jform.cleaned_data.get('push_to_jira'))
            push_to_jira = push_all_jira_issues or (jform and jform.cleaned_data.get('push_to_jira'))
            error = False

            # Save newly added endpoints
            added_endpoints = save_endpoints_to_add(form.endpoints_to_add_list, engagement.product)

            try:
                importer = Importer()
                test, finding_count, closed_finding_count = importer.import_scan(scan, scan_type, engagement, user, environment, active=active, verified=verified, tags=tags,
                            minimum_severity=minimum_severity, endpoints_to_add=list(form.cleaned_data['endpoints']) + added_endpoints, scan_date=scan_date,
                            version=version, branch_tag=branch_tag, build_id=build_id, commit_hash=commit_hash, push_to_jira=push_to_jira,
                            close_old_findings=close_old_findings, group_by=group_by, api_scan_configuration=api_scan_configuration, service=service)

                message = f'{scan_type} processed a total of {finding_count} findings'

                if close_old_findings:
                    message = message + ' and closed %d findings' % (closed_finding_count)

                message = message + "."

                add_success_message_to_response(message)

            except Exception as e:
                logger.exception(e)
                add_error_message_to_response('An exception error occurred during the report import:%s' % str(e))
                error = True

            # Save the credential to the test
            if cred_form.is_valid():
                if cred_form.cleaned_data['cred_user']:
                    # Select the credential mapping object from the selected list and only allow if the credential is associated with the product
                    cred_user = Cred_Mapping.objects.filter(
                        pk=cred_form.cleaned_data['cred_user'].id,
                        engagement=eid).first()

                    new_f = cred_form.save(commit=False)
                    new_f.test = test
                    new_f.cred_id = cred_user.cred_id
                    new_f.save()

            if not error:
                return HttpResponseRedirect(
                    reverse('view_test', args=(test.id, )))

    prod_id = None
    custom_breadcrumb = None
    title = "Import Scan Results"
    if engagement:
        prod_id = engagement.product.id
        product_tab = Product_Tab(prod_id, title=title, tab="engagements")
        product_tab.setEngagement(engagement)
    else:
        prod_id = pid
        custom_breadcrumb = {"", ""}
        product_tab = Product_Tab(prod_id, title=title, tab="findings")

    if jira_helper.get_jira_project(engagement_or_product):
        jform = JIRAImportScanForm(push_all=push_all_jira_issues, prefix='jiraform')

    form.fields['endpoints'].queryset = Endpoint.objects.filter(product__id=product_tab.product.id)
    form.fields['api_scan_configuration'].queryset = Product_API_Scan_Configuration.objects.filter(product__id=product_tab.product.id)
    return render(request,
        'dojo/import_scan_results.html',
        {'form': form,
         'product_tab': product_tab,
         'engagement_or_product': engagement_or_product,
         'custom_breadcrumb': custom_breadcrumb,
         'title': title,
         'cred_form': cred_form,
         'jform': jform,
         'scan_types': get_scan_types_sorted(),
         })
Ejemplo n.º 5
0
    def save(self, push_to_jira=False):
        data = self.validated_data
        close_old_findings = data['close_old_findings']
        active = data['active']
        verified = data['verified']
        minimum_severity = data['minimum_severity']
        scan_type = data['scan_type']
        endpoint_to_add = data['endpoint_to_add']
        scan_date = data['scan_date']
        # Will save in the provided environment or in the `Development` one if absent
        version = data.get('version', None)
        build_id = data.get('build_id', None)
        branch_tag = data.get('branch_tag', None)
        commit_hash = data.get('commit_hash', None)

        environment_name = data.get('environment', 'Development')
        environment = Development_Environment.objects.get(
            name=environment_name)
        tags = None
        if 'tags' in data:
            logger.debug('import scan tags: %s', data['tags'])
            tags = data['tags']

        engagement = data['engagement']
        lead = data['lead']

        scan = data.get('file', None)
        endpoints_to_add = [endpoint_to_add] if endpoint_to_add else None

        importer = Importer()
        try:
            test, finding_count, closed_finding_count = importer.import_scan(
                scan,
                scan_type,
                engagement,
                lead,
                environment,
                active=active,
                verified=verified,
                tags=tags,
                minimum_severity=minimum_severity,
                endpoints_to_add=endpoints_to_add,
                scan_date=scan_date,
                version=version,
                branch_tag=branch_tag,
                build_id=build_id,
                commit_hash=commit_hash,
                push_to_jira=push_to_jira,
                close_old_findings=close_old_findings)
        # convert to exception otherwise django rest framework will swallow them as 400 error
        # exceptions are already logged in the importer
        except SyntaxError as se:
            raise Exception(se)
        except ValueError as ve:
            raise Exception(ve)

        # return the id of the created test, can't find a better way because this is not a ModelSerializer....
        self.fields['test'] = serializers.IntegerField(read_only=True,
                                                       default=test.id)

        return test