Пример #1
0
def process_endpoints_view(request, host_view=False, vulnerable=False):

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

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

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

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

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

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

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

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

    return render(
        request, 'dojo/endpoints.html', {
            'product_tab': product_tab,
            "endpoints": paged_endpoints,
            "filtered": endpoints,
            "name": view_name,
            "host_view": host_view,
            "product_tab": product_tab
        })
Пример #2
0
def all_endpoints(request):
    endpoints = Endpoint.objects.prefetch_related('product', 'tags',
                                                  'product__tags')
    endpoints = get_authorized_endpoints(Permissions.Endpoint_View, endpoints,
                                         request.user)
    show_uri = get_system_setting('display_endpoint_uri')

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

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

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

    return render(
        request, 'dojo/endpoints.html', {
            'product_tab': product_tab,
            "endpoints": paged_endpoints,
            "filtered": endpoints,
            "name": view_name,
            "show_uri": show_uri
        })
Пример #3
0
def endpoint_bulk_update_all(request, pid=None):
    if request.method == "POST":
        endpoints_to_update = request.POST.getlist('endpoints_to_update')
        finds = Endpoint.objects.filter(
            id__in=endpoints_to_update).order_by("endpoint_meta__product__id")
        total_endpoint_count = finds.count()

        if request.POST.get('delete_bulk_endpoints') and endpoints_to_update:

            if pid is None:
                if not request.user.is_staff:
                    raise PermissionDenied
            else:
                product = get_object_or_404(Product, id=pid)
                user_has_permission_or_403(request.user, product,
                                           Permissions.Endpoint_Delete)

            finds = get_authorized_endpoints(Permissions.Endpoint_Delete,
                                             finds, request.user)

            skipped_endpoint_count = total_endpoint_count - finds.count()
            deleted_endpoint_count = finds.count()

            product_calc = list(
                Product.objects.filter(
                    endpoint__id__in=endpoints_to_update).distinct())
            finds.delete()
            for prod in product_calc:
                calculate_grade(prod)

            if skipped_endpoint_count > 0:
                add_error_message_to_response(
                    'Skipped deletion of {} endpoints because you are not authorized.'
                    .format(skipped_endpoint_count))

            if deleted_endpoint_count > 0:
                messages.add_message(
                    request,
                    messages.SUCCESS,
                    'Bulk delete of {} endpoints was successful.'.format(
                        deleted_endpoint_count),
                    extra_tags='alert-success')
        else:
            if endpoints_to_update:

                if pid is None:
                    if not request.user.is_staff:
                        raise PermissionDenied
                else:
                    product = get_object_or_404(Product, id=pid)
                    user_has_permission_or_403(request.user, product,
                                               Permissions.Finding_Edit)

                finds = get_authorized_endpoints(Permissions.Endpoint_Edit,
                                                 finds, request.user)

                skipped_endpoint_count = total_endpoint_count - finds.count()
                updated_endpoint_count = finds.count()

                if skipped_endpoint_count > 0:
                    add_error_message_to_response(
                        'Skipped mitigation of {} endpoints because you are not authorized.'
                        .format(skipped_endpoint_count))

                for endpoint in finds:
                    endpoint.mitigated = not endpoint.mitigated
                    endpoint.save()

                if updated_endpoint_count > 0:
                    messages.add_message(
                        request,
                        messages.SUCCESS,
                        'Bulk mitigation of {} endpoints was successful.'.
                        format(updated_endpoint_count),
                        extra_tags='alert-success')
            else:
                messages.add_message(
                    request,
                    messages.ERROR,
                    'Unable to process bulk update. Required fields were not selected.',
                    extra_tags='alert-danger')
    return HttpResponseRedirect(reverse('endpoint', args=()))
Пример #4
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 or \
                          "not-tag" in operators or "not-test-tag" in operators or "not-engagement-tag" in operators or "not-product-tag" in operators or \
                          "not-tags" in operators or "not-test-tags" in operators or "not-engagement-tags" in operators or "not-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 = get_authorized_findings(
                Permissions.Finding_View)
            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 = get_authorized_endpoints(
                Permissions.Endpoint_View)
            authorized_finding_templates = Finding_Template.objects.all()

            # 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(Finding, 'title')
                component_words = get_words_for_field(Finding,
                                                      '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
            not_tag = operators[
                'not-tag'] if 'not-tag' in operators else keywords
            not_tags = operators[
                'not-tags'] if 'not-tags' in operators else keywords
            if search_tags and tag or tags or not_tag or not_tags:
                logger.debug('searching tags')

                Q1, Q2, Q3, Q4 = Q(), Q(), 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)

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

                if not_tags:
                    Q4 = Q(tags__name__in=not_tags)

                tagged_findings = authorized_findings.filter(Q1 | Q2).exclude(
                    Q3 | Q4).distinct()[:max_results].prefetch_related('tags')
                tagged_finding_templates = authorized_finding_templates.filter(
                    Q1 | Q2).exclude(Q3 | Q4).distinct()[:max_results]
                tagged_tests = authorized_tests.filter(Q1 | Q2).exclude(
                    Q3 | Q4).distinct()[:max_results].prefetch_related('tags')
                tagged_engagements = authorized_engagements.filter(
                    Q1 | Q2).exclude(
                        Q3
                        | Q4).distinct()[:max_results].prefetch_related('tags')
                tagged_products = authorized_products.filter(Q1 | Q2).exclude(
                    Q3 | Q4).distinct()[:max_results].prefetch_related('tags')
                tagged_endpoints = authorized_endpoints.filter(
                    Q1 | Q2).exclude(
                        Q3
                        | Q4).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(protocol__icontains=keywords_query)
                    | Q(query__icontains=keywords_query)
                    | Q(fragment__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:
                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
    '''