Example #1
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()

    if (request.user in endpoint.product.authorized_users.all()
        ) or request.user.is_staff:
        pass
    else:
        raise PermissionDenied

    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]

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

    verified_findings = Finding.objects.filter(endpoints__in=endpoints,
                                               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(verified_findings,
                                       all_findings,
                                       closed_findings,
                                       None,
                                       months_between,
                                       start_date,
                                       relative_delta='months')

    paged_findings = get_page_items(request, verified_findings, 25)

    add_breadcrumb(parent=endpoint, top_level=False, request=request)
    return render(
        request, "dojo/view_endpoint.html", {
            "endpoint": endpoint,
            "endpoints": endpoints,
            "findings": paged_findings,
            'all_findings': all_findings,
            'opened_per_month': monthly_counts['opened_per_period'],
            'endpoint_metadata': endpoint_metadata,
        })
Example #2
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,
        })
Example #3
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,
        })
Example #4
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()

    if (request.user in endpoint.product.authorized_users.all()) or request.user.is_staff:
        pass
    else:
        raise PermissionDenied

    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]


    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)

    add_breadcrumb(parent=endpoint, top_level=False, request=request)
    return render(request,
                  "dojo/view_endpoint.html",
                  {"endpoint": endpoint,
                   "endpoints": endpoints,
                   "findings": paged_findings,
                   'all_findings': all_findings,
                   'opened_per_month': monthly_counts['opened_per_period'],
                   'endpoint_metadata': endpoint_metadata,
                   })
Example #5
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()

    if (request.user in endpoint.product.authorized_users.all()) or request.user.is_staff:
        pass
    else:
        raise PermissionDenied

    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,
                   })
Example #6
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()

    if (request.user in endpoint.product.authorized_users.all()
        ) or request.user.is_staff:
        pass
    else:
        raise PermissionDenied

    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 = localtz.localize(
            datetime.combine(all_findings.last().date, datetime.min.time()))
    else:
        start_date = localtz.localize(datetime.today())
    end_date = localtz.localize(datetime.today())

    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)

    add_breadcrumb(parent=endpoint, top_level=False, request=request)
    return render(
        request, "dojo/view_endpoint.html", {
            "endpoint": endpoint,
            "endpoints": endpoints,
            "findings": paged_findings,
            'all_findings': all_findings,
            'opened_per_month': monthly_counts['opened_per_period'],
        })
Example #7
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()

    if (request.user in endpoint.product.authorized_users.all()) or request.user.is_staff:
        pass
    else:
        raise PermissionDenied

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

    active_findings = Finding.objects.filter(endpoints__in=endpoints,
                                             active=True,
                                             verified=True).distinct()
    if all_findings:
        start_date = localtz.localize(datetime.combine(all_findings.last().date, datetime.min.time()))
    else:
        start_date = localtz.localize(datetime.today())
    end_date = localtz.localize(datetime.today())

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

    monthly_counts = get_period_counts(all_findings, all_findings, None, months_between, start_date,
                                       relative_delta='months')
    paged_findings = get_page_items(request, active_findings, 25)

    add_breadcrumb(parent=endpoint, top_level=False, request=request)
    return render(request,
                  "dojo/view_endpoint.html",
                  {"endpoint": endpoint,
                   "endpoints": endpoints,
                   "findings": paged_findings,
                   'all_findings': all_findings,
                   'opened_per_month': monthly_counts['opened_per_period'],
                   })
Example #8
0
def metrics(request, mtype):
    template = 'dojo/metrics.html'
    page_name = 'Product Type Metrics'
    show_pt_filter = True

    findings = Finding.objects.filter(verified=True,
                                      severity__in=('Critical', 'High', 'Medium', 'Low', 'Info')).prefetch_related(
        'test__engagement__product',
        'test__engagement__product__prod_type',
        'test__engagement__risk_acceptance',
        'risk_acceptance_set',
        'reporter').extra(
        select={
            'ra_count': 'SELECT COUNT(*) FROM dojo_risk_acceptance INNER JOIN '
                        'dojo_risk_acceptance_accepted_findings ON '
                        '( dojo_risk_acceptance.id = dojo_risk_acceptance_accepted_findings.risk_acceptance_id ) '
                        'WHERE dojo_risk_acceptance_accepted_findings.finding_id = dojo_finding.id',
        },
    )
    active_findings = Finding.objects.filter(verified=True, active=True,
                                      severity__in=('Critical', 'High', 'Medium', 'Low', 'Info')).prefetch_related(
        'test__engagement__product',
        'test__engagement__product__prod_type',
        'test__engagement__risk_acceptance',
        'risk_acceptance_set',
        'reporter').extra(
        select={
            'ra_count': 'SELECT COUNT(*) FROM dojo_risk_acceptance INNER JOIN '
                        'dojo_risk_acceptance_accepted_findings ON '
                        '( dojo_risk_acceptance.id = dojo_risk_acceptance_accepted_findings.risk_acceptance_id ) '
                        'WHERE dojo_risk_acceptance_accepted_findings.finding_id = dojo_finding.id',
    },
    )

    if mtype != 'All':
        pt = Product_Type.objects.filter(id=mtype)
        request.GET._mutable = True
        request.GET.appendlist('test__engagement__product__prod_type', mtype)
        request.GET._mutable = False
        mtype = pt[0].name
        show_pt_filter = False
        page_name = '%s Metrics' % mtype
        prod_type = pt
    elif 'test__engagement__product__prod_type' in request.GET:
        prod_type = Product_Type.objects.filter(id__in=request.GET.getlist('test__engagement__product__prod_type', []))
    else:
        prod_type = Product_Type.objects.all()
    findings = MetricsFindingFilter(request.GET, queryset=findings)
    active_findings = MetricsFindingFilter(request.GET, queryset=active_findings)

    findings.qs  # this is needed to load details from filter since it is lazy
    active_findings.qs  # this is needed to load details from filter since it is lazy

    start_date = findings.filters['date'].start_date
    start_date = datetime(start_date.year,
                          start_date.month, start_date.day,
                          tzinfo=timezone.get_current_timezone())
    end_date = findings.filters['date'].end_date
    end_date = datetime(end_date.year,
                        end_date.month, end_date.day,
                        tzinfo=timezone.get_current_timezone())

    if len(prod_type) > 0:
        findings_closed = Finding.objects.filter(mitigated__range=[start_date, end_date],
                                                 test__engagement__product__prod_type__in=prod_type).prefetch_related(
            'test__engagement__product')
        # capture the accepted findings in period
        accepted_findings = Finding.objects.filter(risk_acceptance__created__range=[start_date, end_date],
                                                   test__engagement__product__prod_type__in=prod_type). \
            prefetch_related('test__engagement__product')
        accepted_findings_counts = Finding.objects.filter(risk_acceptance__created__range=[start_date, end_date],
                                                          test__engagement__product__prod_type__in=prod_type). \
            prefetch_related('test__engagement__product').aggregate(
            total=Sum(
                Case(When(severity__in=('Critical', 'High', 'Medium', 'Low'),
                          then=Value(1)),
                     output_field=IntegerField())),
            critical=Sum(
                Case(When(severity='Critical',
                          then=Value(1)),
                     output_field=IntegerField())),
            high=Sum(
                Case(When(severity='High',
                          then=Value(1)),
                     output_field=IntegerField())),
            medium=Sum(
                Case(When(severity='Medium',
                          then=Value(1)),
                     output_field=IntegerField())),
            low=Sum(
                Case(When(severity='Low',
                          then=Value(1)),
                     output_field=IntegerField())),
            info=Sum(
                Case(When(severity='Info',
                          then=Value(1)),
                     output_field=IntegerField())),
        )
    else:
        findings_closed = Finding.objects.filter(mitigated__range=[start_date, end_date]).prefetch_related(
            'test__engagement__product')
        accepted_findings = Finding.objects.filter(risk_acceptance__created__range=[start_date, end_date]). \
            prefetch_related('test__engagement__product')
        accepted_findings_counts = Finding.objects.filter(risk_acceptance__created__range=[start_date, end_date]). \
            prefetch_related('test__engagement__product').aggregate(
            total=Sum(
                Case(When(severity__in=('Critical', 'High', 'Medium', 'Low'),
                          then=Value(1)),
                     output_field=IntegerField())),
            critical=Sum(
                Case(When(severity='Critical',
                          then=Value(1)),
                     output_field=IntegerField())),
            high=Sum(
                Case(When(severity='High',
                          then=Value(1)),
                     output_field=IntegerField())),
            medium=Sum(
                Case(When(severity='Medium',
                          then=Value(1)),
                     output_field=IntegerField())),
            low=Sum(
                Case(When(severity='Low',
                          then=Value(1)),
                     output_field=IntegerField())),
            info=Sum(
                Case(When(severity='Info',
                          then=Value(1)),
                     output_field=IntegerField())),
        )

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

    weeks_between = int(ceil((((r.years * 12) + r.months) * 4.33) + (r.days / 7)))
    if weeks_between <= 0:
        weeks_between += 2

    monthly_counts = get_period_counts(active_findings.qs, findings.qs, findings_closed, accepted_findings, months_between, start_date,
                                       relative_delta='months')
    weekly_counts = get_period_counts(active_findings.qs, findings.qs, findings_closed, accepted_findings, weeks_between, start_date,
                                      relative_delta='weeks')

    top_ten = Product.objects.filter(engagement__test__finding__verified=True,
                                     engagement__test__finding__false_p=False,
                                     engagement__test__finding__duplicate=False,
                                     engagement__test__finding__out_of_scope=False,
                                     engagement__test__finding__mitigated__isnull=True,
                                     engagement__test__finding__severity__in=(
                                         'Critical', 'High', 'Medium', 'Low'),
                                     prod_type__in=prod_type).annotate(
        critical=Sum(
            Case(When(engagement__test__finding__severity='Critical', then=Value(1)),
                 output_field=IntegerField())
        ),
        high=Sum(
            Case(When(engagement__test__finding__severity='High', then=Value(1)),
                 output_field=IntegerField())
        ),
        medium=Sum(
            Case(When(engagement__test__finding__severity='Medium', then=Value(1)),
                 output_field=IntegerField())
        ),
        low=Sum(
            Case(When(engagement__test__finding__severity='Low', then=Value(1)),
                 output_field=IntegerField())
        ),
        total=Sum(
            Case(When(engagement__test__finding__severity__in=(
                'Critical', 'High', 'Medium', 'Low'), then=Value(1)),
                output_field=IntegerField()))
    ).order_by('-critical', '-high', '-medium', '-low')[:10]

    age_detail = [0, 0, 0, 0]

    in_period_counts = {"Critical": 0, "High": 0, "Medium": 0,
                        "Low": 0, "Info": 0, "Total": 0}
    in_period_details = {}

    closed_in_period_counts = {"Critical": 0, "High": 0, "Medium": 0,
                               "Low": 0, "Info": 0, "Total": 0}
    closed_in_period_details = {}

    accepted_in_period_details = {}

    for finding in findings.qs:
        if 0 <= finding.age <= 30:
            age_detail[0] += 1
        elif 30 < finding.age <= 60:
            age_detail[1] += 1
        elif 60 < finding.age <= 90:
            age_detail[2] += 1
        elif finding.age > 90:
            age_detail[3] += 1

        in_period_counts[finding.severity] += 1
        in_period_counts['Total'] += 1

        if finding.test.engagement.product.name not in in_period_details:
            in_period_details[finding.test.engagement.product.name] = {
                'path': reverse('view_product_findings', args=(finding.test.engagement.product.id,)),
                'Critical': 0, 'High': 0, 'Medium': 0, 'Low': 0, 'Info': 0, 'Total': 0}
        in_period_details[
            finding.test.engagement.product.name
        ][finding.severity] += 1
        in_period_details[finding.test.engagement.product.name]['Total'] += 1

    for finding in accepted_findings:
        if finding.test.engagement.product.name not in accepted_in_period_details:
            accepted_in_period_details[finding.test.engagement.product.name] = {
                'path': reverse('accepted_findings') + '?test__engagement__product=' + str(
                    finding.test.engagement.product.id),
                'Critical': 0, 'High': 0, 'Medium': 0, 'Low': 0, 'Info': 0, 'Total': 0}
        accepted_in_period_details[
            finding.test.engagement.product.name
        ][finding.severity] += 1
        accepted_in_period_details[finding.test.engagement.product.name]['Total'] += 1

    for f in findings_closed:
        closed_in_period_counts[f.severity] += 1
        closed_in_period_counts['Total'] += 1

        if f.test.engagement.product.name not in closed_in_period_details:
            closed_in_period_details[f.test.engagement.product.name] = {
                'path': reverse('closed_findings') + '?test__engagement__product=' + str(
                    f.test.engagement.product.id),
                'Critical': 0, 'High': 0, 'Medium': 0, 'Low': 0, 'Info': 0, 'Total': 0}
        closed_in_period_details[
            f.test.engagement.product.name
        ][f.severity] += 1
        closed_in_period_details[f.test.engagement.product.name]['Total'] += 1

    punchcard = list()
    ticks = list()
    highest_count = 0

    if 'view' in request.GET and 'dashboard' == request.GET['view']:
        punchcard, ticks, highest_count = get_punchcard_data(findings.qs, weeks_between, start_date)
        page_name = (get_system_setting('team_name')) + " Metrics"
        template = 'dojo/dashboard-metrics.html'

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

    return render(request, template, {
        'name': page_name,
        'start_date': start_date,
        'end_date': end_date,
        'findings': findings,
        'opened_per_month': monthly_counts['opened_per_period'],
        'active_per_month': monthly_counts['active_per_period'],
        'opened_per_week': weekly_counts['opened_per_period'],
        'accepted_per_month': monthly_counts['accepted_per_period'],
        'accepted_per_week': weekly_counts['accepted_per_period'],
        'top_ten_products': top_ten,
        'age_detail': age_detail,
        'in_period_counts': in_period_counts,
        'in_period_details': in_period_details,
        'accepted_in_period_counts': accepted_findings_counts,
        'accepted_in_period_details': accepted_in_period_details,
        'closed_in_period_counts': closed_in_period_counts,
        'closed_in_period_details': closed_in_period_details,
        'punchcard': punchcard,
        'ticks': ticks,
        'highest_count': highest_count,
        'show_pt_filter': show_pt_filter,
    })
Example #9
0
def metrics(request, mtype):
    template = 'dojo/metrics.html'
    page_name = 'Product Type Metrics'
    show_pt_filter = True

    sql_age_query = ""
    if "postgresql" in settings.DATABASES["default"]["ENGINE"]:
        sql_age_query = """SELECT (CASE WHEN (dojo_finding.mitigated IS NULL)
                        THEN DATE_PART(\'day\', date::timestamp - dojo_finding.date::timestamp)
                        ELSE DATE_PART(\'day\', dojo_finding.mitigated::timestamp - dojo_finding.date::timestamp) END)"""
    else:
        sql_age_query = """SELECT IF(dojo_finding.mitigated IS NULL, DATEDIFF(CURDATE(), dojo_finding.date),
                       DATEDIFF(dojo_finding.mitigated, dojo_finding.date))"""

    findings = Finding.objects.filter(
        verified=True,
        severity__in=('Critical', 'High', 'Medium', 'Low', 'Info')
    ).prefetch_related(
        'test__engagement__product', 'test__engagement__product__prod_type',
        'test__engagement__risk_acceptance', 'risk_acceptance_set', 'reporter'
    ).extra(select={
        'ra_count':
        'SELECT COUNT(*) FROM dojo_risk_acceptance INNER JOIN '
        'dojo_risk_acceptance_accepted_findings ON '
        '( dojo_risk_acceptance.id = dojo_risk_acceptance_accepted_findings.risk_acceptance_id ) '
        'WHERE dojo_risk_acceptance_accepted_findings.finding_id = dojo_finding.id',
        "sql_age":
        sql_age_query
    }, )
    active_findings = Finding.objects.filter(
        verified=True,
        active=True,
        severity__in=('Critical', 'High', 'Medium', 'Low', 'Info')
    ).prefetch_related(
        'test__engagement__product', 'test__engagement__product__prod_type',
        'test__engagement__risk_acceptance', 'risk_acceptance_set', 'reporter'
    ).extra(select={
        'ra_count':
        'SELECT COUNT(*) FROM dojo_risk_acceptance INNER JOIN '
        'dojo_risk_acceptance_accepted_findings ON '
        '( dojo_risk_acceptance.id = dojo_risk_acceptance_accepted_findings.risk_acceptance_id ) '
        'WHERE dojo_risk_acceptance_accepted_findings.finding_id = dojo_finding.id',
        "sql_age":
        sql_age_query
    }, )

    if mtype != 'All':
        pt = Product_Type.objects.filter(id=mtype)
        request.GET._mutable = True
        request.GET.appendlist('test__engagement__product__prod_type', mtype)
        request.GET._mutable = False
        mtype = pt[0].name
        show_pt_filter = False
        page_name = '%s Metrics' % mtype
        prod_type = pt
    elif 'test__engagement__product__prod_type' in request.GET:
        prod_type = Product_Type.objects.filter(id__in=request.GET.getlist(
            'test__engagement__product__prod_type', []))
    else:
        prod_type = Product_Type.objects.all()
    findings = MetricsFindingFilter(request.GET, queryset=findings)
    active_findings = MetricsFindingFilter(request.GET,
                                           queryset=active_findings)

    findings.qs  # this is needed to load details from filter since it is lazy
    active_findings.qs  # this is needed to load details from filter since it is lazy

    start_date = findings.filters['date'].start_date
    start_date = datetime(start_date.year,
                          start_date.month,
                          start_date.day,
                          tzinfo=timezone.get_current_timezone())
    end_date = findings.filters['date'].end_date
    end_date = datetime(end_date.year,
                        end_date.month,
                        end_date.day,
                        tzinfo=timezone.get_current_timezone())

    if len(prod_type) > 0:
        findings_closed = Finding.objects.filter(
            mitigated__range=[start_date, end_date],
            test__engagement__product__prod_type__in=prod_type
        ).prefetch_related('test__engagement__product')
        # capture the accepted findings in period
        accepted_findings = Finding.objects.filter(risk_acceptance__created__range=[start_date, end_date],
                                                   test__engagement__product__prod_type__in=prod_type). \
            prefetch_related('test__engagement__product')
        accepted_findings_counts = Finding.objects.filter(risk_acceptance__created__range=[start_date, end_date],
                                                          test__engagement__product__prod_type__in=prod_type). \
            prefetch_related('test__engagement__product').aggregate(
            total=Sum(
                Case(When(severity__in=('Critical', 'High', 'Medium', 'Low'),
                          then=Value(1)),
                     output_field=IntegerField())),
            critical=Sum(
                Case(When(severity='Critical',
                          then=Value(1)),
                     output_field=IntegerField())),
            high=Sum(
                Case(When(severity='High',
                          then=Value(1)),
                     output_field=IntegerField())),
            medium=Sum(
                Case(When(severity='Medium',
                          then=Value(1)),
                     output_field=IntegerField())),
            low=Sum(
                Case(When(severity='Low',
                          then=Value(1)),
                     output_field=IntegerField())),
            info=Sum(
                Case(When(severity='Info',
                          then=Value(1)),
                     output_field=IntegerField())),
        )
    else:
        findings_closed = Finding.objects.filter(
            mitigated__range=[start_date, end_date]).prefetch_related(
                'test__engagement__product')
        accepted_findings = Finding.objects.filter(risk_acceptance__created__range=[start_date, end_date]). \
            prefetch_related('test__engagement__product')
        accepted_findings_counts = Finding.objects.filter(risk_acceptance__created__range=[start_date, end_date]). \
            prefetch_related('test__engagement__product').aggregate(
            total=Sum(
                Case(When(severity__in=('Critical', 'High', 'Medium', 'Low'),
                          then=Value(1)),
                     output_field=IntegerField())),
            critical=Sum(
                Case(When(severity='Critical',
                          then=Value(1)),
                     output_field=IntegerField())),
            high=Sum(
                Case(When(severity='High',
                          then=Value(1)),
                     output_field=IntegerField())),
            medium=Sum(
                Case(When(severity='Medium',
                          then=Value(1)),
                     output_field=IntegerField())),
            low=Sum(
                Case(When(severity='Low',
                          then=Value(1)),
                     output_field=IntegerField())),
            info=Sum(
                Case(When(severity='Info',
                          then=Value(1)),
                     output_field=IntegerField())),
        )

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

    weeks_between = int(
        ceil((((r.years * 12) + r.months) * 4.33) + (r.days / 7)))
    if weeks_between <= 0:
        weeks_between += 2

    monthly_counts = get_period_counts(active_findings.qs,
                                       findings.qs,
                                       findings_closed,
                                       accepted_findings,
                                       months_between,
                                       start_date,
                                       relative_delta='months')
    weekly_counts = get_period_counts(active_findings.qs,
                                      findings.qs,
                                      findings_closed,
                                      accepted_findings,
                                      weeks_between,
                                      start_date,
                                      relative_delta='weeks')

    top_ten = Product.objects.filter(
        engagement__test__finding__verified=True,
        engagement__test__finding__false_p=False,
        engagement__test__finding__duplicate=False,
        engagement__test__finding__out_of_scope=False,
        engagement__test__finding__mitigated__isnull=True,
        engagement__test__finding__severity__in=('Critical', 'High', 'Medium',
                                                 'Low'),
        prod_type__in=prod_type).annotate(
            critical=Sum(
                Case(When(engagement__test__finding__severity='Critical',
                          then=Value(1)),
                     output_field=IntegerField())),
            high=Sum(
                Case(When(engagement__test__finding__severity='High',
                          then=Value(1)),
                     output_field=IntegerField())),
            medium=Sum(
                Case(When(engagement__test__finding__severity='Medium',
                          then=Value(1)),
                     output_field=IntegerField())),
            low=Sum(
                Case(When(engagement__test__finding__severity='Low',
                          then=Value(1)),
                     output_field=IntegerField())),
            total=Sum(
                Case(When(engagement__test__finding__severity__in=('Critical',
                                                                   'High',
                                                                   'Medium',
                                                                   'Low'),
                          then=Value(1)),
                     output_field=IntegerField()))).order_by(
                         '-critical', '-high', '-medium', '-low')[:10]

    age_detail = [0, 0, 0, 0]

    in_period_counts = {
        "Critical": 0,
        "High": 0,
        "Medium": 0,
        "Low": 0,
        "Info": 0,
        "Total": 0
    }
    in_period_details = {}

    closed_in_period_counts = {
        "Critical": 0,
        "High": 0,
        "Medium": 0,
        "Low": 0,
        "Info": 0,
        "Total": 0
    }
    closed_in_period_details = {}

    accepted_in_period_details = {}

    for finding in findings.qs:
        if 0 <= finding.sql_age <= 30:
            age_detail[0] += 1
        elif 30 < finding.sql_age <= 60:
            age_detail[1] += 1
        elif 60 < finding.sql_age <= 90:
            age_detail[2] += 1
        elif finding.sql_age > 90:
            age_detail[3] += 1

        in_period_counts[finding.severity] += 1
        in_period_counts['Total'] += 1

        if finding.test.engagement.product.name not in in_period_details:
            in_period_details[finding.test.engagement.product.name] = {
                'path':
                reverse('view_product_findings',
                        args=(finding.test.engagement.product.id, )),
                'Critical':
                0,
                'High':
                0,
                'Medium':
                0,
                'Low':
                0,
                'Info':
                0,
                'Total':
                0
            }
        in_period_details[finding.test.engagement.product.name][
            finding.severity] += 1
        in_period_details[finding.test.engagement.product.name]['Total'] += 1

    for finding in accepted_findings:
        if finding.test.engagement.product.name not in accepted_in_period_details:
            accepted_in_period_details[
                finding.test.engagement.product.name] = {
                    'path':
                    reverse('accepted_findings') +
                    '?test__engagement__product=' +
                    str(finding.test.engagement.product.id),
                    'Critical':
                    0,
                    'High':
                    0,
                    'Medium':
                    0,
                    'Low':
                    0,
                    'Info':
                    0,
                    'Total':
                    0
                }
        accepted_in_period_details[finding.test.engagement.product.name][
            finding.severity] += 1
        accepted_in_period_details[
            finding.test.engagement.product.name]['Total'] += 1

    for f in findings_closed:
        closed_in_period_counts[f.severity] += 1
        closed_in_period_counts['Total'] += 1

        if f.test.engagement.product.name not in closed_in_period_details:
            closed_in_period_details[f.test.engagement.product.name] = {
                'path':
                reverse('closed_findings') + '?test__engagement__product=' +
                str(f.test.engagement.product.id),
                'Critical':
                0,
                'High':
                0,
                'Medium':
                0,
                'Low':
                0,
                'Info':
                0,
                'Total':
                0
            }
        closed_in_period_details[f.test.engagement.product.name][
            f.severity] += 1
        closed_in_period_details[f.test.engagement.product.name]['Total'] += 1

    punchcard = list()
    ticks = list()
    highest_count = 0

    if 'view' in request.GET and 'dashboard' == request.GET['view']:
        punchcard, ticks, highest_count = get_punchcard_data(
            findings.qs, weeks_between, start_date)
        page_name = (get_system_setting('team_name')) + " Metrics"
        template = 'dojo/dashboard-metrics.html'

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

    return render(
        request, template, {
            'name': page_name,
            'start_date': start_date,
            'end_date': end_date,
            'findings': findings,
            'opened_per_month': monthly_counts['opened_per_period'],
            'active_per_month': monthly_counts['active_per_period'],
            'opened_per_week': weekly_counts['opened_per_period'],
            'accepted_per_month': monthly_counts['accepted_per_period'],
            'accepted_per_week': weekly_counts['accepted_per_period'],
            'top_ten_products': top_ten,
            'age_detail': age_detail,
            'in_period_counts': in_period_counts,
            'in_period_details': in_period_details,
            'accepted_in_period_counts': accepted_findings_counts,
            'accepted_in_period_details': accepted_in_period_details,
            'closed_in_period_counts': closed_in_period_counts,
            'closed_in_period_details': closed_in_period_details,
            'punchcard': punchcard,
            'ticks': ticks,
            'highest_count': highest_count,
            'show_pt_filter': show_pt_filter,
        })
Example #10
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
    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(), (datetime.now(tz=localtz).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_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 = localtz.localize(datetime.combine(findings.qs.last().date, datetime.min.time()))
        else:
            start_date = localtz.localize(datetime.today())
        end_date = localtz.localize(datetime.today())

        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(findings.qs, findings.qs, 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,
                   'findings': findings.qs,
                   'include_finding_notes': include_finding_notes,
                   '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': request.scheme + "://" + request.META['HTTP_HOST']}

    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)
        engagements = Engagement.objects.filter(test__finding__id__in=ids).distinct()
        tests = Test.objects.filter(finding__id__in=ids).distinct()

        context = {'product': product,
                   'engagements': engagements,
                   'tests': tests,
                   'report_name': report_name,
                   'findings': findings.qs,
                   'include_finding_notes': include_finding_notes,
                   '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': request.scheme + "://" + request.META['HTTP_HOST']}

    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)
        tests = Test.objects.filter(finding__id__in=ids).distinct()

        context = {'engagement': engagement,
                   'tests': tests,
                   'report_name': report_name,
                   'findings': findings.qs,
                   'include_finding_notes': include_finding_notes,
                   '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': request.scheme + "://" + request.META['HTTP_HOST']}

    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,
                   'include_finding_notes': include_finding_notes,
                   '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': request.scheme + "://" + request.META['HTTP_HOST']}

    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,
                   'include_finding_notes': include_finding_notes,
                   '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': request.scheme + "://" + request.META['HTTP_HOST']}
    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,
                   'report_name': report_name,
                   'include_finding_notes': include_finding_notes,
                   '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': request.scheme + "://" + request.META['HTTP_HOST']}
    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,
                           'include_finding_notes': include_finding_notes,
                           'include_executive_summary': include_executive_summary,
                           'include_table_of_contents': include_table_of_contents,
                           'user': user,
                           'team_name': settings.TEAM_NAME,
                           'title': 'Generate Report',
                           })

        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 = datetime.now(tz=localtz)
                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, you will receive an email when it is ready.',
                                 extra_tags='alert-success')

            return HttpResponseRedirect(reverse('reports'))
        else:
            raise Http404()
    paged_findings = get_page_items(request, findings, 25)
    return render(request, 'dojo/request_report.html',
                  {'product_type': product_type,
                   'product': product,
                   'engagement': engagement,
                   'test': test,
                   'endpoint': endpoint,
                   'findings': findings,
                   'paged_findings': paged_findings,
                   'report_form': report_form,
                   })
Example #11
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
    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(), (datetime.now(tz=localtz).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_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 = localtz.localize(datetime.combine(findings.qs.last().date, datetime.min.time()))
        else:
            start_date = localtz.localize(datetime.today())
        end_date = localtz.localize(datetime.today())

        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(findings.qs, findings.qs, 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,
                   'findings': findings.qs,
                   'include_finding_notes': include_finding_notes,
                   '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': request.scheme + "://" + request.META['HTTP_HOST']}

    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)
        engagements = Engagement.objects.filter(test__finding__id__in=ids).distinct()
        tests = Test.objects.filter(finding__id__in=ids).distinct()

        context = {'product': product,
                   'engagements': engagements,
                   'tests': tests,
                   'report_name': report_name,
                   'findings': findings.qs,
                   'include_finding_notes': include_finding_notes,
                   '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': request.scheme + "://" + request.META['HTTP_HOST']}

    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)
        tests = Test.objects.filter(finding__id__in=ids).distinct()

        context = {'engagement': engagement,
                   'tests': tests,
                   'report_name': report_name,
                   'findings': findings.qs,
                   'include_finding_notes': include_finding_notes,
                   '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': request.scheme + "://" + request.META['HTTP_HOST']}

    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,
                   'include_finding_notes': include_finding_notes,
                   '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': request.scheme + "://" + request.META['HTTP_HOST']}

    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,
                   'include_finding_notes': include_finding_notes,
                   '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': request.scheme + "://" + request.META['HTTP_HOST']}
    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,
                   'report_name': report_name,
                   'include_finding_notes': include_finding_notes,
                   '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': request.scheme + "://" + request.META['HTTP_HOST']}
    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,
                           'include_finding_notes': include_finding_notes,
                           'include_executive_summary': include_executive_summary,
                           'include_table_of_contents': include_table_of_contents,
                           'user': user,
                           'team_name': settings.TEAM_NAME,
                           'title': 'Generate Report',
                           })

        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 = datetime.now(tz=localtz)
                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, you will receive an email when it is ready.',
                                 extra_tags='alert-success')

            return HttpResponseRedirect(reverse('reports'))
        else:
            raise Http404()
    paged_findings = get_page_items(request, findings, 25)
    return render(request, 'dojo/request_report.html',
                  {'product_type': product_type,
                   'product': product,
                   'engagement': engagement,
                   'test': test,
                   'endpoint': endpoint,
                   'findings': findings,
                   'paged_findings': paged_findings,
                   'report_form': report_form,
                   })
Example #12
0
def endpoint_querys(prod_type, request):
    filters = dict()

    endpoints_query = Endpoint_Status.objects.filter(
        mitigated=False,
        finding__severity__in=(
            'Critical', 'High', 'Medium', 'Low', 'Info')).prefetch_related(
                'finding__test__engagement__product',
                'finding__test__engagement__product__prod_type',
                'finding__test__engagement__risk_acceptance',
                'finding__risk_acceptance_set', 'finding__reporter')

    active_endpoints_query = Endpoint_Status.objects.filter(
        mitigated=False,
        finding__severity__in=(
            'Critical', 'High', 'Medium', 'Low', 'Info')).prefetch_related(
                'finding__test__engagement__product',
                'finding__test__engagement__product__prod_type',
                'finding__test__engagement__risk_acceptance',
                'finding__risk_acceptance_set', 'finding__reporter')

    endpoints = MetricsEndpointFilter(request.GET, queryset=endpoints_query)
    active_endpoints = MetricsEndpointFilter(request.GET,
                                             queryset=active_endpoints_query)

    endpoints_qs = queryset_check(endpoints)
    active_endpoints_qs = queryset_check(active_endpoints)

    if not endpoints_qs:
        endpoints = endpoints_query
        active_endpoints = active_endpoints_query
        endpoints_qs = endpoints if isinstance(endpoints,
                                               QuerySet) else endpoints.qs
        active_endpoints_qs = active_endpoints if isinstance(
            active_endpoints, QuerySet) else active_endpoints.qs
        messages.add_message(
            request,
            messages.ERROR,
            'All objects have been filtered away. Displaying all objects',
            extra_tags='alert-danger')

    start_date = endpoints_qs.earliest('date').date
    start_date = datetime(start_date.year,
                          start_date.month,
                          start_date.day,
                          tzinfo=timezone.get_current_timezone())
    end_date = endpoints_qs.latest('date').date
    end_date = datetime(end_date.year,
                        end_date.month,
                        end_date.day,
                        tzinfo=timezone.get_current_timezone())

    if len(prod_type) > 0:
        endpoints_closed = Endpoint_Status.objects.filter(
            mitigated_time__range=[start_date, end_date],
            finding__test__engagement__product__prod_type__in=prod_type
        ).prefetch_related('finding__test__engagement__product')
        # capture the accepted findings in period
        accepted_endpoints = Endpoint_Status.objects.filter(date__range=[start_date, end_date], risk_accepted=True,
                                                   finding__test__engagement__product__prod_type__in=prod_type). \
            prefetch_related('finding__test__engagement__product')
        accepted_endpoints_counts = Endpoint_Status.objects.filter(date__range=[start_date, end_date], risk_accepted=True,
                                                          finding__test__engagement__product__prod_type__in=prod_type). \
            prefetch_related('finding__test__engagement__product')
        accepted_endpoints_counts = severity_count(accepted_endpoints_counts,
                                                   'aggregate',
                                                   'finding__severity')
    else:
        endpoints_closed = Endpoint_Status.objects.filter(
            mitigated__date__range=[start_date, end_date]).prefetch_related(
                'finding__test__engagement__product')
        accepted_endpoints = Endpoint_Status.objects.filter(date__range=[start_date, end_date], risk_accepted=True). \
            prefetch_related('finding__test__engagement__product')
        accepted_endpoints_counts = Endpoint_Status.objects.filter(date__range=[start_date, end_date], risk_accepted=True). \
            prefetch_related('finding__test__engagement__product')
        accepted_endpoints_counts = severity_count(accepted_endpoints_counts,
                                                   'aggregate',
                                                   'finding__severity')

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

    weeks_between = int(
        ceil((((r.years * 12) + r.months) * 4.33) + (r.days / 7)))
    if weeks_between <= 0:
        weeks_between += 2

    monthly_counts = get_period_counts(active_endpoints_qs,
                                       endpoints_qs,
                                       endpoints_closed,
                                       accepted_endpoints,
                                       months_between,
                                       start_date,
                                       relative_delta='months')
    weekly_counts = get_period_counts(active_endpoints_qs,
                                      endpoints_qs,
                                      endpoints_closed,
                                      accepted_endpoints,
                                      weeks_between,
                                      start_date,
                                      relative_delta='weeks')

    top_ten = Product.objects.filter(
        engagement__test__finding__endpoint_status__mitigated=False,
        engagement__test__finding__endpoint_status__false_positive=False,
        engagement__test__finding__endpoint_status__out_of_scope=False,
        engagement__test__finding__severity__in=('Critical', 'High', 'Medium',
                                                 'Low'),
        prod_type__in=prod_type)
    top_ten = severity_count(top_ten, 'annotate',
                             'engagement__test__finding__severity').order_by(
                                 '-critical', '-high', '-medium', '-low')[:10]

    filters['all'] = endpoints
    filters['closed'] = endpoints_closed
    filters['accepted'] = accepted_endpoints
    filters['accepted_count'] = accepted_endpoints_counts
    filters['top_ten'] = top_ten
    filters['monthly_counts'] = monthly_counts
    filters['weekly_counts'] = weekly_counts
    filters['weeks_between'] = weeks_between
    filters['start_date'] = start_date
    filters['end_date'] = end_date

    return filters
Example #13
0
def finding_querys(prod_type, request):
    filters = dict()

    findings_query = Finding.objects.filter(
        verified=True,
        severity__in=('Critical', 'High', 'Medium', 'Low', 'Info')
    ).prefetch_related(
        'test__engagement__product', 'test__engagement__product__prod_type',
        'test__engagement__risk_acceptance', 'risk_acceptance_set', 'reporter'
    ).extra(select={
        'ra_count':
        'SELECT COUNT(*) FROM dojo_risk_acceptance INNER JOIN '
        'dojo_risk_acceptance_accepted_findings ON '
        '( dojo_risk_acceptance.id = dojo_risk_acceptance_accepted_findings.risk_acceptance_id ) '
        'WHERE dojo_risk_acceptance_accepted_findings.finding_id = dojo_finding.id',
    }, )
    active_findings_query = Finding.objects.filter(
        verified=True,
        active=True,
        severity__in=('Critical', 'High', 'Medium', 'Low', 'Info')
    ).prefetch_related(
        'test__engagement__product', 'test__engagement__product__prod_type',
        'test__engagement__risk_acceptance', 'risk_acceptance_set', 'reporter'
    ).extra(select={
        'ra_count':
        'SELECT COUNT(*) FROM dojo_risk_acceptance INNER JOIN '
        'dojo_risk_acceptance_accepted_findings ON '
        '( dojo_risk_acceptance.id = dojo_risk_acceptance_accepted_findings.risk_acceptance_id ) '
        'WHERE dojo_risk_acceptance_accepted_findings.finding_id = dojo_finding.id',
    }, )

    findings = MetricsFindingFilter(request.GET, queryset=findings_query)
    active_findings = MetricsFindingFilter(request.GET,
                                           queryset=active_findings_query)

    findings_qs = queryset_check(findings)
    active_findings_qs = queryset_check(active_findings)

    if not findings_qs:
        findings = findings_query
        active_findings = active_findings_query
        findings_qs = findings if isinstance(findings,
                                             QuerySet) else findings.qs
        active_findings_qs = active_findings if isinstance(
            active_findings, QuerySet) else active_findings.qs
        messages.add_message(
            request,
            messages.ERROR,
            'All objects have been filtered away. Displaying all objects',
            extra_tags='alert-danger')

    start_date = findings_qs.earliest('date').date
    start_date = datetime(start_date.year,
                          start_date.month,
                          start_date.day,
                          tzinfo=timezone.get_current_timezone())
    end_date = findings_qs.latest('date').date
    end_date = datetime(end_date.year,
                        end_date.month,
                        end_date.day,
                        tzinfo=timezone.get_current_timezone())

    if len(prod_type) > 0:
        findings_closed = Finding.objects.filter(
            mitigated__date__range=[start_date, end_date],
            test__engagement__product__prod_type__in=prod_type
        ).prefetch_related('test__engagement__product')
        # capture the accepted findings in period
        accepted_findings = Finding.objects.filter(risk_acceptance__created__date__range=[start_date, end_date],
                                                   test__engagement__product__prod_type__in=prod_type). \
            prefetch_related('test__engagement__product')
        accepted_findings_counts = Finding.objects.filter(risk_acceptance__created__date__range=[start_date, end_date],
                                                          test__engagement__product__prod_type__in=prod_type). \
            prefetch_related('test__engagement__product')
        accepted_findings_counts = severity_count(accepted_findings_counts,
                                                  'aggregate', 'severity')
    else:
        findings_closed = Finding.objects.filter(
            mitigated__date__range=[start_date, end_date]).prefetch_related(
                'test__engagement__product')
        accepted_findings = Finding.objects.filter(risk_acceptance__created__date__range=[start_date, end_date]). \
            prefetch_related('test__engagement__product')
        accepted_findings_counts = Finding.objects.filter(risk_acceptance__created__date__range=[start_date, end_date]). \
            prefetch_related('test__engagement__product')
        accepted_findings_counts = severity_count(accepted_findings_counts,
                                                  'aggregate', 'severity')

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

    weeks_between = int(
        ceil((((r.years * 12) + r.months) * 4.33) + (r.days / 7)))
    if weeks_between <= 0:
        weeks_between += 2

    monthly_counts = get_period_counts(active_findings_qs,
                                       findings_qs,
                                       findings_closed,
                                       accepted_findings,
                                       months_between,
                                       start_date,
                                       relative_delta='months')
    weekly_counts = get_period_counts(active_findings_qs,
                                      findings_qs,
                                      findings_closed,
                                      accepted_findings,
                                      weeks_between,
                                      start_date,
                                      relative_delta='weeks')

    top_ten = Product.objects.filter(
        engagement__test__finding__verified=True,
        engagement__test__finding__false_p=False,
        engagement__test__finding__duplicate=False,
        engagement__test__finding__out_of_scope=False,
        engagement__test__finding__mitigated__isnull=True,
        engagement__test__finding__severity__in=('Critical', 'High', 'Medium',
                                                 'Low'),
        prod_type__in=prod_type)
    top_ten = severity_count(top_ten, 'annotate',
                             'engagement__test__finding__severity').order_by(
                                 '-critical', '-high', '-medium', '-low')[:10]

    filters['all'] = findings
    filters['closed'] = findings_closed
    filters['accepted'] = accepted_findings
    filters['accepted_count'] = accepted_findings_counts
    filters['top_ten'] = top_ten
    filters['monthly_counts'] = monthly_counts
    filters['weekly_counts'] = weekly_counts
    filters['weeks_between'] = weeks_between
    filters['start_date'] = start_date
    filters['end_date'] = end_date

    return filters
Example #14
0
def finding_querys(prod_type, request):
    findings_query = Finding.objects.filter(
        verified=True,
        severity__in=('Critical', 'High', 'Medium', 'Low', 'Info')
    ).select_related(
        'reporter',
        'test',
        'test__engagement__product',
        'test__engagement__product__prod_type',
    ).prefetch_related(
        'risk_acceptance_set',
        'test__engagement__risk_acceptance',
        'test__test_type',
    )

    findings_query = get_authorized_findings(Permissions.Finding_View, findings_query, request.user)

    active_findings_query = Finding.objects.filter(
        verified=True,
        active=True,
        severity__in=('Critical', 'High', 'Medium', 'Low', 'Info')
    ).select_related(
        'reporter',
        'test',
        'test__engagement__product',
        'test__engagement__product__prod_type',
    ).prefetch_related(
        'risk_acceptance_set',
        'test__engagement__risk_acceptance',
        'test__test_type',
    )

    active_findings_query = get_authorized_findings(Permissions.Finding_View, active_findings_query, request.user)

    findings = MetricsFindingFilter(request.GET, queryset=findings_query)
    active_findings = MetricsFindingFilter(request.GET, queryset=active_findings_query)

    findings_qs = queryset_check(findings)
    active_findings_qs = queryset_check(active_findings)

    if not findings_qs and not findings_query:
        findings = findings_query
        active_findings = active_findings_query
        findings_qs = findings if isinstance(findings, QuerySet) else findings.qs
        active_findings_qs = active_findings if isinstance(active_findings, QuerySet) else active_findings.qs
        messages.add_message(request,
                                     messages.ERROR,
                                     'All objects have been filtered away. Displaying all objects',
                                     extra_tags='alert-danger')

    try:
        start_date = findings_qs.earliest('date').date
        start_date = datetime(start_date.year,
                            start_date.month, start_date.day,
                            tzinfo=timezone.get_current_timezone())
        end_date = findings_qs.latest('date').date
        end_date = datetime(end_date.year,
                            end_date.month, end_date.day,
                            tzinfo=timezone.get_current_timezone())
    except:
        start_date = timezone.now()
        end_date = timezone.now()

    if len(prod_type) > 0:
        findings_closed = Finding.objects.filter(mitigated__date__range=[start_date, end_date],
                                                 test__engagement__product__prod_type__in=prod_type).prefetch_related(
            'test__engagement__product')
        # capture the accepted findings in period
        accepted_findings = Finding.objects.filter(risk_accepted=True, date__range=[start_date, end_date],
                                                   test__engagement__product__prod_type__in=prod_type). \
            prefetch_related('test__engagement__product')
        accepted_findings_counts = Finding.objects.filter(risk_accepted=True, date__range=[start_date, end_date],
                                                          test__engagement__product__prod_type__in=prod_type). \
            prefetch_related('test__engagement__product')
    else:
        findings_closed = Finding.objects.filter(mitigated__date__range=[start_date, end_date]).prefetch_related(
            'test__engagement__product')
        accepted_findings = Finding.objects.filter(risk_accepted=True, date__range=[start_date, end_date]). \
            prefetch_related('test__engagement__product')
        accepted_findings_counts = Finding.objects.filter(risk_accepted=True, date__range=[start_date, end_date]). \
            prefetch_related('test__engagement__product')

    findings_closed = get_authorized_findings(Permissions.Finding_View, findings_closed, request.user)
    accepted_findings = get_authorized_findings(Permissions.Finding_View, accepted_findings, request.user)
    accepted_findings_counts = get_authorized_findings(Permissions.Finding_View, accepted_findings_counts, request.user)
    accepted_findings_counts = severity_count(accepted_findings_counts, 'aggregate', 'severity')

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

    weeks_between = int(ceil((((r.years * 12) + r.months) * 4.33) + (r.days / 7)))
    if weeks_between <= 0:
        weeks_between += 2

    monthly_counts = get_period_counts(active_findings_qs, findings_qs, findings_closed, accepted_findings, months_between, start_date,
                                       relative_delta='months')
    weekly_counts = get_period_counts(active_findings_qs, findings_qs, findings_closed, accepted_findings, weeks_between, start_date,
                                      relative_delta='weeks')

    top_ten = get_authorized_products(Permissions.Product_View)
    top_ten = top_ten.filter(engagement__test__finding__verified=True,
                                     engagement__test__finding__false_p=False,
                                     engagement__test__finding__duplicate=False,
                                     engagement__test__finding__out_of_scope=False,
                                     engagement__test__finding__mitigated__isnull=True,
                                     engagement__test__finding__severity__in=(
                                         'Critical', 'High', 'Medium', 'Low'),
                                     prod_type__in=prod_type)
    top_ten = severity_count(top_ten, 'annotate', 'engagement__test__finding__severity').order_by('-critical', '-high', '-medium', '-low')[:10]

    return {
        'all': findings,
        'closed': findings_closed,
        'accepted': accepted_findings,
        'accepted_count': accepted_findings_counts,
        'top_ten': top_ten,
        'monthly_counts': monthly_counts,
        'weekly_counts': weekly_counts,
        'weeks_between': weeks_between,
        'start_date': start_date,
        'end_date': end_date,
    }