예제 #1
0
def metrics(request, mtype):
    template = 'dojo/metrics.html'
    show_pt_filter = True
    view = identify_view(request)
    page_name = 'Product Type Metrics by '

    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 = {}

    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()

    filters = dict()
    if view == 'Finding':
        page_name += 'Findings'
        filters = finding_querys(prod_type, request)
    elif view == 'Endpoint':
        page_name += 'Affected Endpoints'
        filters = endpoint_querys(prod_type, request)

    for obj in queryset_check(filters['all']):
        if view == 'Endpoint':
            obj = obj.finding

        if 0 <= obj.age <= 30:
            age_detail[0] += 1
        elif 30 < obj.age <= 60:
            age_detail[1] += 1
        elif 60 < obj.age <= 90:
            age_detail[2] += 1
        elif obj.age > 90:
            age_detail[3] += 1

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

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

    for obj in filters['accepted']:
        if view == 'Endpoint':
            obj = finding.finding

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

    for obj in filters['closed']:
        if view == 'Endpoint':
            obj = obj.finding
        closed_in_period_counts[obj.severity] += 1
        closed_in_period_counts['Total'] += 1

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

    punchcard = list()
    ticks = list()
    monthly_counts = filters['monthly_counts']
    weekly_counts = filters['weekly_counts']

    if 'view' in request.GET and 'dashboard' == request.GET['view']:
        punchcard, ticks = get_punchcard_data(queryset_check(filters['all']),
                                              filters['start_date'],
                                              filters['weeks_between'], view)
        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': filters['start_date'],
            'end_date': filters['end_date'],
            'findings': filters['all'],
            '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': filters['top_ten'],
            'age_detail': age_detail,
            'in_period_counts': in_period_counts,
            'in_period_details': in_period_details,
            'accepted_in_period_counts': filters['accepted_count'],
            '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,
            'show_pt_filter': show_pt_filter,
        })
예제 #2
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
예제 #3
0
def metrics(request, mtype):
    template = 'dojo/metrics.html'
    show_pt_filter = True
    view = identify_view(request)
    page_name = 'Product Type Metrics by '

    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 = get_authorized_product_types(Permissions.Product_Type_View)
    # legacy code calls has 'prod_type' as 'related_name' for product.... so weird looking prefetch
    prod_type = prod_type.prefetch_related('prod_type', 'prod_type__authorized_users', 'authorized_users')

    filters = dict()
    if view == 'Finding':
        page_name += 'Findings'
        filters = finding_querys(prod_type, request)
    elif view == 'Endpoint':
        page_name += 'Affected Endpoints'
        filters = endpoint_querys(prod_type, request)

    in_period_counts, in_period_details, age_detail = get_in_period_details([
        obj.finding if view == 'Endpoint' else obj
        for obj in queryset_check(filters['all'])
    ])

    accepted_in_period_details = get_accepted_in_period_details([
        obj.finding if view == 'Endpoint' else obj
        for obj in filters['accepted']
    ])

    closed_in_period_counts, closed_in_period_details = get_closed_in_period_details([
        obj.finding if view == 'Endpoint' else obj
        for obj in filters['closed']
    ])

    punchcard = list()
    ticks = list()

    if 'view' in request.GET and 'dashboard' == request.GET['view']:
        punchcard, ticks = get_punchcard_data(queryset_check(filters['all']), filters['start_date'], filters['weeks_between'], view)
        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': filters['start_date'],
        'end_date': filters['end_date'],
        'findings': filters['all'],
        'opened_per_month': filters['monthly_counts']['opened_per_period'],
        'active_per_month': filters['monthly_counts']['active_per_period'],
        'opened_per_week': filters['weekly_counts']['opened_per_period'],
        'accepted_per_month': filters['monthly_counts']['accepted_per_period'],
        'accepted_per_week': filters['weekly_counts']['accepted_per_period'],
        'top_ten_products': filters['top_ten'],
        'age_detail': age_detail,
        'in_period_counts': in_period_counts,
        'in_period_details': in_period_details,
        'accepted_in_period_counts': filters['accepted_count'],
        '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,
        'show_pt_filter': show_pt_filter,
    })
예제 #4
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
예제 #5
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,
    }