Пример #1
0
def delete_engagement(request, eid):
    engagement = get_object_or_404(Engagement, pk=eid)
    product = engagement.product
    form = DeleteEngagementForm(instance=engagement)

    if request.method == 'POST':
        if 'id' in request.POST and str(engagement.id) == request.POST['id']:
            form = DeleteEngagementForm(request.POST, instance=engagement)
            if form.is_valid():
                del engagement.tags
                engagement.delete()
                messages.add_message(
                    request,
                    messages.SUCCESS,
                    'Engagement and relationships removed.',
                    extra_tags='alert-success')
                return HttpResponseRedirect(reverse("view_engagements", args=(product.id, )))

    collector = NestedObjects(using=DEFAULT_DB_ALIAS)
    collector.collect([engagement])
    rels = collector.nested()

    product_tab = Product_Tab(product.id, title="Delete Engagement", tab="engagements")
    product_tab.setEngagement(engagement)
    return render(request, 'dojo/delete_engagement.html', {
        'product_tab': product_tab,
        'engagement': engagement,
        'form': form,
        'rels': rels,
    })
Пример #2
0
def edit_test(request, tid):
    test = get_object_or_404(Test, pk=tid)
    form = TestForm(instance=test)
    if request.method == 'POST':
        form = TestForm(request.POST, instance=test)
        if form.is_valid():
            new_test = form.save()
            tags = request.POST.getlist('tags')
            t = ", ".join(tags)
            new_test.tags = t
            messages.add_message(request,
                                 messages.SUCCESS,
                                 'Test saved.',
                                 extra_tags='alert-success')
            return HttpResponseRedirect(reverse('view_engagement', args=(test.engagement.id,)))

    form.initial['target_start'] = test.target_start.date()
    form.initial['target_end'] = test.target_end.date()
    form.initial['tags'] = [tag.name for tag in test.tags]

    product_tab = Product_Tab(test.engagement.product.id, title="Edit Test", tab="engagements")
    product_tab.setEngagement(test.engagement)
    return render(request, 'dojo/edit_test.html',
                  {'test': test,
                   'product_tab': product_tab,
                   'form': form,
                   })
Пример #3
0
def delete_test(request, tid):
    test = get_object_or_404(Test, pk=tid)
    eng = test.engagement
    form = DeleteTestForm(instance=test)

    if request.method == 'POST':
        if 'id' in request.POST and str(test.id) == request.POST['id']:
            form = DeleteTestForm(request.POST, instance=test)
            if form.is_valid():
                del test.tags
                test.delete()
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'Test and relationships removed.',
                                     extra_tags='alert-success')
                return HttpResponseRedirect(reverse('view_engagement', args=(eng.id,)))

    collector = NestedObjects(using=DEFAULT_DB_ALIAS)
    collector.collect([test])
    rels = collector.nested()

    product_tab = Product_Tab(test.engagement.product.id, title="Delete Test", tab="engagements")
    product_tab.setEngagement(test.engagement)
    return render(request, 'dojo/delete_test.html',
                  {'test': test,
                   'product_tab': product_tab,
                   'form': form,
                   'rels': rels,
                   'deletable_objects': rels,
                   })
Пример #4
0
def action_history(request, cid, oid):
    try:
        ct = ContentType.objects.get_for_id(cid)
        obj = ct.get_object_for_this_type(pk=oid)
    except KeyError:
        raise Http404()

    product_id = None
    active_tab = None
    finding = None
    test = False
    object_value = None

    if str(ct) == "product":
        product_id = obj.id
        active_tab = "overview"
        object_value = Product.objects.get(id=obj.id)
    elif str(ct) == "engagement":
        object_value = Engagement.objects.get(id=obj.id)
        product_id = object_value.product.id
        active_tab = "engagements"
    elif str(ct) == "test":
        object_value = Test.objects.get(id=obj.id)
        product_id = object_value.engagement.product.id
        active_tab = "engagements"
        test = True
    elif str(ct) == "finding":
        object_value = Finding.objects.get(id=obj.id)
        product_id = object_value.test.engagement.product.id
        active_tab = "findings"
        finding = object_value
    elif str(ct) == "endpoint":
        object_value = Endpoint.objects.get(id=obj.id)
        product_id = object_value.product.id
        active_tab = "endpoints"

    product_tab = None
    if product_id:
        product_tab = Product_Tab(product_id, title="History", tab=active_tab)
        if active_tab == "engagements":
            if str(ct) == "engagement":
                product_tab.setEngagement(object_value)
            else:
                product_tab.setEngagement(object_value.engagement)

    history = LogEntry.objects.filter(content_type=ct,
                                      object_pk=obj.id).order_by('-timestamp')
    history = LogEntryFilter(request.GET, queryset=history)
    paged_history = get_page_items(request, history.qs, 25)

    return render(request, 'dojo/action_history.html',
                  {"history": paged_history,
                   'product_tab': product_tab,
                   "filtered": history,
                   "obj": obj,
                   "test": test,
                   "object_value": object_value,
                   "finding": finding
                   })
Пример #5
0
def upload_risk(request, eid):
    eng = Engagement.objects.get(id=eid)
    # exclude the findings already accepted
    exclude_findings = [
        finding.id for ra in eng.risk_acceptance.all()
        for finding in ra.accepted_findings.all()
    ]
    eng_findings = Finding.objects.filter(active="True", verified="True", duplicate="False", test__in=eng.test_set.all()) \
        .exclude(id__in=exclude_findings).order_by('title')

    if request.method == 'POST':
        form = UploadRiskForm(request.POST, request.FILES)
        if form.is_valid():
            findings = form.cleaned_data['accepted_findings']
            for finding in findings:
                finding.active = False
                finding.save()
            risk = form.save(commit=False)
            risk.reporter = form.cleaned_data['reporter']
            risk.expiration_date = form.cleaned_data['expiration_date']
            risk.accepted_by = form.cleaned_data['accepted_by']
            risk.compensating_control = form.cleaned_data['compensating_control']
            risk.path = form.cleaned_data['path']
            risk.save()  # have to save before findings can be added
            risk.accepted_findings = findings
            if form.cleaned_data['notes']:
                notes = Notes(
                    entry=form.cleaned_data['notes'],
                    author=request.user,
                    date=timezone.now())
                notes.save()
                risk.notes.add(notes)

            risk.save()  # saving notes and findings
            eng.risk_acceptance.add(risk)
            eng.save()
            messages.add_message(
                request,
                messages.SUCCESS,
                'Risk exception saved.',
                extra_tags='alert-success')
            return HttpResponseRedirect(
                reverse('view_engagement', args=(eid, )))
    else:
        form = UploadRiskForm(initial={'reporter': request.user})

    form.fields["accepted_findings"].queryset = eng_findings
    product_tab = Product_Tab(eng.product.id, title="Upload Risk Exception", tab="engagements")
    product_tab.setEngagement(eng)

    return render(request, 'dojo/up_risk.html', {
                  'eng': eng,
                  'product_tab': product_tab,
                  'form': form
                  })
Пример #6
0
def view_object_eng(request, id):
    object_queryset = Objects_Engagement.objects.filter(engagement=id).order_by('object_id__path', 'object_id__folder', 'object_id__artifact')
    engagement = Engagement.objects.get(id=id)
    product_tab = Product_Tab(engagement.product.id, title="Tracked Files, Folders and Artifacts on a Product", tab="engagements")
    product_tab.setEngagement(engagement)
    return render(request,
                  'dojo/view_objects_eng.html',
                  {
                      'object_queryset': object_queryset,
                      'product_tab': product_tab,
                      'id': id
                  })
Пример #7
0
def view_test(request, tid):
    test = Test.objects.get(id=tid)
    prod = test.engagement.product
    auth = request.user.is_staff or request.user in prod.authorized_users.all()
    if not auth:
        # will render 403
        raise PermissionDenied
    notes = test.notes.all()
    person = request.user.username
    findings = Finding.objects.filter(test=test).order_by('numerical_severity')
    stub_findings = Stub_Finding.objects.filter(test=test)
    cred_test = Cred_Mapping.objects.filter(test=test).select_related('cred_id').order_by('cred_id')
    creds = Cred_Mapping.objects.filter(engagement=test.engagement).select_related('cred_id').order_by('cred_id')

    if request.method == 'POST' and request.user.is_staff:
        form = NoteForm(request.POST)
        if form.is_valid():
            new_note = form.save(commit=False)
            new_note.author = request.user
            new_note.date = timezone.now()
            new_note.save()
            test.notes.add(new_note)
            form = NoteForm()
            url = request.build_absolute_uri(reverse("view_test", args=(test.id,)))
            title = "Test: %s on %s" % (test.test_type.name, test.engagement.product.name)
            process_notifications(request, new_note, url, title)
            messages.add_message(request,
                                 messages.SUCCESS,
                                 'Note added successfully.',
                                 extra_tags='alert-success')
    else:
        form = NoteForm()

    fpage = get_page_items(request, findings, 25)
    sfpage = get_page_items(request, stub_findings, 25)
    show_re_upload = any(test.test_type.name in code for code in ImportScanForm.SCAN_TYPE_CHOICES)

    product_tab = Product_Tab(prod.id, title="Test", tab="engagements")
    product_tab.setEngagement(test.engagement)
    return render(request, 'dojo/view_test.html',
                  {'test': test,
                   'product_tab': product_tab,
                   'findings': fpage,
                   'findings_count': findings.count(),
                   'stub_findings': sfpage,
                   'form': form,
                   'notes': notes,
                   'person': person,
                   'request': request,
                   'show_re_upload': show_re_upload,
                   'creds': creds,
                   'cred_test': cred_test
                   })
Пример #8
0
def complete_checklist(request, eid):
    eng = get_object_or_404(Engagement, id=eid)
    add_breadcrumb(
        parent=eng,
        title="Complete checklist",
        top_level=False,
        request=request)
    if request.method == 'POST':
        tests = Test.objects.filter(engagement=eng)
        findings = Finding.objects.filter(test__in=tests).all()
        form = CheckForm(request.POST, findings=findings)
        if form.is_valid():
            cl = form.save(commit=False)
            try:
                check_l = Check_List.objects.get(engagement=eng)
                cl.id = check_l.id
                cl.save()
                form.save_m2m()
            except:

                cl.engagement = eng
                cl.save()
                form.save_m2m()
                pass
            messages.add_message(
                request,
                messages.SUCCESS,
                'Checklist saved.',
                extra_tags='alert-success')
            return HttpResponseRedirect(
                reverse('view_engagement', args=(eid, )))
    else:
        tests = Test.objects.filter(engagement=eng)
        findings = Finding.objects.filter(test__in=tests).all()
        form = CheckForm(findings=findings)

    product_tab = Product_Tab(eng.product.id, title="Checklist", tab="engagements")
    product_tab.setEngagement(eng)
    return render(request, 'dojo/checklist.html', {
        'form': form,
        'product_tab': product_tab,
        'eid': eng.id,
        'findings': findings,
    })
Пример #9
0
def complete_checklist(request, eid):
    eng = get_object_or_404(Engagement, id=eid)
    add_breadcrumb(
        parent=eng,
        title="Complete checklist",
        top_level=False,
        request=request)
    if request.method == 'POST':
        tests = Test.objects.filter(engagement=eng)
        findings = Finding.objects.filter(test__in=tests).all()
        form = CheckForm(request.POST, findings=findings)
        if form.is_valid():
            cl = form.save(commit=False)
            try:
                check_l = Check_List.objects.get(engagement=eng)
                cl.id = check_l.id
                cl.save()
                form.save_m2m()
            except:

                cl.engagement = eng
                cl.save()
                form.save_m2m()
                pass
            messages.add_message(
                request,
                messages.SUCCESS,
                'Checklist saved.',
                extra_tags='alert-success')
            return HttpResponseRedirect(
                reverse('view_engagement', args=(eid, )))
    else:
        tests = Test.objects.filter(engagement=eng)
        findings = Finding.objects.filter(test__in=tests).all()
        form = CheckForm(findings=findings)

    product_tab = Product_Tab(eng.product.id, title="Checklist", tab="engagements")
    product_tab.setEngagement(eng)
    return render(request, 'dojo/checklist.html', {
        'form': form,
        'product_tab': product_tab,
        'eid': eng.id,
        'findings': findings,
    })
Пример #10
0
def view_endpoint(request, eid):
    endpoint = get_object_or_404(Endpoint, id=eid)
    host = endpoint.host_no_port
    endpoints = Endpoint.objects.filter(host__regex="^" + host + ":?",
                                        product=endpoint.product).distinct()

    endpoint_metadata = dict(
        endpoint.endpoint_meta.values_list('name', 'value'))

    all_findings = Finding.objects.filter(endpoints__in=endpoints).distinct()

    active_findings = Finding.objects.filter(endpoints__in=endpoints,
                                             active=True,
                                             verified=True).distinct()

    closed_findings = Finding.objects.filter(
        endpoints__in=endpoints, mitigated__isnull=False).distinct()
    if all_findings:
        start_date = timezone.make_aware(
            datetime.combine(all_findings.last().date, datetime.min.time()))
    else:
        start_date = timezone.now()
    end_date = timezone.now()

    r = relativedelta(end_date, start_date)
    months_between = (r.years * 12) + r.months
    # include current month
    months_between += 1

    monthly_counts = get_period_counts(active_findings,
                                       all_findings,
                                       closed_findings,
                                       None,
                                       months_between,
                                       start_date,
                                       relative_delta='months')

    paged_findings = get_page_items(request, active_findings, 25)

    vulnerable = False

    if active_findings.count() != 0:
        vulnerable = True

    product_tab = Product_Tab(endpoint.product.id, "Endpoint", tab="endpoints")
    return render(
        request, "dojo/view_endpoint.html", {
            "endpoint": endpoint,
            'product_tab': product_tab,
            "endpoints": endpoints,
            "findings": paged_findings,
            'all_findings': all_findings,
            'opened_per_month': monthly_counts['opened_per_period'],
            'endpoint_metadata': endpoint_metadata,
            'vulnerable': vulnerable,
        })
Пример #11
0
def all_cred_product(request, pid):
    prod = get_object_or_404(Product, id=pid)
    creds = Cred_Mapping.objects.filter(product=prod).order_by('cred_id__name')

    product_tab = Product_Tab(prod.id, title="Credentials", tab="settings")
    return render(request, 'dojo/view_cred_prod.html', {
        'product_tab': product_tab,
        'creds': creds,
        'prod': prod
    })
Пример #12
0
def delete_test(request, tid):
    test = get_object_or_404(Test, pk=tid)
    eng = test.engagement
    form = DeleteTestForm(instance=test)

    if request.method == 'POST':
        if 'id' in request.POST and str(test.id) == request.POST['id']:
            form = DeleteTestForm(request.POST, instance=test)
            if form.is_valid():
                del test.tags
                test.delete()
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'Test and relationships removed.',
                                     extra_tags='alert-success')
                create_notification(
                    event='other',
                    title='Deletion of %s' % test.title,
                    description='The test "%s" was deleted by %s' %
                    (test.title, request.user),
                    url=request.build_absolute_uri(
                        reverse('view_engagement', args=(eng.id, ))),
                    recipients=[test.engagement.lead],
                    icon="exclamation-triangle")
                return HttpResponseRedirect(
                    reverse('view_engagement', args=(eng.id, )))

    collector = NestedObjects(using=DEFAULT_DB_ALIAS)
    collector.collect([test])
    rels = collector.nested()

    product_tab = Product_Tab(test.engagement.product.id,
                              title="Delete Test",
                              tab="engagements")
    product_tab.setEngagement(test.engagement)
    return render(
        request, 'dojo/delete_test.html', {
            'test': test,
            'product_tab': product_tab,
            'form': form,
            'rels': rels,
            'deletable_objects': rels,
        })
Пример #13
0
def engagement_presets(request, pid):
    prod = get_object_or_404(Product, id=pid)
    presets = Engagement_Presets.objects.filter(product=prod).all()

    product_tab = Product_Tab(prod.id, title="Engagement Presets", tab="settings")

    return render(request, 'dojo/view_presets.html',
                  {'product_tab': product_tab,
                   'presets': presets,
                   'prod': prod})
Пример #14
0
def view_objects(request, pid):
    object_queryset = Objects_Product.objects.filter(product=pid).order_by('path', 'folder', 'artifact')

    product_tab = Product_Tab(pid, title="Tracked Product Files, Paths and Artifacts", tab="settings")
    return render(request,
                  'dojo/view_objects.html',
                  {
                      'object_queryset': object_queryset,
                      'product_tab': product_tab,
                      'pid': pid
                  })
def all_tool_product(request, pid):
    prod = get_object_or_404(Product, id=pid)
    tools = Tool_Product_Settings.objects.filter(product=prod).order_by('name')
    product_tab = Product_Tab(prod.id,
                              title="Tool Configurations",
                              tab="settings")
    return render(request, 'dojo/view_tool_product_all.html', {
        'prod': prod,
        'tools': tools,
        'product_tab': product_tab
    })
Пример #16
0
def action_history(request, cid, oid):
    try:
        ct = ContentType.objects.get_for_id(cid)
        obj = ct.get_object_for_this_type(pk=oid)
    except KeyError:
        raise Http404()

    product_id = None
    active_tab = None
    finding = None
    test = False
    object_value = None

    if str(ct) == "product":
        product_id = obj.id
        active_tab = "overview"
        object_value = Product.objects.get(id=obj.id)
    elif str(ct) == "engagement":
        object_value = Engagement.objects.get(id=obj.id)
        product_id = object_value.product.id
        active_tab = "engagements"
    elif str(ct) == "test":
        object_value = Test.objects.get(id=obj.id)
        product_id = object_value.engagement.product.id
        active_tab = "engagements"
        test = True
    elif str(ct) == "finding":
        object_value = Finding.objects.get(id=obj.id)
        product_id = object_value.test.engagement.product.id
        active_tab = "findings"
        finding = object_value
    elif str(ct) == "endpoint":
        object_value = Endpoint.objects.get(id=obj.id)
        product_id = object_value.product.id
        active_tab = "endpoints"

    product_tab = None
    if product_id:
        product_tab = Product_Tab(product_id, title="History", tab=active_tab)
        if active_tab == "engagements":
            if str(ct) == "engagement":
                product_tab.setEngagement(object_value)
            else:
                product_tab.setEngagement(object_value.engagement)

    history = LogEntry.objects.filter(content_type=ct,
                                      object_pk=obj.id).order_by('-timestamp')
    history = LogEntryFilter(request.GET, queryset=history)
    paged_history = get_page_items(request, history.qs, 25)

    return render(
        request, 'dojo/action_history.html', {
            "history": paged_history,
            'product_tab': product_tab,
            "filtered": history,
            "obj": obj,
            "test": test,
            "object_value": object_value,
            "finding": finding
        })
Пример #17
0
def delete_engagement(request, eid):
    engagement = get_object_or_404(Engagement, pk=eid)
    product = engagement.product
    form = DeleteEngagementForm(instance=engagement)

    if request.method == 'POST':
        if 'id' in request.POST and str(engagement.id) == request.POST['id']:
            form = DeleteEngagementForm(request.POST, instance=engagement)
            if form.is_valid():
                del engagement.tags
                engagement.delete()
                messages.add_message(
                    request,
                    messages.SUCCESS,
                    'Engagement and relationships removed.',
                    extra_tags='alert-success')
                create_notification(event='other',
                                    title='Deletion of %s' % engagement.name,
                                    description='The engagement "%s" was deleted by %s' % (engagement.name, request.user),
                                    url=request.build_absolute_uri(reverse('view_engagements', args=(product.id, ))),
                                    recipients=[engagement.lead],
                                    icon="exclamation-triangle")

                if engagement.engagement_type == 'CI/CD':
                    return HttpResponseRedirect(reverse("view_engagements_cicd", args=(product.id, )))
                else:
                    return HttpResponseRedirect(reverse("view_engagements", args=(product.id, )))

    collector = NestedObjects(using=DEFAULT_DB_ALIAS)
    collector.collect([engagement])
    rels = collector.nested()

    product_tab = Product_Tab(product.id, title="Delete Engagement", tab="engagements")
    product_tab.setEngagement(engagement)
    return render(request, 'dojo/delete_engagement.html', {
        'product_tab': product_tab,
        'engagement': engagement,
        'form': form,
        'rels': rels,
    })
Пример #18
0
def process_endpoints_view(request, host_view=False, vulnerable=False):

    if vulnerable:
        endpoints = Endpoint.objects.filter(finding__active=True, finding__verified=True, finding__false_p=False,
                                     finding__duplicate=False, finding__out_of_scope=False, mitigated=False)
    else:
        endpoints = Endpoint.objects.all()

    endpoints = endpoints.prefetch_related('product', 'product__tags', 'tags').distinct()
    endpoints = get_authorized_endpoints(Permissions.Endpoint_View, endpoints, request.user)

    if host_view:
        ids = get_endpoint_ids(EndpointFilter(request.GET, queryset=endpoints, user=request.user).qs)
        endpoints = EndpointFilter(request.GET, queryset=endpoints.filter(id__in=ids), user=request.user)
    else:
        endpoints = EndpointFilter(request.GET, queryset=endpoints, user=request.user)

    paged_endpoints = get_page_items(request, endpoints.qs, 25)

    if vulnerable:
        view_name = "Vulnerable"
    else:
        view_name = "All"

    if host_view:
        view_name += " Endpoint Hosts"
    else:
        view_name += " Endpoints"

    add_breadcrumb(title=view_name, top_level=not len(request.GET), request=request)

    product_tab = None
    if 'product' in request.GET:
        p = request.GET.getlist('product', [])
        if len(p) == 1:
            product = get_object_or_404(Product, id=p[0])
            if not settings.FEATURE_AUTHORIZATION_V2:
                if not user_is_authorized(request.user, 'view', product):
                    raise PermissionDenied
            else:
                user_has_permission_or_403(request.user, product, Permissions.Product_View)
            product_tab = Product_Tab(product.id, view_name, tab="endpoints")

    return render(
        request, 'dojo/endpoints.html', {
            'product_tab': product_tab,
            "endpoints": paged_endpoints,
            "filtered": endpoints,
            "name": view_name,
            "host_view": host_view,
            "product_tab": product_tab
        })
Пример #19
0
def vulnerable_endpoints(request):
    endpoints = Endpoint.objects.filter(finding__active=True,
                                        finding__verified=True,
                                        finding__false_p=False,
                                        finding__duplicate=False,
                                        finding__out_of_scope=False,
                                        mitigated=False).prefetch_related(
                                            'product', 'product__tags',
                                            'tags').distinct()

    # are they authorized
    if request.user.is_staff:
        pass
    else:
        endpoints = Endpoint.objects.filter(
            Q(product__authorized_users__in=[request.user])
            | Q(product__prod_type__authorized_users__in=[request.user]))
        if not endpoints:
            raise PermissionDenied

    product = None
    if 'product' in request.GET:
        p = request.GET.getlist('product', [])
        if len(p) == 1:
            product = get_object_or_404(Product, id=p[0])

    ids = get_endpoint_ids(
        EndpointFilter(request.GET, queryset=endpoints, user=request.user).qs)
    endpoints = EndpointFilter(request.GET,
                               queryset=endpoints.filter(id__in=ids),
                               user=request.user)
    endpoints_query = endpoints.qs.order_by('host')
    paged_endpoints = get_page_items(request, endpoints_query, 25)
    add_breadcrumb(title="Vulnerable Endpoints",
                   top_level=not len(request.GET),
                   request=request)

    system_settings = System_Settings.objects.get()

    product_tab = None
    view_name = "All Endpoints"
    if product:
        product_tab = Product_Tab(product.id,
                                  "Vulnerable Endpoints",
                                  tab="endpoints")
    return render(
        request, 'dojo/endpoints.html', {
            'product_tab': product_tab,
            "endpoints": paged_endpoints,
            "filtered": endpoints,
            "name": "Vulnerable Endpoints",
        })
Пример #20
0
def all_endpoints(request):
    endpoints = Endpoint.objects.all().prefetch_related(
        'product', 'tags', 'product__tags')
    show_uri = get_system_setting('display_endpoint_uri')
    # are they authorized
    if request.user.is_staff:
        pass
    else:
        endpoints = Endpoint.objects.filter(
            Q(product__authorized_users__in=[request.user])
            | Q(product__prod_type__authorized_users__in=[request.user]))
        if not endpoints:
            raise PermissionDenied

    product = None
    if 'product' in request.GET:
        p = request.GET.getlist('product', [])
        if len(p) == 1:
            product = get_object_or_404(Product, id=p[0])

    if show_uri:
        endpoints = EndpointFilter(request.GET,
                                   queryset=endpoints,
                                   user=request.user)
        paged_endpoints = get_page_items(request, endpoints.qs, 25)
    else:
        ids = get_endpoint_ids(
            EndpointFilter(request.GET, queryset=endpoints,
                           user=request.user).qs)
        endpoints = EndpointFilter(request.GET,
                                   queryset=endpoints.filter(id__in=ids),
                                   user=request.user)
        paged_endpoints = get_page_items(request, endpoints.qs, 25)
    add_breadcrumb(title="All Endpoints",
                   top_level=not len(request.GET),
                   request=request)

    product_tab = None
    view_name = "All Endpoints"
    if product:
        view_name = "Endpoints"
        product_tab = Product_Tab(product.id, "Endpoints", tab="endpoints")

    return render(
        request, 'dojo/endpoints.html', {
            'product_tab': product_tab,
            "endpoints": paged_endpoints,
            "filtered": endpoints,
            "name": view_name,
            "show_uri": show_uri
        })
Пример #21
0
def process_endpoint_view(request, eid, host_view=False):
    endpoint = get_object_or_404(Endpoint, id=eid)

    if host_view:
        endpoints = endpoint.host_endpoints()
        endpoint_metadata = None
        all_findings = endpoint.host_findings()
        active_findings = endpoint.host_active_findings()
    else:
        endpoints = None
        endpoint_metadata = dict(endpoint.endpoint_meta.values_list('name', 'value'))
        all_findings = endpoint.findings()
        active_findings = endpoint.active_findings()

    if all_findings:
        start_date = timezone.make_aware(datetime.combine(all_findings.last().date, datetime.min.time()))
    else:
        start_date = timezone.now()
    end_date = timezone.now()

    r = relativedelta(end_date, start_date)
    months_between = (r.years * 12) + r.months
    # include current month
    months_between += 1

    # closed_findings is needed as a parameter for get_periods_counts, but they are not relevant in the endpoint view
    closed_findings = Finding.objects.none()

    monthly_counts = get_period_counts(active_findings, all_findings, closed_findings, None, months_between, start_date,
                                       relative_delta='months')

    paged_findings = get_page_items(request, active_findings, 25)

    vulnerable = False

    if active_findings.count() != 0:
        vulnerable = True

    product_tab = Product_Tab(endpoint.product.id, "Host" if host_view else "Endpoint", tab="endpoints")
    return render(request,
                  "dojo/view_endpoint.html",
                  {"endpoint": endpoint,
                   'product_tab': product_tab,
                   "endpoints": endpoints,
                   "findings": paged_findings,
                   'all_findings': all_findings,
                   'opened_per_month': monthly_counts['opened_per_period'],
                   'endpoint_metadata': endpoint_metadata,
                   'vulnerable': vulnerable,
                   'host_view': host_view,
                   })
Пример #22
0
def delete_engagement(request, eid):
    engagement = get_object_or_404(Engagement, pk=eid)
    product = engagement.product
    form = DeleteEngagementForm(instance=engagement)

    if request.method == 'POST':
        if 'id' in request.POST and str(engagement.id) == request.POST['id']:
            form = DeleteEngagementForm(request.POST, instance=engagement)
            if form.is_valid():
                del engagement.tags
                engagement.delete()
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'Engagement and relationships removed.',
                                     extra_tags='alert-success')

                if engagement.engagement_type == 'CI/CD':
                    return HttpResponseRedirect(
                        reverse("view_engagements_cicd", args=(product.id, )))
                else:
                    return HttpResponseRedirect(
                        reverse("view_engagements", args=(product.id, )))

    collector = NestedObjects(using=DEFAULT_DB_ALIAS)
    collector.collect([engagement])
    rels = collector.nested()

    product_tab = Product_Tab(product.id,
                              title="Delete Engagement",
                              tab="engagements")
    product_tab.setEngagement(engagement)
    return render(
        request, 'dojo/delete_engagement.html', {
            'product_tab': product_tab,
            'engagement': engagement,
            'form': form,
            'rels': rels,
        })
Пример #23
0
def all_endpoints(request):
    endpoints = Endpoint.objects.prefetch_related('product', 'tags',
                                                  'product__tags')
    endpoints = get_authorized_endpoints(Permissions.Endpoint_View, endpoints,
                                         request.user)
    show_uri = get_system_setting('display_endpoint_uri')

    product = None
    if 'product' in request.GET:
        p = request.GET.getlist('product', [])
        if len(p) == 1:
            product = get_object_or_404(Product, id=p[0])
            if not settings.FEATURE_AUTHORIZATION_V2:
                if not user_is_authorized(request.user, 'view', product):
                    raise PermissionDenied
            else:
                user_has_permission_or_403(request.user, product,
                                           Permissions.Product_View)

    if show_uri:
        endpoints = EndpointFilter(request.GET,
                                   queryset=endpoints,
                                   user=request.user)
        paged_endpoints = get_page_items(request, endpoints.qs, 25)
    else:
        ids = get_endpoint_ids(
            EndpointFilter(request.GET, queryset=endpoints,
                           user=request.user).qs)
        endpoints = EndpointFilter(request.GET,
                                   queryset=endpoints.filter(id__in=ids),
                                   user=request.user)
        paged_endpoints = get_page_items(request, endpoints.qs, 25)
    add_breadcrumb(title="All Endpoints",
                   top_level=not len(request.GET),
                   request=request)

    product_tab = None
    view_name = "All Endpoints"
    if product:
        view_name = "Endpoints"
        product_tab = Product_Tab(product.id, "Endpoints", tab="endpoints")

    return render(
        request, 'dojo/endpoints.html', {
            'product_tab': product_tab,
            "endpoints": paged_endpoints,
            "filtered": endpoints,
            "name": view_name,
            "show_uri": show_uri
        })
Пример #24
0
def delete_test(request, tid):
    test = get_object_or_404(Test, pk=tid)
    eng = test.engagement
    form = DeleteTestForm(instance=test)

    from django.contrib.admin.utils import NestedObjects
    from django.db import DEFAULT_DB_ALIAS

    collector = NestedObjects(using=DEFAULT_DB_ALIAS)
    collector.collect([test])
    rels = collector.nested()

    if request.method == 'POST':
        if 'id' in request.POST and str(test.id) == request.POST['id']:
            form = DeleteTestForm(request.POST, instance=test)
            if form.is_valid():
                del test.tags
                test.delete()
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'Test and relationships removed.',
                                     extra_tags='alert-success')
                return HttpResponseRedirect(
                    reverse('view_engagement', args=(eng.id, )))

    product_tab = Product_Tab(test.engagement.product.id,
                              title="Delete Test",
                              tab="engagements")
    product_tab.setEngagement(test.engagement)
    return render(
        request, 'dojo/delete_test.html', {
            'test': test,
            'product_tab': product_tab,
            'form': form,
            'rels': rels,
            'deletable_objects': rels,
        })
Пример #25
0
def view_engagements(request, pid, engagement_type="Interactive"):
    prod = get_object_or_404(Product, id=pid)
    auth = request.user.is_staff or request.user in prod.authorized_users.all()
    if not auth:
        # will render 403
        raise PermissionDenied

    engs = Engagement.objects.filter(product=prod, active=True)
    default_page_num = 10

    result_engs = EngagementFilter(
        request.GET,
        queryset=Engagement.objects.filter(
            product=prod, active=True,
            engagement_type=engagement_type).order_by('-updated'))

    engs = get_page_items(request,
                          result_engs.qs,
                          default_page_num,
                          param_name="engs")

    result = EngagementFilter(
        request.GET,
        queryset=Engagement.objects.filter(
            product=prod, active=False,
            engagement_type=engagement_type).order_by('-target_end'))

    i_engs_page = get_page_items(request,
                                 result.qs,
                                 default_page_num,
                                 param_name="i_engs")

    title = "All Engagements"
    if engagement_type == "CI/CD":
        title = "CI/CD Engagements"

    product_tab = Product_Tab(pid, title=title, tab="engagements")
    return render(
        request, 'dojo/view_engagements.html', {
            'prod': prod,
            'product_tab': product_tab,
            'engagement_type': engagement_type,
            'engs': engs,
            'engs_count': result_engs.qs.count(),
            'i_engs': i_engs_page,
            'i_engs_count': result.qs.count(),
            'user': request.user,
            'authorized': auth
        })
Пример #26
0
def edit_test(request, tid):
    test = get_object_or_404(Test, pk=tid)
    form = TestForm(instance=test)
    if request.method == 'POST':
        form = TestForm(request.POST, instance=test)
        if form.is_valid():
            new_test = form.save()
            messages.add_message(request,
                                 messages.SUCCESS,
                                 'Test saved.',
                                 extra_tags='alert-success')
            return HttpResponseRedirect(reverse('view_engagement', args=(test.engagement.id,)))

    form.initial['target_start'] = test.target_start.date()
    form.initial['target_end'] = test.target_end.date()
    form.initial['description'] = test.description

    product_tab = Product_Tab(test.engagement.product.id, title="Edit Test", tab="engagements")
    product_tab.setEngagement(test.engagement)
    return render(request, 'dojo/edit_test.html',
                  {'test': test,
                   'product_tab': product_tab,
                   'form': form,
                   })
Пример #27
0
def view_engagements(request, pid, engagement_type="Interactive"):
    prod = get_object_or_404(Product, id=pid)
    auth = request.user.is_staff or request.user in prod.authorized_users.all()
    if not auth:
        raise PermissionDenied

    default_page_num = 10

    # In Progress Engagements
    result_engs = EngagementFilter(
        request.GET,
        queryset=Engagement.objects.filter(product=prod, active=True, status="In Progress", engagement_type=engagement_type).order_by('-updated'))

    engs = get_page_items(request, result_engs.qs, default_page_num, param_name="engs")

    # Engagements that are queued because they haven't started or paused
    queued_engs = EngagementFilter(
        request.GET,
        queryset=Engagement.objects.filter(~Q(status="In Progress"), product=prod, active=True, engagement_type=engagement_type).order_by('-updated'))

    result_queued_engs = get_page_items(request, queued_engs.qs, default_page_num, param_name="queued_engs")

    # Cancelled or Completed Engagements
    result = EngagementFilter(
        request.GET,
        queryset=Engagement.objects.filter(product=prod, active=False, engagement_type=engagement_type).order_by('-target_end'))

    i_engs_page = get_page_items(request, result.qs, default_page_num, param_name="i_engs")

    title = "All Engagements"
    if engagement_type == "CI/CD":
        title = "CI/CD Engagements"

    product_tab = Product_Tab(pid, title=title, tab="engagements")
    return render(request,
                  'dojo/view_engagements.html',
                  {'prod': prod,
                   'product_tab': product_tab,
                   'engagement_type': engagement_type,
                   'engs': engs,
                   'engs_count': result_engs.qs.count(),
                   'queued_engs': result_queued_engs,
                   'queued_engs_count': queued_engs.qs.count(),
                   'i_engs': i_engs_page,
                   'i_engs_count': result.qs.count(),
                   'user': request.user,
                   'authorized': auth})
Пример #28
0
def import_endpoint_meta(request, pid):
    product = get_object_or_404(Product, id=pid)
    form = ImportEndpointMetaForm()
    if request.method == 'POST':
        form = ImportEndpointMetaForm(request.POST, request.FILES)
        if form.is_valid():
            file = request.FILES.get('file', None)
            # Make sure size is not too large
            if file and is_scan_file_too_large(file):
                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')

            create_endpoints = form.cleaned_data['create_endpoints']
            create_tags = form.cleaned_data['create_tags']
            create_dojo_meta = form.cleaned_data['create_dojo_meta']

            try:
                endpoint_meta_import(file,
                                     product,
                                     create_endpoints,
                                     create_tags,
                                     create_dojo_meta,
                                     origin='UI',
                                     request=request)
            except Exception as e:
                logger.exception(e)
                add_error_message_to_response(
                    'An exception error occurred during the report import:%s' %
                    str(e))
            return HttpResponseRedirect(
                reverse('endpoint') + "?product=" + pid)

    add_breadcrumb(title="Endpoint Meta Importer",
                   top_level=False,
                   request=request)
    product_tab = Product_Tab(product.id,
                              title="Endpoint Meta Importer",
                              tab="endpoints")
    return render(request, 'dojo/endpoint_meta_importer.html', {
        'product_tab': product_tab,
        'form': form,
    })
Пример #29
0
def delete_finding_group(request, fgid):
    logger.debug('delete finding group: %s', fgid)
    finding_group = get_object_or_404(Finding_Group, pk=fgid)
    form = DeleteFindingGroupForm(instance=finding_group)

    if request.method == 'POST':
        if 'id' in request.POST and str(
                finding_group.id) == request.POST['id']:
            form = DeleteFindingGroupForm(request.POST, instance=finding_group)
            if form.is_valid():
                product = finding_group.test.engagement.product
                finding_group.delete()
                messages.add_message(
                    request,
                    messages.SUCCESS,
                    'Finding Group and relationships removed.',
                    extra_tags='alert-success')

                create_notification(
                    event='other',
                    title='Deletion of %s' % finding_group.name,
                    product=product,
                    description='The finding group "%s" was deleted by %s' %
                    (finding_group.name, request.user),
                    url=request.build_absolute_uri(
                        reverse('view_test', args=(finding_group.test.id, ))),
                    icon="exclamation-triangle")
                return HttpResponseRedirect(
                    reverse('view_test', args=(finding_group.test.id, )))

    collector = NestedObjects(using=DEFAULT_DB_ALIAS)
    collector.collect([finding_group])
    rels = collector.nested()
    product_tab = Product_Tab(finding_group.test.engagement.product.id,
                              title="Product",
                              tab="settings")

    return render(
        request, 'dojo/delete_finding_group.html', {
            'finding_group': finding_group,
            'form': form,
            'product_tab': product_tab,
            'rels': rels,
        })
def add_meta_data(request, eid):
    endpoint = Endpoint.objects.get(id=eid)
    ct = ContentType.objects.get_for_model(endpoint)

    if request.method == 'POST':
        form = EndpointMetaDataForm(request.POST)
        if form.is_valid():
            cf, created = CustomField.objects.get_or_create(
                name=form.cleaned_data['name'],
                content_type=ct,
                field_type='a')
            cf.save()
            cfv, created = CustomFieldValue.objects.get_or_create(
                field=cf, object_id=endpoint.id)
            cfv.value = form.cleaned_data['value']
            cfv.clean()
            cfv.save()
            messages.add_message(request,
                                 messages.SUCCESS,
                                 'Metadata added successfully.',
                                 extra_tags='alert-success')
            if 'add_another' in request.POST:
                return HttpResponseRedirect(
                    reverse('add_meta_data', args=(eid, )))
            else:
                return HttpResponseRedirect(
                    reverse('view_endpoint', args=(eid, )))
    else:
        form = EndpointMetaDataForm(initial={'content_type': endpoint})

    add_breadcrumb(parent=endpoint,
                   title="Add Metadata",
                   top_level=False,
                   request=request)
    product_tab = Product_Tab(endpoint.product.id,
                              "Add Metadata",
                              tab="endpoints")
    return render(request, 'dojo/add_endpoint_meta_data.html', {
        'form': form,
        'product_tab': product_tab,
        'endpoint': endpoint,
    })
Пример #31
0
def add_engagement_presets(request, pid):
    prod = get_object_or_404(Product, id=pid)
    if request.method == 'POST':
        tform = EngagementPresetsForm(request.POST)
        if tform.is_valid():
            form_copy = tform.save(commit=False)
            form_copy.product = prod
            form_copy.save()
            tform.save_m2m()
            messages.add_message(
                request,
                messages.SUCCESS,
                'Engagement Preset Successfully Created.',
                extra_tags='alert-success')
            return HttpResponseRedirect(reverse('engagement_presets', args=(pid,)))
    else:
        tform = EngagementPresetsForm()

    product_tab = Product_Tab(pid, title="New Engagement Preset", tab="settings")
    return render(request, 'dojo/new_params.html', {'tform': tform, 'pid': pid, 'product_tab': product_tab})
Пример #32
0
def delete_object(request, pid, ttid):
    object = Objects_Product.objects.get(pk=ttid)

    if request.method == 'POST':
        tform = ObjectSettingsForm(request.POST, instance=object)
        object.delete()
        messages.add_message(request,
                             messages.SUCCESS,
                             'Tracked Product Files Deleted.',
                             extra_tags='alert-success')
        return HttpResponseRedirect(reverse('view_objects', args=(pid,)))
    else:
        tform = DeleteObjectsSettingsForm(instance=object)

    product_tab = Product_Tab(pid, title="Delete Product Tool Configuration", tab="settings")
    return render(request,
                  'dojo/delete_object.html',
                  {
                      'tform': tform,
                      'product_tab': product_tab
                  })
def edit_meta_data(request, eid):

    endpoint = Endpoint.objects.get(id=eid)
    ct = ContentType.objects.get_for_model(endpoint)

    endpoint_cf = CustomField.objects.filter(content_type=ct)
    endpoint_metadata = {}

    for cf in endpoint_cf:
        cfv = CustomFieldValue.objects.filter(field=cf, object_id=endpoint.id)
        if len(cfv):
            endpoint_metadata[cf] = cfv[0]

    if request.method == 'POST':
        for key, value in request.POST.iteritems():
            if key.startswith('cfv_'):
                cfv_id = int(key.split('_')[1])
                cfv = get_object_or_404(CustomFieldValue, id=cfv_id)

                value = value.strip()
                if value:
                    cfv.value = value
                    cfv.save()
                else:
                    cfv.delete()
        messages.add_message(request,
                             messages.SUCCESS,
                             'Metadata edited successfully.',
                             extra_tags='alert-success')
        return HttpResponseRedirect(reverse('view_endpoint', args=(eid, )))

    product_tab = Product_Tab(endpoint.product.id,
                              "Edit Metadata",
                              tab="endpoints")
    return render(
        request, 'dojo/edit_endpoint_meta_data.html', {
            'endpoint': endpoint,
            'product_tab': product_tab,
            'endpoint_metadata': endpoint_metadata,
        })
def edit_object(request, pid, ttid):
    object = Objects_Product.objects.get(pk=ttid)

    if request.method == 'POST':
        tform = ObjectSettingsForm(request.POST, instance=object)
        if tform.is_valid():
            tform.save()

            messages.add_message(
                request,
                messages.SUCCESS,
                'Tool Product Configuration Successfully Updated.',
                extra_tags='alert-success')
            return HttpResponseRedirect(reverse('view_objects', args=(pid, )))
    else:
        tform = ObjectSettingsForm(instance=object)

    product_tab = Product_Tab(pid, title="Edit Tracked Files", tab="settings")
    return render(request, 'dojo/edit_object.html', {
        'tform': tform,
        'product_tab': product_tab
    })
Пример #35
0
def add_endpoint(request, pid):
    product = get_object_or_404(Product, id=pid)
    template = 'dojo/add_endpoint.html'
    if '_popup' in request.GET:
        template = 'dojo/add_related.html'

    form = AddEndpointForm(product=product)
    if request.method == 'POST':
        form = AddEndpointForm(request.POST, product=product)
        if form.is_valid():
            endpoints = form.save()
            tags = request.POST.getlist('tags')
            t = ", ".join(tags)
            for e in endpoints:
                e.tags = t
            messages.add_message(request,
                                 messages.SUCCESS,
                                 'Endpoint added successfully.',
                                 extra_tags='alert-success')
            if '_popup' in request.GET:
                resp = '<script type="text/javascript">opener.emptyEndpoints(window);</script>'
                for endpoint in endpoints:
                    resp += '<script type="text/javascript">opener.dismissAddAnotherPopupDojo(window, "%s", "%s");</script>' \
                            % (escape(endpoint._get_pk_val()), escape(endpoint))
                resp += '<script type="text/javascript">window.close();</script>'
                return HttpResponse(resp)
            else:
                return HttpResponseRedirect(
                    reverse('endpoints') + "?product=" + pid)

    product_tab = None
    if '_popup' not in request.GET:
        product_tab = Product_Tab(product.id, "Add Endpoint", tab="endpoints")

    return render(request, template, {
        'product_tab': product_tab,
        'name': 'Add Endpoint',
        'form': form
    })
Пример #36
0
def edit_engagement_presets(request, pid, eid):
    prod = get_object_or_404(Product, id=pid)
    preset = get_object_or_404(Engagement_Presets, id=eid)

    product_tab = Product_Tab(prod.id, title="Edit Engagement Preset", tab="settings")

    if request.method == 'POST':
        tform = EngagementPresetsForm(request.POST, instance=preset)
        if tform.is_valid():
            tform.save()
            messages.add_message(
                request,
                messages.SUCCESS,
                'Engagement Preset Successfully Updated.',
                extra_tags='alert-success')
            return HttpResponseRedirect(reverse('engagement_presets', args=(pid,)))
    else:
        tform = EngagementPresetsForm(instance=preset)

    return render(request, 'dojo/edit_presets.html',
                  {'product_tab': product_tab,
                   'tform': tform,
                   'prod': prod})
def delete_tool_product(request, pid, ttid):
    tool_product = Tool_Product_Settings.objects.get(pk=ttid)
    prod = get_object_or_404(Product, id=pid)
    if request.method == 'POST':
        tform = DeleteToolProductSettingsForm(request.POST,
                                              instance=tool_product)
        tool_product.delete()
        messages.add_message(request,
                             messages.SUCCESS,
                             'Tool Product Successfully Deleted.',
                             extra_tags='alert-success')
        return HttpResponseRedirect(reverse('all_tool_product', args=(pid, )))
    else:
        tform = ToolProductSettingsForm(instance=tool_product)

    product_tab = Product_Tab(pid,
                              title="Delete Product Tool Configuration",
                              tab="settings")

    return render(request, 'dojo/delete_tool_product.html', {
        'tform': tform,
        'product_tab': product_tab
    })
Пример #38
0
def new_cred_product(request, pid):
    prod = get_object_or_404(Product, pk=pid)
    if request.method == 'POST':
        tform = CredMappingFormProd(request.POST)
        if tform.is_valid():
            # 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(
                cred_id=tform.cleaned_data['cred_id'].id, product=pid).first()
            message = "Credential already associated."
            status_tag = 'alert-danger'

            if cred_user is None:
                prod = Product.objects.get(id=pid)
                new_f = tform.save(commit=False)
                new_f.product = prod
                new_f.save()
                message = 'Credential Successfully Updated.'
                status_tag = 'alert-success'

            messages.add_message(request,
                                 messages.SUCCESS,
                                 message,
                                 extra_tags=status_tag)
            return HttpResponseRedirect(
                reverse('all_cred_product', args=(pid, )))
    else:
        tform = CredMappingFormProd()

    product_tab = Product_Tab(pid,
                              title="Add Credential Configuration",
                              tab="settings")

    return render(request, 'dojo/new_cred_product.html', {
        'tform': tform,
        'pid': pid,
        'product_tab': product_tab
    })
Пример #39
0
def generate_report(request, obj):
    user = Dojo_User.objects.get(id=request.user.id)
    product_type = None
    product = None
    engagement = None
    test = None
    endpoint = None
    endpoints = None
    endpoint_all_findings = None
    endpoint_monthly_counts = None
    endpoint_active_findings = None
    accepted_findings = None
    open_findings = None
    closed_findings = None
    verified_findings = None
    report_title = None
    report_subtitle = None
    report_info = "Generated By %s on %s" % (
        user.get_full_name(), (timezone.now().strftime("%m/%d/%Y %I:%M%p %Z")))

    if type(obj).__name__ == "Product":
        if request.user.is_staff or request.user in obj.authorized_users.all():
            pass  # user is authorized for this product
        else:
            raise PermissionDenied
    elif type(obj).__name__ == "Endpoint":
        if request.user.is_staff or request.user in obj.product.authorized_users.all():
            pass  # user is authorized for this product
        else:
            raise PermissionDenied
    elif type(obj).__name__ == "QuerySet":
        # authorization taken care of by only selecting findings from product user is authed to see
        pass
    else:
        if not request.user.is_staff:
            raise PermissionDenied

    report_format = request.GET.get('report_type', 'AsciiDoc')
    include_finding_notes = int(request.GET.get('include_finding_notes', 0))
    include_finding_images = int(request.GET.get('include_finding_images', 0))
    include_executive_summary = int(request.GET.get('include_executive_summary', 0))
    include_table_of_contents = int(request.GET.get('include_table_of_contents', 0))
    generate = "_generate" in request.GET
    report_name = str(obj)
    report_type = type(obj).__name__
    add_breadcrumb(title="Generate Report", top_level=False, request=request)
    if type(obj).__name__ == "Product_Type":
        product_type = obj
        filename = "product_type_finding_report.pdf"
        template = "dojo/product_type_pdf_report.html"
        report_name = "Product Type Report: " + str(product_type)
        report_title = "Product Type Report"
        report_subtitle = str(product_type)

        findings = ReportFindingFilter(request.GET, queryset=Finding.objects.filter(
            test__engagement__product__prod_type=product_type).distinct().prefetch_related('test',
                                                                                           'test__engagement__product',
                                                                                           'test__engagement__product__prod_type'))
        products = Product.objects.filter(prod_type=product_type,
                                          engagement__test__finding__in=findings.qs).distinct()
        engagements = Engagement.objects.filter(product__prod_type=product_type,
                                                test__finding__in=findings.qs).distinct()
        tests = Test.objects.filter(engagement__product__prod_type=product_type,
                                    finding__in=findings.qs).distinct()
        if findings:
            start_date = timezone.make_aware(datetime.combine(findings.qs.last().date, datetime.min.time()))
        else:
            start_date = timezone.now()

        end_date = timezone.now()

        r = relativedelta(end_date, start_date)
        months_between = (r.years * 12) + r.months
        # include current month
        months_between += 1

        endpoint_monthly_counts = get_period_counts_legacy(findings.qs.order_by('numerical_severity'), findings.qs.order_by('numerical_severity'), None,
                                                            months_between, start_date,
                                                            relative_delta='months')

        context = {'product_type': product_type,
                   'products': products,
                   'engagements': engagements,
                   'tests': tests,
                   'report_name': report_name,
                   'endpoint_opened_per_month': endpoint_monthly_counts[
                       'opened_per_period'] if endpoint_monthly_counts is not None else [],
                   'endpoint_active_findings': findings.qs.order_by('numerical_severity'),
                   'findings': findings.qs.order_by('numerical_severity'),
                   'include_finding_notes': include_finding_notes,
                   'include_finding_images': include_finding_images,
                   'include_executive_summary': include_executive_summary,
                   'include_table_of_contents': include_table_of_contents,
                   'user': user,
                   'team_name': settings.TEAM_NAME,
                   'title': 'Generate Report',
                   'host': report_url_resolver(request),
                   'user_id': request.user.id}

    elif type(obj).__name__ == "Product":
        product = obj
        filename = "product_finding_report.pdf"
        template = "dojo/product_pdf_report.html"
        report_name = "Product Report: " + str(product)
        report_title = "Product Report"
        report_subtitle = str(product)
        findings = ReportFindingFilter(request.GET, queryset=Finding.objects.filter(
            test__engagement__product=product).distinct().prefetch_related('test',
                                                                           'test__engagement__product',
                                                                           'test__engagement__product__prod_type'))
        ids = set(finding.id for finding in findings.qs)
        engagements = Engagement.objects.filter(test__finding__id__in=ids).distinct()
        tests = Test.objects.filter(finding__id__in=ids).distinct()
        ids = get_endpoint_ids(Endpoint.objects.filter(product=product).distinct())
        endpoints = Endpoint.objects.filter(id__in=ids)
        context = {'product': product,
                   'engagements': engagements,
                   'tests': tests,
                   'report_name': report_name,
                   'findings': findings.qs.order_by('numerical_severity'),
                   'include_finding_notes': include_finding_notes,
                   'include_finding_images': include_finding_images,
                   'include_executive_summary': include_executive_summary,
                   'include_table_of_contents': include_table_of_contents,
                   'user': user,
                   'team_name': settings.TEAM_NAME,
                   'title': 'Generate Report',
                   'endpoints': endpoints,
                   'host': report_url_resolver(request),
                   'user_id': request.user.id}

    elif type(obj).__name__ == "Engagement":
        engagement = obj
        findings = ReportFindingFilter(request.GET,
                                       queryset=Finding.objects.filter(test__engagement=engagement,
                                                                       ).prefetch_related('test',
                                                                                          'test__engagement__product',
                                                                                          'test__engagement__product__prod_type').distinct())
        report_name = "Engagement Report: " + str(engagement)
        filename = "engagement_finding_report.pdf"
        template = 'dojo/engagement_pdf_report.html'
        report_title = "Engagement Report"
        report_subtitle = str(engagement)

        ids = set(finding.id for finding in findings.qs)
        tests = Test.objects.filter(finding__id__in=ids).distinct()
        ids = get_endpoint_ids(Endpoint.objects.filter(product=engagement.product).distinct())
        endpoints = Endpoint.objects.filter(id__in=ids)
        context = {'engagement': engagement,
                   'tests': tests,
                   'report_name': report_name,
                   'findings': findings.qs.order_by('numerical_severity'),
                   'include_finding_notes': include_finding_notes,
                   'include_finding_images': include_finding_images,
                   'include_executive_summary': include_executive_summary,
                   'include_table_of_contents': include_table_of_contents,
                   'user': user,
                   'team_name': settings.TEAM_NAME,
                   'title': 'Generate Report',
                   'host': report_url_resolver(request),
                   'user_id': request.user.id,
                   'endpoints': endpoints}

    elif type(obj).__name__ == "Test":
        test = obj
        findings = ReportFindingFilter(request.GET,
                                       queryset=Finding.objects.filter(test=test).prefetch_related('test',
                                                                                                   'test__engagement__product',
                                                                                                   'test__engagement__product__prod_type').distinct())
        filename = "test_finding_report.pdf"
        template = "dojo/test_pdf_report.html"
        report_name = "Test Report: " + str(test)
        report_title = "Test Report"
        report_subtitle = str(test)

        context = {'test': test,
                   'report_name': report_name,
                   'findings': findings.qs.order_by('numerical_severity'),
                   'include_finding_notes': include_finding_notes,
                   'include_finding_images': include_finding_images,
                   'include_executive_summary': include_executive_summary,
                   'include_table_of_contents': include_table_of_contents,
                   'user': user,
                   'team_name': settings.TEAM_NAME,
                   'title': 'Generate Report',
                   'host': report_url_resolver(request),
                   'user_id': request.user.id}

    elif type(obj).__name__ == "Endpoint":
        endpoint = obj
        host = endpoint.host_no_port
        report_name = "Endpoint Report: " + host
        report_type = "Endpoint"
        endpoints = Endpoint.objects.filter(host__regex="^" + host + ":?",
                                            product=endpoint.product).distinct()
        filename = "endpoint_finding_report.pdf"
        template = 'dojo/endpoint_pdf_report.html'
        report_title = "Endpoint Report"
        report_subtitle = host
        findings = ReportFindingFilter(request.GET,
                                       queryset=Finding.objects.filter(endpoints__in=endpoints,
                                                                       ).prefetch_related('test',
                                                                                          'test__engagement__product',
                                                                                          'test__engagement__product__prod_type').distinct())

        context = {'endpoint': endpoint,
                   'endpoints': endpoints,
                   'report_name': report_name,
                   'findings': findings.qs.order_by('numerical_severity'),
                   'include_finding_notes': include_finding_notes,
                   'include_finding_images': include_finding_images,
                   'include_executive_summary': include_executive_summary,
                   'include_table_of_contents': include_table_of_contents,
                   'user': user,
                   'team_name': get_system_setting('team_name'),
                   'title': 'Generate Report',
                   'host': report_url_resolver(request),
                   'user_id': request.user.id}
    elif type(obj).__name__ == "QuerySet":
        findings = ReportAuthedFindingFilter(request.GET,
                                             queryset=obj.prefetch_related('test',
                                                                           'test__engagement__product',
                                                                           'test__engagement__product__prod_type').distinct(),
                                             user=request.user)
        filename = "finding_report.pdf"
        report_name = 'Finding'
        report_type = 'Finding'
        template = 'dojo/finding_pdf_report.html'
        report_title = "Finding Report"
        report_subtitle = ''

        context = {'findings': findings.qs.order_by('numerical_severity'),
                   'report_name': report_name,
                   'include_finding_notes': include_finding_notes,
                   'include_finding_images': include_finding_images,
                   'include_executive_summary': include_executive_summary,
                   'include_table_of_contents': include_table_of_contents,
                   'user': user,
                   'team_name': settings.TEAM_NAME,
                   'title': 'Generate Report',
                   'host': report_url_resolver(request),
                   'user_id': request.user.id}
    else:
        raise Http404()

    report_form = ReportOptionsForm()

    if generate:
        report_form = ReportOptionsForm(request.GET)
        if report_format == 'AsciiDoc':
            return render(request,
                          'dojo/asciidoc_report.html',
                          {'product_type': product_type,
                           'product': product,
                           'engagement': engagement,
                           'test': test,
                           'endpoint': endpoint,
                           'findings': findings.qs.order_by('numerical_severity'),
                           'include_finding_notes': include_finding_notes,
                           'include_finding_images': include_finding_images,
                           'include_executive_summary': include_executive_summary,
                           'include_table_of_contents': include_table_of_contents,
                           'user': user,
                           'team_name': settings.TEAM_NAME,
                           'title': 'Generate Report',
                           'user_id': request.user.id,
                           'host': report_url_resolver(request),
                           })

        elif report_format == 'PDF':
            if 'regen' in request.GET:
                # we should already have a report object, lets get and use it
                report = get_object_or_404(Report, id=request.GET['regen'])
                report.datetime = timezone.now()
                report.status = 'requested'
                if report.requester.username != request.user.username:
                    report.requester = request.user
            else:
                # lets create the report object and send it in to celery task
                report = Report(name=report_name,
                                type=report_type,
                                format='PDF',
                                requester=request.user,
                                task_id='tbd',
                                options=request.path + "?" + request.GET.urlencode())
            report.save()
            async_pdf_report.delay(report=report,
                                   template=template,
                                   filename=filename,
                                   report_title=report_title,
                                   report_subtitle=report_subtitle,
                                   report_info=report_info,
                                   context=context,
                                   uri=request.build_absolute_uri(report.get_url()))
            messages.add_message(request, messages.SUCCESS,
                                 'Your report is building.',
                                 extra_tags='alert-success')

            return HttpResponseRedirect(reverse('reports'))

        elif report_format == 'HTML':
            return render(request,
                          template,
                          {'product_type': product_type,
                           'product': product,
                           'engagement': engagement,
                           'report_name': report_name,
                           'test': test,
                           'endpoint': endpoint,
                           'endpoints': endpoints,
                           'findings': findings.qs.order_by('numerical_severity'),
                           'include_finding_notes': include_finding_notes,
                           'include_finding_images': include_finding_images,
                           'include_executive_summary': include_executive_summary,
                           'include_table_of_contents': include_table_of_contents,
                           'user': user,
                           'team_name': settings.TEAM_NAME,
                           'title': 'Generate Report',
                           'user_id': request.user.id,
                           'host': "",
                           })

        else:
            raise Http404()
    paged_findings = get_page_items(request, findings.qs.order_by('numerical_severity'), 25)

    product_tab = None
    if engagement:
        product_tab = Product_Tab(engagement.product.id, title="Engagement Report", tab="engagements")
        product_tab.setEngagement(engagement)
    elif test:
        product_tab = Product_Tab(test.engagement.product.id, title="Test Report", tab="engagements")
        product_tab.setEngagement(test.engagement)
    elif product:
        product_tab = Product_Tab(product.id, title="Product Report", tab="findings")
    elif endpoints:
        product_tab = Product_Tab(endpoint.product.id, title="Endpoint Report", tab="endpoints")

    return render(request, 'dojo/request_report.html',
                  {'product_type': product_type,
                   'product': product,
                   'product_tab': product_tab,
                   'engagement': engagement,
                   'test': test,
                   'endpoint': endpoint,
                   'findings': findings,
                   'paged_findings': paged_findings,
                   'report_form': report_form,
                   })
Пример #40
0
def edit_engagement(request, eid):
    eng = Engagement.objects.get(pk=eid)
    ci_cd_form = False
    if eng.engagement_type == "CI/CD":
        ci_cd_form = True
    jform = None
    if request.method == 'POST':
        form = EngForm(request.POST, instance=eng, cicd=ci_cd_form, product=eng.product.id)
        if 'jiraform-push_to_jira' in request.POST:
            jform = JIRAFindingForm(
                request.POST, prefix='jiraform', enabled=True)

        if (form.is_valid() and jform is None) or (form.is_valid() and jform and jform.is_valid()):
            if 'jiraform-push_to_jira' in request.POST:
                if JIRA_Issue.objects.filter(engagement=eng).exists():
                    update_epic_task.delay(
                        eng, jform.cleaned_data.get('push_to_jira'))
                    enabled = True
                else:
                    enabled = False
                    add_epic_task.delay(eng,
                                        jform.cleaned_data.get('push_to_jira'))
            temp_form = form.save(commit=False)
            if (temp_form.status == "Cancelled" or temp_form.status == "Completed"):
                temp_form.active = False
            elif(temp_form.active is False):
                temp_form.active = True
            temp_form.save()
            tags = request.POST.getlist('tags')
            t = ", ".join(tags)
            eng.tags = t
            messages.add_message(
                request,
                messages.SUCCESS,
                'Engagement updated successfully.',
                extra_tags='alert-success')
            if '_Add Tests' in request.POST:
                return HttpResponseRedirect(
                    reverse('add_tests', args=(eng.id, )))
            else:
                return HttpResponseRedirect(
                    reverse('view_engagement', args=(eng.id, )))
    else:
        form = EngForm(instance=eng, cicd=ci_cd_form, product=eng.product.id)
        try:
            # jissue = JIRA_Issue.objects.get(engagement=eng)
            enabled = True
        except:
            enabled = False
            pass

        if get_system_setting('enable_jira') and JIRA_PKey.objects.filter(
                product=eng.product).count() != 0:
            jform = JIRAFindingForm(prefix='jiraform', enabled=enabled)
        else:
            jform = None

    form.initial['tags'] = [tag.name for tag in eng.tags]

    title = ""
    if eng.engagement_type == "CI/CD":
        title = " CI/CD"
    product_tab = Product_Tab(eng.product.id, title="Edit" + title + " Engagement", tab="engagements")
    product_tab.setEngagement(eng)
    return render(request, 'dojo/new_eng.html', {
        'product_tab': product_tab,
        'form': form,
        'edit': True,
        'jform': jform,
        'eng': eng
    })
Пример #41
0
def ad_hoc_finding(request, pid):
    prod = Product.objects.get(id=pid)
    test = None
    try:
        eng = Engagement.objects.get(product=prod, name="Ad Hoc Engagement")
        tests = Test.objects.filter(engagement=eng)

        if len(tests) != 0:
            test = tests[0]
        else:
            test = Test(engagement=eng, test_type=Test_Type.objects.get(name="Pen Test"),
                        target_start=timezone.now(), target_end=timezone.now())
            test.save()
    except:
        eng = Engagement(name="Ad Hoc Engagement", target_start=timezone.now(),
                         target_end=timezone.now(), active=False, product=prod)
        eng.save()
        test = Test(engagement=eng, test_type=Test_Type.objects.get(name="Pen Test"),
                    target_start=timezone.now(), target_end=timezone.now())
        test.save()
    form_error = False
    enabled = False
    jform = None
    form = AdHocFindingForm(initial={'date': timezone.now().date()})
    if get_system_setting('enable_jira'):
            if JIRA_PKey.objects.filter(product=test.engagement.product).count() != 0:
                enabled = JIRA_PKey.objects.get(product=test.engagement.product).push_all_issues
                jform = JIRAFindingForm(enabled=enabled, prefix='jiraform')
    else:
        jform = None
    if request.method == 'POST':
        form = AdHocFindingForm(request.POST)
        if form.is_valid():
            new_finding = form.save(commit=False)
            new_finding.test = test
            new_finding.reporter = request.user
            new_finding.numerical_severity = Finding.get_numerical_severity(
                new_finding.severity)
            if new_finding.false_p or new_finding.active is False:
                new_finding.mitigated = timezone.now()
                new_finding.mitigated_by = request.user
            create_template = new_finding.is_template
            # always false now since this will be deprecated soon in favor of new Finding_Template model
            new_finding.is_template = False
            new_finding.save()
            new_finding.endpoints = form.cleaned_data['endpoints']
            new_finding.save()
            if 'jiraform-push_to_jira' in request.POST:
                jform = JIRAFindingForm(request.POST, prefix='jiraform', enabled=enabled)
                if jform.is_valid():
                    add_issue_task.delay(new_finding, jform.cleaned_data.get('push_to_jira'))
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'Finding added successfully.',
                                     extra_tags='alert-success')
            if create_template:
                templates = Finding_Template.objects.filter(title=new_finding.title)
                if len(templates) > 0:
                    messages.add_message(request,
                                         messages.ERROR,
                                         'A finding template was not created.  A template with this title already '
                                         'exists.',
                                         extra_tags='alert-danger')
                else:
                    template = Finding_Template(title=new_finding.title,
                                                cwe=new_finding.cwe,
                                                severity=new_finding.severity,
                                                description=new_finding.description,
                                                mitigation=new_finding.mitigation,
                                                impact=new_finding.impact,
                                                references=new_finding.references,
                                                numerical_severity=new_finding.numerical_severity)
                    template.save()
                    messages.add_message(request,
                                         messages.SUCCESS,
                                         'A finding template was also created.',
                                         extra_tags='alert-success')
            if '_Finished' in request.POST:
                return HttpResponseRedirect(reverse('view_test', args=(test.id,)))
            else:
                return HttpResponseRedirect(reverse('add_findings', args=(test.id,)))
        else:
            if 'endpoints' in form.cleaned_data:
                form.fields['endpoints'].queryset = form.cleaned_data['endpoints']
            else:
                form.fields['endpoints'].queryset = Endpoint.objects.none()
            form_error = True
            messages.add_message(request,
                                 messages.ERROR,
                                 'The form has errors, please correct them below.',
                                 extra_tags='alert-danger')
    product_tab = Product_Tab(pid, title="Add Finding", tab="engagements")
    product_tab.setEngagement(eng)
    return render(request, 'dojo/ad_hoc_findings.html',
                  {'form': form,
                   'product_tab': product_tab,
                   'temp': False,
                   'tid': test.id,
                   'pid': pid,
                   'form_error': form_error,
                   'jform': jform,
                   })
Пример #42
0
def view_engagement(request, eid):
    eng = get_object_or_404(Engagement, id=eid)
    tests = Test.objects.filter(engagement=eng).order_by('test_type__name')
    prod = eng.product
    auth = request.user.is_staff or request.user in prod.authorized_users.all()
    risks_accepted = eng.risk_acceptance.all()
    preset_test_type = None
    network = None
    if eng.preset:
        preset_test_type = eng.preset.test_type.all()
        network = eng.preset.network_locations.all()
    system_settings = System_Settings.objects.get()
    if not auth:
        # will render 403
        raise PermissionDenied

    try:
        jissue = JIRA_Issue.objects.get(engagement=eng)
    except:
        jissue = None
        pass
    try:
        jconf = JIRA_PKey.objects.get(product=eng.product).conf
    except:
        jconf = None
        pass
    exclude_findings = [
        finding.id for ra in eng.risk_acceptance.all()
        for finding in ra.accepted_findings.all()
    ]
    eng_findings = Finding.objects.filter(test__in=eng.test_set.all()) \
        .exclude(id__in=exclude_findings).order_by('title')

    try:
        check = Check_List.objects.get(engagement=eng)
    except:
        check = None
        pass
    form = DoneForm()
    if request.method == 'POST' and request.user.is_staff:
        eng.progress = 'check_list'
        eng.save()

    creds = Cred_Mapping.objects.filter(
        product=eng.product).select_related('cred_id').order_by('cred_id')
    cred_eng = Cred_Mapping.objects.filter(
        engagement=eng.id).select_related('cred_id').order_by('cred_id')

    add_breadcrumb(parent=eng, top_level=False, request=request)
    if hasattr(settings, 'ENABLE_DEDUPLICATION'):
        if settings.ENABLE_DEDUPLICATION:
            enabled = True
            findings = Finding.objects.filter(
                test__engagement=eng, duplicate=False)
        else:
            enabled = False
            findings = None
    else:
        enabled = False
        findings = None

    if findings is not None:
        fpage = get_page_items(request, findings, 15)
    else:
        fpage = None

    # ----------

    try:
        start_date = Finding.objects.filter(
            test__engagement__product=eng.product).order_by('date')[:1][0].date
    except:
        start_date = timezone.now()

    end_date = timezone.now()

    risk_acceptances = Risk_Acceptance.objects.filter(
        engagement__in=Engagement.objects.filter(product=eng.product))

    accepted_findings = [
        finding for ra in risk_acceptances
        for finding in ra.accepted_findings.all()
    ]

    title = ""
    if eng.engagement_type == "CI/CD":
        title = " CI/CD"
    product_tab = Product_Tab(prod.id, title="View" + title + " Engagement", tab="engagements")
    product_tab.setEngagement(eng)
    return render(
        request, 'dojo/view_eng.html', {
            'eng': eng,
            'product_tab': product_tab,
            'system_settings': system_settings,
            'tests': tests,
            'findings': fpage,
            'enabled': enabled,
            'check': check,
            'threat': eng.tmodel_path,
            'risk': eng.risk_path,
            'form': form,
            'risks_accepted': risks_accepted,
            'can_add_risk': len(eng_findings),
            'jissue': jissue,
            'jconf': jconf,
            'accepted_findings': accepted_findings,
            'start_date': start_date,
            'creds': creds,
            'cred_eng': cred_eng,
            'network': network,
            'preset_test_type': preset_test_type
        })
Пример #43
0
def add_tests(request, eid):
    eng = Engagement.objects.get(id=eid)
    cred_form = CredMappingForm()
    cred_form.fields["cred_user"].queryset = Cred_Mapping.objects.filter(
        engagement=eng).order_by('cred_id')

    if request.method == 'POST':
        form = TestForm(request.POST)
        cred_form = CredMappingForm(request.POST)
        cred_form.fields["cred_user"].queryset = Cred_Mapping.objects.filter(
            engagement=eng).order_by('cred_id')
        if form.is_valid():
            new_test = form.save(commit=False)
            new_test.engagement = eng
            try:
                new_test.lead = User.objects.get(id=form['lead'].value())
            except:
                new_test.lead = None
                pass

            # Set status to in progress if a test is added
            if eng.status != "In Progress" and eng.active is True:
                eng.status = "In Progress"
                eng.save()

            new_test.save()
            tags = request.POST.getlist('tags')
            t = ", ".join(tags)
            new_test.tags = t

            # 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 = new_test
                    new_f.cred_id = cred_user.cred_id
                    new_f.save()

            messages.add_message(
                request,
                messages.SUCCESS,
                'Test added successfully.',
                extra_tags='alert-success')

            create_notification(
                event='test_added',
                title=new_test.test_type.name + " for " + eng.product.name,
                test=new_test,
                engagement=eng,
                url=request.build_absolute_uri(
                    reverse('view_engagement', args=(eng.id, ))))

            if '_Add Another Test' in request.POST:
                return HttpResponseRedirect(
                    reverse('add_tests', args=(eng.id, )))
            elif '_Add Findings' in request.POST:
                return HttpResponseRedirect(
                    reverse('add_findings', args=(new_test.id, )))
            elif '_Finished' in request.POST:
                return HttpResponseRedirect(
                    reverse('view_engagement', args=(eng.id, )))
    else:
        form = TestForm()
        form.initial['target_start'] = eng.target_start
        form.initial['target_end'] = eng.target_end
        form.initial['lead'] = request.user
    add_breadcrumb(
        parent=eng, title="Add Tests", top_level=False, request=request)
    product_tab = Product_Tab(eng.product.id, title="Add Tests", tab="engagements")
    product_tab.setEngagement(eng)
    return render(request, 'dojo/add_tests.html', {
        'product_tab': product_tab,
        'form': form,
        'cred_form': cred_form,
        'eid': eid,
        'eng': eng
    })
Пример #44
0
def import_scan_results(request, eid=None, pid=None):
    engagement = None
    form = ImportScanForm()
    cred_form = CredMappingForm()
    finding_count = 0

    if eid:
        engagement = get_object_or_404(Engagement, id=eid)
        cred_form.fields["cred_user"].queryset = Cred_Mapping.objects.filter(engagement=engagement).order_by('cred_id')

    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 form.is_valid():
            # Allows for a test to be imported with an engagement created on the fly
            if engagement is None:
                engagement = Engagement()
                product = get_object_or_404(Product, id=pid)
                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.save()
            file = request.FILES['file']
            scan_date = form.cleaned_data['scan_date']
            min_sev = form.cleaned_data['minimum_severity']
            active = form.cleaned_data['active']
            verified = form.cleaned_data['verified']

            scan_type = request.POST['scan_type']
            if not any(scan_type in code
                       for code in ImportScanForm.SCAN_TYPE_CHOICES):
                raise Http404()

            tt, t_created = Test_Type.objects.get_or_create(name=scan_type)
            # will save in development environment
            environment, env_created = Development_Environment.objects.get_or_create(
                name="Development")
            t = Test(
                engagement=engagement,
                test_type=tt,
                target_start=scan_date,
                target_end=scan_date,
                environment=environment,
                percent_complete=100)
            t.lead = request.user
            t.full_clean()
            t.save()
            tags = request.POST.getlist('tags')
            ts = ", ".join(tags)
            t.tags = ts

            # 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 = t
                    new_f.cred_id = cred_user.cred_id
                    new_f.save()

            parser = import_parser_factory(file, t)

            try:
                for item in parser.items:
                    print "item blowup"
                    print item
                    sev = item.severity
                    if sev == 'Information' or sev == 'Informational':
                        sev = 'Info'

                    item.severity = sev

                    if Finding.SEVERITIES[sev] > Finding.SEVERITIES[min_sev]:
                        continue

                    item.test = t
                    if item.date == timezone.now().date():
                        item.date = t.target_start

                    item.reporter = request.user
                    item.last_reviewed = timezone.now()
                    item.last_reviewed_by = request.user
                    item.active = active
                    item.verified = verified
                    item.save(dedupe_option=False, false_history=True)

                    if hasattr(item, 'unsaved_req_resp') and len(
                            item.unsaved_req_resp) > 0:
                        for req_resp in item.unsaved_req_resp:
                            burp_rr = BurpRawRequestResponse(
                                finding=item,
                                burpRequestBase64=req_resp["req"],
                                burpResponseBase64=req_resp["resp"],
                            )
                            burp_rr.clean()
                            burp_rr.save()

                    if item.unsaved_request is not None and item.unsaved_response is not None:
                        burp_rr = BurpRawRequestResponse(
                            finding=item,
                            burpRequestBase64=item.unsaved_request,
                            burpResponseBase64=item.unsaved_response,
                        )
                        burp_rr.clean()
                        burp_rr.save()

                    for endpoint in item.unsaved_endpoints:
                        ep, created = Endpoint.objects.get_or_create(
                            protocol=endpoint.protocol,
                            host=endpoint.host,
                            path=endpoint.path,
                            query=endpoint.query,
                            fragment=endpoint.fragment,
                            product=t.engagement.product)

                        item.endpoints.add(ep)
                    item.save(false_history=True)

                    if item.unsaved_tags is not None:
                        item.tags = item.unsaved_tags

                    finding_count += 1

                messages.add_message(
                    request,
                    messages.SUCCESS,
                    scan_type + ' processed, a total of ' + message(
                        finding_count, 'finding', 'processed'),
                    extra_tags='alert-success')

                create_notification(
                    event='results_added',
                    title=str(finding_count) + " findings for " + engagement.product.name,
                    finding_count=finding_count,
                    test=t,
                    engagement=engagement,
                    url=request.build_absolute_uri(
                        reverse('view_test', args=(t.id, ))))

                return HttpResponseRedirect(
                    reverse('view_test', args=(t.id, )))
            except SyntaxError:
                messages.add_message(
                    request,
                    messages.ERROR,
                    'There appears to be an error in the XML report, please check and try again.',
                    extra_tags='alert-danger')
    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")

    return render(request, 'dojo/import_scan_results.html', {
        'form': form,
        'product_tab': product_tab,
        'custom_breadcrumb': custom_breadcrumb,
        'title': title,
        'cred_form': cred_form,
    })
Пример #45
0
def re_import_scan_results(request, tid):
    additional_message = "When re-uploading a scan, any findings not found in original scan will be updated as " \
                         "mitigated.  The process attempts to identify the differences, however manual verification " \
                         "is highly recommended."
    t = get_object_or_404(Test, id=tid)
    scan_type = t.test_type.name
    engagement = t.engagement
    form = ReImportScanForm()

    form.initial['tags'] = [tag.name for tag in t.tags]
    if request.method == "POST":
        form = ReImportScanForm(request.POST, request.FILES)
        if form.is_valid():
            scan_date = form.cleaned_data['scan_date']
            min_sev = form.cleaned_data['minimum_severity']
            file = request.FILES['file']
            scan_type = t.test_type.name
            active = form.cleaned_data['active']
            verified = form.cleaned_data['verified']
            tags = request.POST.getlist('tags')
            ts = ", ".join(tags)
            t.tags = ts
            try:
                parser = import_parser_factory(file, t)
            except ValueError:
                raise Http404()

            try:
                items = parser.items
                original_items = t.finding_set.all().values_list("id", flat=True)
                new_items = []
                mitigated_count = 0
                finding_count = 0
                finding_added_count = 0
                reactivated_count = 0
                for item in items:
                    sev = item.severity
                    if sev == 'Information' or sev == 'Informational':
                        sev = 'Info'
                        item.severity = sev

                    if Finding.SEVERITIES[sev] > Finding.SEVERITIES[min_sev]:
                        continue

                    if scan_type == 'Veracode Scan' or scan_type == 'Arachni Scan':
                        find = Finding.objects.filter(title=item.title,
                                                      test__id=t.id,
                                                      severity=sev,
                                                      numerical_severity=Finding.get_numerical_severity(sev),
                                                      description=item.description
                                                      )
                    else:
                        find = Finding.objects.filter(title=item.title,
                                                      test__id=t.id,
                                                      severity=sev,
                                                      numerical_severity=Finding.get_numerical_severity(sev),
                                                      )

                    if len(find) == 1:
                        find = find[0]
                        if find.mitigated:
                            # it was once fixed, but now back
                            find.mitigated = None
                            find.mitigated_by = None
                            find.active = True
                            find.verified = verified
                            find.save()
                            note = Notes(entry="Re-activated by %s re-upload." % scan_type,
                                         author=request.user)
                            note.save()
                            find.notes.add(note)
                            reactivated_count += 1
                        new_items.append(find.id)
                    else:
                        item.test = t
                        item.date = t.target_start
                        item.reporter = request.user
                        item.last_reviewed = timezone.now()
                        item.last_reviewed_by = request.user
                        item.verified = verified
                        item.active = active
                        item.save()
                        finding_added_count += 1
                        new_items.append(item.id)
                        find = item

                        if hasattr(item, 'unsaved_req_resp') and len(item.unsaved_req_resp) > 0:
                            for req_resp in item.unsaved_req_resp:
                                burp_rr = BurpRawRequestResponse(finding=find,
                                                                 burpRequestBase64=req_resp["req"],
                                                                 burpResponseBase64=req_resp["resp"],
                                                                 )
                                burp_rr.clean()
                                burp_rr.save()

                        if item.unsaved_request is not None and item.unsaved_response is not None:
                            burp_rr = BurpRawRequestResponse(finding=find,
                                                             burpRequestBase64=item.unsaved_request,
                                                             burpResponseBase64=item.unsaved_response,
                                                             )
                            burp_rr.clean()
                            burp_rr.save()
                    if find:
                        finding_count += 1
                        for endpoint in item.unsaved_endpoints:
                            ep, created = Endpoint.objects.get_or_create(protocol=endpoint.protocol,
                                                                         host=endpoint.host,
                                                                         path=endpoint.path,
                                                                         query=endpoint.query,
                                                                         fragment=endpoint.fragment,
                                                                         product=t.engagement.product)
                            find.endpoints.add(ep)

                        if item.unsaved_tags is not None:
                            find.tags = item.unsaved_tags

                # calculate the difference
                to_mitigate = set(original_items) - set(new_items)
                for finding_id in to_mitigate:
                    finding = Finding.objects.get(id=finding_id)
                    finding.mitigated = datetime.combine(scan_date, timezone.now().time())
                    finding.mitigated_by = request.user
                    finding.active = False
                    finding.save()
                    note = Notes(entry="Mitigated by %s re-upload." % scan_type,
                                 author=request.user)
                    note.save()
                    finding.notes.add(note)
                    mitigated_count += 1
                messages.add_message(request,
                                     messages.SUCCESS,
                                     '%s processed, a total of ' % scan_type + message(finding_count, 'finding',
                                                                                       'processed'),
                                     extra_tags='alert-success')
                if finding_added_count > 0:
                    messages.add_message(request,
                                         messages.SUCCESS,
                                         'A total of ' + message(finding_added_count, 'finding',
                                                                 'added') + ', that are new to scan.',
                                         extra_tags='alert-success')
                if reactivated_count > 0:
                    messages.add_message(request,
                                         messages.SUCCESS,
                                         'A total of ' + message(reactivated_count, 'finding',
                                                                 'reactivated') + ', that are back in scan results.',
                                         extra_tags='alert-success')
                if mitigated_count > 0:
                    messages.add_message(request,
                                         messages.SUCCESS,
                                         'A total of ' + message(mitigated_count, 'finding',
                                                                 'mitigated') + '. Please manually verify each one.',
                                         extra_tags='alert-success')

                create_notification(event='results_added', title=str(finding_count) + " findings for " + engagement.product.name, finding_count=finding_count, test=t, engagement=engagement, url=request.build_absolute_uri(reverse('view_test', args=(t.id,))))

                return HttpResponseRedirect(reverse('view_test', args=(t.id,)))
            except SyntaxError:
                messages.add_message(request,
                                     messages.ERROR,
                                     'There appears to be an error in the XML report, please check and try again.',
                                     extra_tags='alert-danger')

    product_tab = Product_Tab(engagement.product.id, title="Re-upload a %s" % scan_type, tab="engagements")
    product_tab.setEngagement(engagement)
    return render(request,
                  'dojo/import_scan_results.html',
                  {'form': form,
                   'product_tab': product_tab,
                   'eid': engagement.id,
                   'additional_message': additional_message,
                   })
Пример #46
0
def view_risk(request, eid, raid):
    risk_approval = get_object_or_404(Risk_Acceptance, pk=raid)
    eng = get_object_or_404(Engagement, pk=eid)
    if (request.user.is_staff or request.user in eng.product.authorized_users.all()):
        pass
    else:
        raise PermissionDenied

    a_file = risk_approval.path

    if request.method == 'POST':
        note_form = NoteForm(request.POST)
        if note_form.is_valid():
            new_note = note_form.save(commit=False)
            new_note.author = request.user
            new_note.date = timezone.now()
            new_note.save()
            risk_approval.notes.add(new_note)
            messages.add_message(
                request,
                messages.SUCCESS,
                'Note added successfully.',
                extra_tags='alert-success')

        if 'delete_note' in request.POST:
            note = get_object_or_404(Notes, pk=request.POST['delete_note_id'])
            if note.author.username == request.user.username:
                risk_approval.notes.remove(note)
                note.delete()
                messages.add_message(
                    request,
                    messages.SUCCESS,
                    'Note deleted successfully.',
                    extra_tags='alert-success')
            else:
                messages.add_message(
                    request,
                    messages.ERROR,
                    "Since you are not the note's author, it was not deleted.",
                    extra_tags='alert-danger')

        if 'remove_finding' in request.POST:
            finding = get_object_or_404(
                Finding, pk=request.POST['remove_finding_id'])
            risk_approval.accepted_findings.remove(finding)
            finding.active = True
            finding.save()
            messages.add_message(
                request,
                messages.SUCCESS,
                'Finding removed successfully.',
                extra_tags='alert-success')
        if 'replace_file' in request.POST:
            replace_form = ReplaceRiskAcceptanceForm(
                request.POST, request.FILES, instance=risk_approval)
            if replace_form.is_valid():
                risk_approval.path.delete(save=False)
                risk_approval.path = replace_form.cleaned_data['path']
                risk_approval.save()
                messages.add_message(
                    request,
                    messages.SUCCESS,
                    'File replaced successfully.',
                    extra_tags='alert-success')
        if 'add_findings' in request.POST:
            add_findings_form = AddFindingsRiskAcceptanceForm(
                request.POST, request.FILES, instance=risk_approval)
            if add_findings_form.is_valid():
                findings = add_findings_form.cleaned_data['accepted_findings']
                for finding in findings:
                    finding.active = False
                    finding.save()
                    risk_approval.accepted_findings.add(finding)
                risk_approval.save()
                messages.add_message(
                    request,
                    messages.SUCCESS,
                    'Finding%s added successfully.' % ('s' if len(findings) > 1
                                                       else ''),
                    extra_tags='alert-success')

    note_form = NoteForm()
    replace_form = ReplaceRiskAcceptanceForm()
    add_findings_form = AddFindingsRiskAcceptanceForm()
    exclude_findings = [
        finding.id for ra in eng.risk_acceptance.all()
        for finding in ra.accepted_findings.all()
    ]
    findings = Finding.objects.filter(test__in=eng.test_set.all()) \
        .exclude(id__in=exclude_findings).order_by("title")

    add_fpage = get_page_items(request, findings, 10, 'apage')
    add_findings_form.fields[
        "accepted_findings"].queryset = add_fpage.object_list

    fpage = get_page_items(
        request,
        risk_approval.accepted_findings.order_by('numerical_severity'), 15)

    authorized = (request.user == risk_approval.reporter.username or request.user.is_staff)

    product_tab = Product_Tab(eng.product.id, title="Risk Exception", tab="engagements")
    product_tab.setEngagement(eng)
    return render(
        request, 'dojo/view_risk.html', {
            'risk_approval': risk_approval,
            'product_tab': product_tab,
            'accepted_findings': fpage,
            'notes': risk_approval.notes.all(),
            'a_file': a_file,
            'eng': eng,
            'note_form': note_form,
            'replace_form': replace_form,
            'add_findings_form': add_findings_form,
            'show_add_findings_form': len(findings),
            'request': request,
            'add_findings': add_fpage,
            'authorized': authorized,
        })
Пример #47
0
def add_temp_finding(request, tid, fid):
    jform = None
    test = get_object_or_404(Test, id=tid)
    finding = get_object_or_404(Finding_Template, id=fid)
    findings = Finding_Template.objects.all()

    if request.method == 'POST':
        form = FindingForm(request.POST)
        if form.is_valid():
            new_finding = form.save(commit=False)
            new_finding.test = test
            new_finding.reporter = request.user
            new_finding.numerical_severity = Finding.get_numerical_severity(
                new_finding.severity)
            new_finding.date = datetime.today()
            if new_finding.false_p or new_finding.active is False:
                new_finding.mitigated = timezone.now()
                new_finding.mitigated_by = request.user

            create_template = new_finding.is_template
            # is template always False now in favor of new model Finding_Template
            # no further action needed here since this is already adding from template.
            new_finding.is_template = False
            new_finding.save(dedupe_option=False, false_history=False)
            new_finding.endpoints = form.cleaned_data['endpoints']
            new_finding.save(false_history=True)
            if 'jiraform-push_to_jira' in request.POST:
                    jform = JIRAFindingForm(request.POST, prefix='jiraform', enabled=True)
                    if jform.is_valid():
                        add_issue_task.delay(new_finding, jform.cleaned_data.get('push_to_jira'))
            messages.add_message(request,
                                 messages.SUCCESS,
                                 'Finding from template added successfully.',
                                 extra_tags='alert-success')

            if create_template:
                templates = Finding_Template.objects.filter(title=new_finding.title)
                if len(templates) > 0:
                    messages.add_message(request,
                                         messages.ERROR,
                                         'A finding template was not created.  A template with this title already '
                                         'exists.',
                                         extra_tags='alert-danger')
                else:
                    template = Finding_Template(title=new_finding.title,
                                                cwe=new_finding.cwe,
                                                severity=new_finding.severity,
                                                description=new_finding.description,
                                                mitigation=new_finding.mitigation,
                                                impact=new_finding.impact,
                                                references=new_finding.references,
                                                numerical_severity=new_finding.numerical_severity)
                    template.save()
                    messages.add_message(request,
                                         messages.SUCCESS,
                                         'A finding template was also created.',
                                         extra_tags='alert-success')

            return HttpResponseRedirect(reverse('view_test', args=(test.id,)))
        else:
            messages.add_message(request,
                                 messages.ERROR,
                                 'The form has errors, please correct them below.',
                                 extra_tags='alert-danger')

    else:
        form = FindingForm(initial={'active': False,
                                    'date': timezone.now().date(),
                                    'verified': False,
                                    'false_p': False,
                                    'duplicate': False,
                                    'out_of_scope': False,
                                    'title': finding.title,
                                    'description': finding.description,
                                    'cwe': finding.cwe,
                                    'severity': finding.severity,
                                    'mitigation': finding.mitigation,
                                    'impact': finding.impact,
                                    'references': finding.references,
                                    'numerical_severity': finding.numerical_severity})
        if get_system_setting('enable_jira'):
            enabled = JIRA_PKey.objects.get(product=test.engagement.product).push_all_issues
            jform = JIRAFindingForm(enabled=enabled, prefix='jiraform')
        else:
            jform = None

    product_tab = Product_Tab(test.engagement.product.id, title="Add Finding", tab="engagements")
    product_tab.setEngagement(test.engagement)
    return render(request, 'dojo/add_findings.html',
                  {'form': form,
                   'product_tab': product_tab,
                   'jform': jform,
                   'findings': findings,
                   'temp': True,
                   'fid': finding.id,
                   'tid': test.id,
                   'test': test,
                   })
Пример #48
0
def add_findings(request, tid):
    test = Test.objects.get(id=tid)
    form_error = False
    enabled = False
    jform = None
    form = AddFindingForm(initial={'date': timezone.now().date()})

    if get_system_setting('enable_jira') and JIRA_PKey.objects.filter(product=test.engagement.product).count() != 0:
        enabled = JIRA_PKey.objects.get(product=test.engagement.product).push_all_issues
        jform = JIRAFindingForm(enabled=enabled, prefix='jiraform')
    else:
        jform = None

    if request.method == 'POST':
        form = AddFindingForm(request.POST)
        if form['active'].value() is False or form['verified'].value() is False and 'jiraform-push_to_jira' in request.POST:
            error = ValidationError('Findings must be active and verified to be pushed to JIRA',
                                    code='not_active_or_verified')
            if form['active'].value() is False:
                form.add_error('active', error)
            if form['verified'].value() is False:
                form.add_error('verified', error)
            messages.add_message(request,
                                 messages.ERROR,
                                 'Findings must be active and verified to be pushed to JIRA',
                                 extra_tags='alert-danger')
        if form['severity'].value() == 'Info' and 'jiraform-push_to_jira' in request.POST:
            error = ValidationError('Findings with Informational severity cannot be pushed to JIRA.',
                                    code='info-severity-to-jira')
        if form.is_valid():
            new_finding = form.save(commit=False)
            new_finding.test = test
            new_finding.reporter = request.user
            new_finding.numerical_severity = Finding.get_numerical_severity(
                new_finding.severity)
            if new_finding.false_p or new_finding.active is False:
                new_finding.mitigated = timezone.now()
                new_finding.mitigated_by = request.user
            create_template = new_finding.is_template
            # always false now since this will be deprecated soon in favor of new Finding_Template model
            new_finding.is_template = False
            new_finding.save(dedupe_option=False)
            new_finding.endpoints = form.cleaned_data['endpoints']
            new_finding.save(false_history=True)
            if 'jiraform-push_to_jira' in request.POST:
                jform = JIRAFindingForm(request.POST, prefix='jiraform', enabled=enabled)
                if jform.is_valid():
                    add_issue_task.delay(new_finding, jform.cleaned_data.get('push_to_jira'))
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'Finding added successfully.',
                                     extra_tags='alert-success')
            if create_template:
                templates = Finding_Template.objects.filter(title=new_finding.title)
                if len(templates) > 0:
                    messages.add_message(request,
                                         messages.ERROR,
                                         'A finding template was not created.  A template with this title already '
                                         'exists.',
                                         extra_tags='alert-danger')
                else:
                    template = Finding_Template(title=new_finding.title,
                                                cwe=new_finding.cwe,
                                                severity=new_finding.severity,
                                                description=new_finding.description,
                                                mitigation=new_finding.mitigation,
                                                impact=new_finding.impact,
                                                references=new_finding.references,
                                                numerical_severity=new_finding.numerical_severity)
                    template.save()
                    messages.add_message(request,
                                         messages.SUCCESS,
                                         'A finding template was also created.',
                                         extra_tags='alert-success')
            if '_Finished' in request.POST:
                return HttpResponseRedirect(reverse('view_test', args=(test.id,)))
            else:
                return HttpResponseRedirect(reverse('add_findings', args=(test.id,)))
        else:
            if 'endpoints' in form.cleaned_data:
                form.fields['endpoints'].queryset = form.cleaned_data['endpoints']
            else:
                form.fields['endpoints'].queryset = Endpoint.objects.none()
            form_error = True
            messages.add_message(request,
                                 messages.ERROR,
                                 'The form has errors, please correct them below.',
                                 extra_tags='alert-danger')
    product_tab = Product_Tab(test.engagement.product.id, title="Add Finding", tab="engagements")
    product_tab.setEngagement(test.engagement)
    return render(request, 'dojo/add_findings.html',
                  {'form': form,
                   'product_tab': product_tab,
                   'test': test,
                   'temp': False,
                   'tid': tid,
                   'form_error': form_error,
                   'jform': jform,
                   })