예제 #1
0
def engagement_calendar(request):
    if 'lead' not in request.GET or '0' in request.GET.getlist('lead'):
        engagements = get_authorized_engagements(Permissions.Engagement_View)
    else:
        filters = []
        leads = request.GET.getlist('lead', '')
        if '-1' in request.GET.getlist('lead'):
            leads.remove('-1')
            filters.append(Q(lead__isnull=True))
        filters.append(Q(lead__in=leads))
        engagements = get_authorized_engagements(
            Permissions.Engagement_View).filter(reduce(operator.or_, filters))

    engagements = engagements.select_related('lead')
    engagements = engagements.prefetch_related('product')

    add_breadcrumb(title="Engagement Calendar",
                   top_level=True,
                   request=request)
    return render(
        request, 'dojo/calendar.html', {
            'caltype': 'engagements',
            'leads': request.GET.getlist('lead', ''),
            'engagements': engagements,
            'users': Dojo_User.objects.all()
        })
예제 #2
0
def engagements(request, view):

    if not view:
        view = 'active'

    filtered_engagements = get_filtered_engagements(request, view)

    engs = get_page_items(request, filtered_engagements.qs, 25)
    product_name_words = sorted(get_authorized_products(Permissions.Product_View).values_list('name', flat=True))
    engagement_name_words = sorted(get_authorized_engagements(Permissions.Engagement_View).values_list('name', flat=True).distinct())

    add_breadcrumb(
        title=f"{view.capitalize()} Engagements",
        top_level=not len(request.GET),
        request=request)

    return render(
        request, 'dojo/engagement.html', {
            'engagements': engs,
            'engagement_test_counts': get_test_counts(filtered_engagements.qs),
            'filter_form': filtered_engagements.form,
            'product_name_words': product_name_words,
            'engagement_name_words': engagement_name_words,
            'view': view.capitalize(),
        })
예제 #3
0
def dashboard(request: HttpRequest) -> HttpResponse:
    engagements = get_authorized_engagements(Permissions.Engagement_View).distinct()
    findings = get_authorized_findings(Permissions.Finding_View).distinct()

    findings = findings.filter(duplicate=False)

    engagement_count = engagements.filter(active=True).count()

    today = timezone.now().date()

    date_range = [today - timedelta(days=6), today]  # 7 days (6 days plus today)
    finding_count = findings\
        .filter(created__date__range=date_range)\
        .count()
    mitigated_count = findings\
        .filter(mitigated__date__range=date_range)\
        .count()
    accepted_count = findings\
        .filter(risk_acceptance__created__date__range=date_range)\
        .count()

    severity_count_all = get_severities_all(findings)
    severity_count_by_month = get_severities_by_month(findings, today)
    punchcard, ticks = get_punchcard_data(findings, today - relativedelta(weeks=26), 26)

    if user_has_configuration_permission(request.user, 'dojo.view_engagement_survey', 'staff'):
        unassigned_surveys = Answered_Survey.objects.filter(assignee_id__isnull=True, completed__gt=0, ) \
            .filter(Q(engagement__isnull=True) | Q(engagement__in=engagements))
    else:
        unassigned_surveys = None

    if request.user.is_superuser and not settings.FEATURE_CONFIGURATION_AUTHORIZATION:
        message = '''Legacy authorization for changing configurations based on staff users will be
                     removed with version 2.12.0 / 5. July 2022. If you have set
                     `FEATURE_CONFIGURATION_AUTHORIZATION` to `False` in your local configuration,
                     remove this local setting and start using the new authorization.'''
        messages.add_message(request, messages.WARNING, message, extra_tags='alert-warning')

    add_breadcrumb(request=request, clear=True)
    return render(request, 'dojo/dashboard.html', {
        'engagement_count': engagement_count,
        'finding_count': finding_count,
        'mitigated_count': mitigated_count,
        'accepted_count': accepted_count,
        'critical': severity_count_all['Critical'],
        'high': severity_count_all['High'],
        'medium': severity_count_all['Medium'],
        'low': severity_count_all['Low'],
        'info': severity_count_all['Info'],
        'by_month': severity_count_by_month,
        'punchcard': punchcard,
        'ticks': ticks,
        'surveys': unassigned_surveys,
    })
예제 #4
0
def dashboard(request: HttpRequest) -> HttpResponse:
    engagements = get_authorized_engagements(
        Permissions.Engagement_View).distinct()
    if request.user.is_staff:
        findings = Finding.objects.all()
    else:
        findings = Finding.objects.filter(
            Q(test__engagement__product__authorized_users=request.user)
            | Q(test__engagement__product__prod_type__authorized_users=request.
                user)).distinct()

    findings = findings.filter(duplicate=False)

    engagement_count = engagements.filter(active=True).count()

    today = timezone.now().date()

    date_range = [today - timedelta(days=6),
                  today]  # 7 days (6 days plus today)
    finding_count = findings\
        .filter(created__date__range=date_range)\
        .count()
    mitigated_count = findings\
        .filter(mitigated__date__range=date_range)\
        .count()
    accepted_count = findings\
        .filter(risk_acceptance__created__date__range=date_range)\
        .count()

    severity_count_all = get_severities_all(findings)
    severity_count_by_month = get_severities_by_month(findings, today)
    punchcard, ticks = get_punchcard_data(findings,
                                          today - relativedelta(weeks=26), 26)

    unassigned_surveys = Answered_Survey.objects.filter(
        assignee_id__isnull=True, completed__gt=0)

    add_breadcrumb(request=request, clear=True)
    return render(
        request, 'dojo/dashboard.html', {
            'engagement_count': engagement_count,
            'finding_count': finding_count,
            'mitigated_count': mitigated_count,
            'accepted_count': accepted_count,
            'critical': severity_count_all['Critical'],
            'high': severity_count_all['High'],
            'medium': severity_count_all['Medium'],
            'low': severity_count_all['Low'],
            'info': severity_count_all['Info'],
            'by_month': severity_count_by_month,
            'punchcard': punchcard,
            'ticks': ticks,
            'surveys': unassigned_surveys,
        })
예제 #5
0
 def accept_risks(self, request):
     serializer = AcceptedRiskSerializer(data=request.data, many=True)
     if serializer.is_valid():
         accepted_risks = serializer.save()
     else:
         return Response(data=serializer.errors,
                         status=status.HTTP_400_BAD_REQUEST)
     owner = request.user
     accepted_result = []
     for engagement in get_authorized_engagements(
             Permissions.Engagement_View):
         base_findings = engagement.unaccepted_open_findings
         accepted = _accept_risks(accepted_risks, base_findings, owner)
         engagement.accept_risks(accepted)
         accepted_result.extend(accepted)
     result = RiskAcceptanceSerializer(instance=accepted_result, many=True)
     return Response(result.data)
예제 #6
0
def engagements_all(request):

    products_with_engagements = get_authorized_products(Permissions.Engagement_View)
    products_with_engagements = products_with_engagements.filter(~Q(engagement=None)).distinct()

    # count using prefetch instead of just using 'engagement__set_test_test` to avoid loading all test in memory just to count them
    filter_qs = products_with_engagements.prefetch_related(
        Prefetch('engagement_set', queryset=Engagement.objects.all().annotate(test_count=Count('test__id')))
    )

    filter_qs = filter_qs.prefetch_related(
        'engagement_set__tags',
        'prod_type',
        'engagement_set__lead',
        'tags',
    )
    if System_Settings.objects.get().enable_jira:
        filter_qs = filter_qs.prefetch_related(
            'engagement_set__jira_project__jira_instance',
            'jira_project_set__jira_instance'
        )

    filtered = EngagementFilter(
        request.GET,
        queryset=filter_qs
    )

    prods = get_page_items(request, filtered.qs, 25)

    name_words = products_with_engagements.values_list('name', flat=True)
    eng_words = get_authorized_engagements(Permissions.Engagement_View).values_list('name', flat=True).distinct()

    add_breadcrumb(
        title="All Engagements",
        top_level=not len(request.GET),
        request=request)

    return render(
        request, 'dojo/engagements_all.html', {
            'products': prods,
            'filter_form': filtered.form,
            'name_words': sorted(set(name_words)),
            'eng_words': sorted(set(eng_words)),
        })
예제 #7
0
def get_filtered_engagements(request, view):

    if view not in ['all', 'active']:
        raise ValidationError(f'View {view} is not allowed')

    engagements = get_authorized_engagements(Permissions.Engagement_View).order_by('-target_start')

    if view == 'active':
        engagements = engagements.filter(active=True)

    engagements = engagements.select_related('product', 'product__prod_type') \
        .prefetch_related('lead', 'tags', 'product__tags')

    if System_Settings.objects.get().enable_jira:
        engagements = engagements.prefetch_related(
            'jira_project__jira_instance',
            'product__jira_project_set__jira_instance'
        )

    engagements = EngagementDirectFilter(request.GET, queryset=engagements)

    return engagements
예제 #8
0
def simple_search(request):
    ip_addresses = []
    dashes = []
    query = []
    tests = None
    findings = None
    finding_templates = None
    products = None
    tagged_tests = None
    tagged_findings = None
    tagged_products = None
    tagged_endpoints = None
    tagged_engagements = None
    tagged_finding_templates = None
    engagements = None
    endpoints = None
    languages = None
    app_analysis = None
    clean_query = ''
    cookie = False
    terms = ''
    form = SimpleSearchForm()

    original_clean_query = ""
    findings_filter = None
    title_words = None
    component_words = None
    paged_generic = None

    # if request.method == 'GET' and "query" in request.GET:
    if request.method == 'GET':
        form = SimpleSearchForm(request.GET)
        if form.is_valid():
            cookie = True

            clean_query = form.cleaned_data['query'] or ''
            original_clean_query = clean_query

            operators, keywords = parse_search_query(clean_query)

            search_tags = "tag" in operators or "test-tag" in operators or "engagement-tag" in operators or "product-tag" in operators or\
                          "tags" in operators or "test-tags" in operators or "engagement-tags" in operators or "product-tags" in operators

            search_cve = "cve" in operators

            search_finding_id = "id" in operators
            search_findings = "finding" in operators or search_cve or search_finding_id or search_tags or not operators

            search_finding_templates = "template" in operators or search_tags or not (
                operators or search_finding_id or search_cve)
            search_tests = "test" in operators or search_tags or not (
                operators or search_finding_id or search_cve)
            search_engagements = "engagement" in operators or search_tags or not (
                operators or search_finding_id or search_cve)

            search_products = "product" in operators or search_tags or not (
                operators or search_finding_id or search_cve)
            search_endpoints = "endpoint" in operators or search_tags or not (
                operators or search_finding_id or search_cve)
            search_languages = "language" in operators or search_tags or not (
                operators or search_finding_id or search_cve)
            search_technologies = "technology" in operators or search_tags or not (
                operators or search_finding_id or search_cve)

            authorized_findings = Finding.objects.all()
            authorized_tests = get_authorized_tests(Permissions.Test_View)
            authorized_engagements = get_authorized_engagements(
                Permissions.Engagement_View)
            authorized_products = get_authorized_products(
                Permissions.Product_View)
            authorized_endpoints = Endpoint.objects.all()
            authorized_finding_templates = Finding_Template.objects.all()

            if not request.user.is_staff:
                authorized_findings = authorized_findings.filter(
                    Q(test__engagement__product__authorized_users__in=[
                        request.user
                    ]) |
                    Q(test__engagement__product__prod_type__authorized_users__in
                      =[request.user]))
                authorized_endpoints = authorized_endpoints.filter(
                    Q(product__authorized_users__in=[request.user]) |
                    Q(product__prod_type__authorized_users__in=[request.user]))
                # can't filter templates

            # TODO better get findings in their own query and match on id. that would allow filtering on additional fields such cve, prod_id, etc.

            findings = authorized_findings
            tests = authorized_tests
            engagements = authorized_engagements
            products = authorized_products
            endpoints = authorized_endpoints

            findings_filter = None
            title_words = None
            component_words = None

            keywords_query = ' '.join(keywords)

            if search_finding_id:
                logger.debug('searching finding id')

                findings = authorized_findings
                findings = findings.filter(id=operators['id'][0])

            elif search_findings:
                logger.debug('searching findings')

                findings_filter = OpenFindingFilter(request.GET,
                                                    queryset=findings,
                                                    user=request.user,
                                                    pid=None,
                                                    prefix='finding')
                # setting initial values for filters is not supported and discouraged: https://django-filter.readthedocs.io/en/stable/guide/tips.html#using-initial-values-as-defaults
                # we could try to modify request.GET before generating the filter, but for now we'll leave it as is

                title_words = get_words_for_field(authorized_findings, 'title')
                component_words = get_words_for_field(authorized_findings,
                                                      'component_name')

                findings = findings_filter.qs

                findings = apply_tag_filters(findings, operators)
                findings = apply_endpoint_filter(findings, operators)
                findings = apply_cve_filter(findings, operators)

                findings = perform_keyword_search_for_operator(
                    findings, operators, 'finding', keywords_query)

            else:
                findings = None
                findings_filter = None
                component_words = None

            # prefetch after watson to avoid inavlid query errors due to watson not understanding prefetching
            if findings is not None:  # check for None to avoid query execution
                logger.debug('prefetching findings')

                findings = get_page_items(request, findings, 25)

                findings.object_list = prefetch_for_findings(
                    findings.object_list)

                # some over the top tag displaying happening...
                findings.object_list = findings.object_list.prefetch_related(
                    'test__engagement__product__tags')

            tag = operators['tag'] if 'tag' in operators else keywords
            tags = operators['tags'] if 'tags' in operators else keywords
            if search_tags and tag or tags:
                logger.debug('searching tags')

                Q1, Q2 = Q(), Q()

                if tag:
                    tag = ','.join(tag)  # contains needs a single value
                    Q1 = Q(tags__name__contains=tag)

                if tags:
                    Q2 = Q(tags__name__in=tags)

                tagged_findings = authorized_findings.filter(
                    Q1 | Q2).distinct()[:max_results].prefetch_related('tags')
                tagged_finding_templates = authorized_finding_templates.filter(
                    Q1 | Q2).distinct()[:max_results]
                tagged_tests = authorized_tests.filter(
                    Q1 | Q2).distinct()[:max_results].prefetch_related('tags')
                tagged_engagements = authorized_engagements.filter(
                    Q1 | Q2).distinct()[:max_results].prefetch_related('tags')
                tagged_products = authorized_products.filter(
                    Q1 | Q2).distinct()[:max_results].prefetch_related('tags')
                tagged_endpoints = authorized_endpoints.filter(
                    Q1 | Q2).distinct()[:max_results].prefetch_related('tags')
            else:
                tagged_findings = None
                tagged_finding_templates = None
                tagged_tests = None
                tagged_engagements = None
                tagged_products = None
                tagged_endpoints = None

            tagged_results = tagged_findings or tagged_finding_templates or tagged_tests or tagged_engagements or tagged_products or tagged_endpoints

            if search_finding_templates:
                logger.debug('searching finding templates')

                finding_templates = authorized_finding_templates
                finding_templates = apply_tag_filters(finding_templates,
                                                      operators)

                if keywords_query:
                    watson_results = watson.filter(finding_templates,
                                                   keywords_query)
                    finding_templates = finding_templates.filter(
                        id__in=[watson.id for watson in watson_results])

                finding_templates = finding_templates[:max_results]
            else:
                finding_templates = None

            if search_tests:
                logger.debug('searching tests')

                tests = authorized_tests
                tests = apply_tag_filters(tests, operators)

                if keywords_query:
                    watson_results = watson.filter(tests, keywords_query)
                    tests = tests.filter(
                        id__in=[watson.id for watson in watson_results])

                tests = tests.prefetch_related('engagement',
                                               'engagement__product',
                                               'test_type', 'tags',
                                               'engagement__tags',
                                               'engagement__product__tags')
                tests = tests[:max_results]
            else:
                tests = None

            if search_engagements:
                logger.debug('searching engagements')

                engagements = authorized_engagements
                engagements = apply_tag_filters(engagements, operators)

                if keywords_query:
                    watson_results = watson.filter(engagements, keywords_query)
                    engagements = engagements.filter(
                        id__in=[watson.id for watson in watson_results])

                engagements = engagements.prefetch_related(
                    'product', 'product__tags', 'tags')
                engagements = engagements[:max_results]
            else:
                engagements = None

            if search_products:
                logger.debug('searching products')

                products = authorized_products
                products = apply_tag_filters(products, operators)

                if keywords_query:
                    watson_results = watson.filter(products, keywords_query)
                    products = products.filter(
                        id__in=[watson.id for watson in watson_results])

                products = products.prefetch_related('tags')
                products = products[:max_results]
            else:
                products = None

            if search_endpoints:
                logger.debug('searching endpoint')

                endpoints = authorized_endpoints
                endpoints = apply_tag_filters(endpoints, operators)

                endpoints = endpoints.filter(
                    Q(host__icontains=keywords_query)
                    | Q(path__icontains=keywords_query)
                    | Q(fqdn__icontains=keywords_query)
                    | Q(protocol__icontains=keywords_query))
                endpoints = prefetch_for_endpoints(endpoints)
                endpoints = endpoints[:max_results]
            else:
                endpoints = None

            if search_languages:
                logger.debug('searching languages')

                languages = Languages.objects.filter(
                    language__language__icontains=keywords_query)
                languages = languages.prefetch_related('product',
                                                       'product__tags')
                languages = languages[:max_results]
            else:
                languages = None

            if search_technologies:
                logger.debug('searching technologies')

                app_analysis = App_Analysis.objects.filter(
                    name__icontains=keywords_query)
                app_analysis = app_analysis[:max_results]
            else:
                app_analysis = None

            # make sure watson only searches in authorized model instances
            if keywords_query and False:
                logger.debug('searching generic')
                logger.debug('going generic with: %s', keywords_query)
                generic = watson.search(
                    keywords_query,
                    models=(
                        authorized_findings, authorized_tests,
                        authorized_engagements, authorized_products,
                        authorized_endpoints, authorized_finding_templates,
                        App_Analysis)).prefetch_related('object')[:max_results]
            else:
                generic = None

            # paging doesn't work well with django_watson
            # paged_generic = get_page_items(request, generic, 25)

            # generic = get_page_items(request, generic, 25)
            # generic = watson.search(original_clean_query)[:50].prefetch_related('object')
            # generic = watson.search("qander document 'CVE-2019-8331'")[:10].prefetch_related('object')
            # generic = watson.search("'CVE-2020-6754'")[:10].prefetch_related('object')
            # generic = watson.search(" 'ISEC-433'")[:10].prefetch_related('object')

            logger.debug('all searched')

        else:
            logger.debug(form.errors)
            form = SimpleSearchForm()

        add_breadcrumb(title="Simple Search", top_level=True, request=request)

        activetab = 'findings' if findings \
            else 'products' if products \
                else 'engagements' if engagements else \
                    'tests' if tests else \
                         'endpoint' if endpoints else \
                            'tagged' if tagged_results else \
                                'generic'

    response = render(
        request, 'dojo/simple_search.html', {
            'clean_query': original_clean_query,
            'languages': languages,
            'app_analysis': app_analysis,
            'tests': tests,
            'findings': findings,
            'finding_templates': finding_templates,
            'filtered': findings_filter,
            'title_words': title_words,
            'component_words': component_words,
            'products': products,
            'tagged_tests': tagged_tests,
            'tagged_findings': tagged_findings,
            'tagged_finding_templates': tagged_finding_templates,
            'tagged_products': tagged_products,
            'tagged_endpoints': tagged_endpoints,
            'tagged_engagements': tagged_engagements,
            'engagements': engagements,
            'endpoints': endpoints,
            'name': 'Simple Search',
            'metric': False,
            'user': request.user,
            'form': form,
            'activetab': activetab,
            'show_product_column': True,
            'generic': generic
        })

    if cookie:
        response.set_cookie("highlight",
                            value=keywords_query,
                            max_age=None,
                            expires=None,
                            path='/',
                            secure=True,
                            httponly=False)
    else:
        response.delete_cookie("highlight", path='/')
    return response
    '''