Exemplo n.º 1
0
def finding_sla(finding):
    if not get_system_setting('enable_finding_sla'):
        return ""

    title = ""
    severity = finding.severity
    find_sla = finding.sla()
    sla_age = get_system_setting('sla_' + severity.lower())
    if finding.mitigated:
        status = "blue"
        status_text = 'Remediated within SLA for ' + severity.lower() + ' findings (' + str(sla_age) + ' days)'
        if find_sla and find_sla < 0:
            status = "orange"
            find_sla = abs(find_sla)
            status_text = 'Out of SLA: Remediatied ' + str(find_sla) + ' days past SLA for ' + severity.lower() + ' findings (' + str(sla_age) + ' days)'
    else:
        status = "green"
        status_text = 'Remediation for ' + severity.lower() + ' findings in ' + str(sla_age) + ' days or less'
        if find_sla and find_sla < 0:
            status = "red"
            find_sla = abs(find_sla)
            status_text = 'Overdue: Remediation for ' + severity.lower() + ' findings in ' + str(sla_age) + ' days or less'

    if find_sla is not None:
        title = '<a data-toggle="tooltip" data-placement="bottom" title="" href="#" data-original-title="' + status_text + '">' \
                '<span class="label severity age-' + status + '">' + str(find_sla) + '</span></a>'

    return mark_safe(title)
Exemplo n.º 2
0
def new_eng_for_app(request, pid, cicd=False):
    jform = None
    prod = Product.objects.get(id=pid)
    if request.method == 'POST':
        form = EngForm(request.POST, cicd=cicd)
        if form.is_valid():
            new_eng = form.save(commit=False)
            if not new_eng.name:
                new_eng.name = str(new_eng.target_start)
            new_eng.threat_model = False
            new_eng.api_test = False
            new_eng.pen_test = False
            new_eng.check_list = False
            new_eng.product = prod
            if new_eng.threat_model:
                new_eng.progress = 'threat_model'
            else:
                new_eng.progress = 'other'
            if cicd:
                new_eng.engagement_type = 'CI/CD'
                new_eng.status = "In Progress"

            new_eng.save()
            tags = request.POST.getlist('tags')
            t = ", ".join(tags)
            new_eng.tags = t
            if get_system_setting('enable_jira'):
                    # Test to make sure there is a Jira project associated the product
                    try:
                        jform = JIRAFindingForm(request.POST, prefix='jiraform', enabled=JIRA_PKey.objects.get(product=prod).push_all_issues)
                        if jform.is_valid():
                            add_epic_task.delay(new_eng, jform.cleaned_data.get('push_to_jira'))
                    except JIRA_PKey.DoesNotExist:
                        pass

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

            create_notification(event='engagement_added', title=new_eng.name + " for " + prod.name, engagement=new_eng, url=request.build_absolute_uri(reverse('view_engagement', args=(new_eng.id,))), objowner=new_eng.lead)

            if "_Add Tests" in request.POST:
                return HttpResponseRedirect(reverse('add_tests', args=(new_eng.id,)))
            elif "_Import Scan Results" in request.POST:
                return HttpResponseRedirect(reverse('import_scan_results', args=(new_eng.id,)))
            else:
                return HttpResponseRedirect(reverse('view_engagement', args=(new_eng.id,)))
    else:
        form = EngForm(initial={'lead': request.user, 'target_start': timezone.now().date(), 'target_end': timezone.now().date() + timedelta(days=7)}, cicd=cicd, product=prod.id)
        if(get_system_setting('enable_jira')):
                if JIRA_PKey.objects.filter(product=prod).count() != 0:
                    jform = JIRAFindingForm(prefix='jiraform', enabled=JIRA_PKey.objects.get(product=prod).push_all_issues)

    product_tab = Product_Tab(pid, title="New Engagement", tab="engagements")
    return render(request, 'dojo/new_eng.html',
                  {'form': form, 'pid': pid,
                   'product_tab': product_tab,
                   'jform': jform
                   })
Exemplo n.º 3
0
        def runScan(prod_id, p_dict):
            ipScan_queue = Queue.Queue(50)
            for host in p_dict:
                current_scan = Scan.objects.get(id=p_dict[host]['scan_id'])
                if not current_scan.date:
                    current_scan.date = locale.localize(datetime.today())

                # For each host, save the IPScan and the date to the scan
                # to the db

                ipScan_queue.put((host, p_dict[host]))
                ipscan_thread = threadedIPScan(ipScan_queue)
                ipscan_thread.setDaemon(True)
                ipscan_thread.start()

            ipScan_queue.join()

            # Compare the results to the expected ports and email results if
            # necessary
            product = Product.objects.get(id=prod_id).name
            msg = "Hello, \n\nA port scan of the product " + product
            msg += " was performed on " + locale.normalize(
                current_scan.date).strftime("%A %B %d, %Y at %I:%M:%S %p")
            msg += "\nThe results of the scan show that the following ip "
            msg += "addresses have the following ports open: \n\n"

            for host in p_dict:
                msg += str(host) + ": \n"
                for p in p_dict[host]['result']:
                    msg += str(p) + " \n"

                scans_same_setting = Scan.objects.filter(
                    scan_settings=current_scan.scan_settings)
                diff = p_dict[host]['result'] - p_dict[host]['expected']
                if diff and len(scans_same_setting) > 1:
                    msg += '\nThese ports appear in this scan but were not '
                    msg += 'open in the previous scan:\n '
                    msg += '****** Please ensure that these ports are open if '
                    msg += 'and only if you have meant it that way ******\n'
                    msg += str(host) + ": \n"
                    for d in diff:
                        msg += str(d) + " \n"

            msg += "\nYou are receiving this email because you have signed up "
            msg += "for a port scan on the product security test dojo.\n"
            msg += "\nFor any questions please email "
            msg += settings.PORT_SCAN_CONTACT_EMAIL + "\n"
            msg += "Thanks,\nThe "
            msg += get_system_setting('team_name')
            msg += " Team"
            email_to = current_scan.scan_settings.email

            send_mail(get_system_setting('team_name') + ' Port Scan Report',
                      msg,
                      settings.PORT_SCAN_RESULT_EMAIL_FROM,
                      [email_to],
                      fail_silently=False)
Exemplo n.º 4
0
def new_eng_for_app(request, pid):
    jform = None
    prod = Product.objects.get(id=pid)
    if request.method == 'POST':
        form = EngForm(request.POST)
        if form.is_valid():
            new_eng = form.save(commit=False)
            new_eng.product = prod
            if new_eng.threat_model:
                new_eng.progress = 'threat_model'
            else:
                new_eng.progress = 'other'
            new_eng.save()
            if get_system_setting('enable_jira'):
                    #Test to make sure there is a Jira project associated the product
                    try:
                        jform = JIRAFindingForm(request.POST, prefix='jiraform',
                                            enabled=JIRA_PKey.objects.get(product=prod).push_all_issues)
                        if jform.is_valid():
                            add_epic_task.delay(new_eng, jform.cleaned_data.get('push_to_jira'))
                    except JIRA_PKey.DoesNotExist:
                        pass

            #else:
            #    print >>sys.stderr, 'no prefix is found'

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

            create_notification(event='engagement_added', title='Engagement added', engagement=new_eng, url=request.build_absolute_uri(reverse('view_engagement', args=(new_eng.id,))), objowner=new_eng.lead)

            if "_Add Tests" in request.POST:
                return HttpResponseRedirect(reverse('add_tests', args=(new_eng.id,)))
            else:
                return HttpResponseRedirect(reverse('view_engagement', args=(new_eng.id,)))
    else:
        form = EngForm(initial={})
        if(get_system_setting('enable_jira')):
                if JIRA_PKey.objects.filter(product=prod).count() != 0:
                    jform = JIRAFindingForm(prefix='jiraform', enabled=JIRA_PKey.objects.get(product=prod).push_all_issues)

    add_breadcrumb(parent=prod, title="New Engagement", top_level=False, request=request)

    return render(request, 'dojo/new_eng.html',
                  {'form': form, 'pid': pid,
                   'jform': jform
                   })
Exemplo n.º 5
0
def webhook(request):
    # Webhook shouldn't be active if jira isn't enabled
    if not get_system_setting('enable_jira'):
        raise PermissionDenied
    elif not get_system_setting('enable_jira_web_hook'):
        raise PermissionDenied

    if request.method == 'POST':
        parsed = json.loads(request.body)
        if 'issue' in parsed.keys():
            jid = parsed['issue']['id']
            jissue = get_object_or_404(JIRA_Issue, jira_id=jid)
            if jissue.finding is not None:
                finding = jissue.finding
                resolved = True
                if parsed['issue']['fields']['resolution'] is None:
                    resolved = False
                if finding.active == resolved:
                    if finding.active:
                        now = timezone.now()
                        finding.active = False
                        finding.mitigated = now
                        finding.endpoints.clear()
                    else:
                        finding.active = True
                        finding.mitigated = None
                        finding.save()
                    finding.save()
            """
            if jissue.engagement is not None:
                eng = jissue.engagement
                if parsed['issue']['fields']['resolution'] != None:
                    eng.active = False
                    eng.status = 'Completed'
                    eng.save()
           """
        else:
            comment_text = parsed['comment']['body']
            commentor = parsed['comment']['updateAuthor']['displayName']
            jid = parsed['comment']['self'].split('/')[7]
            jissue = JIRA_Issue.objects.get(jira_id=jid)
            finding = jissue.finding
            new_note = Notes()
            new_note.entry = '(%s): %s' % (commentor, comment_text)
            new_note.author, created = User.objects.get_or_create(username='******')
            new_note.save()
            finding.notes.add(new_note)
            finding.save()
    return HttpResponse('')
Exemplo n.º 6
0
def all_endpoints(request):
    endpoints = Endpoint.objects.all()
    show_uri = get_system_setting('display_endpoint_uri')
    # are they authorized
    if request.user.is_staff:
        pass
    else:
        products = Product.objects.filter(authorized_users__in=[request.user])
        if products.exists():
            endpoints = endpoints.filter(product__in=products.all())
        else:
            raise PermissionDenied

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

    ids = get_endpoint_ids(EndpointFilter(request.GET, queryset=endpoints, user=request.user).qs)
    if show_uri:
        paged_endpoints = get_page_items(request, endpoints, 25)
    else:
        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)
    return render(request,
                  'dojo/endpoints.html',
                  {"endpoints": paged_endpoints,
                   "filtered": endpoints,
                   "name": "All Endpoints",
                   "show_uri": show_uri
                   })
def severity_value(value):
    try:
        if get_system_setting('s_finding_severity_naming'):
            value = Finding.get_numerical_severity(value)
    except:
        pass

    return value
Exemplo n.º 8
0
    def handle(self, *args, **options):
        type = options['type']

        if not options:
            print "Must specify an argument: Weekly, Monthly, or Quarterly"
            sys.exit(0)
        if type not in ["Weekly", "Monthly", "Quarterly"]:
            print("Unexpected frequency: " + str(type) +
                  "\nMust specify an argument: Weekly, Monthly, or Quarterly.")
            sys.exit(0)

        scSettings = ScanSettings.objects.filter(frequency=type)

        scan_start_time = datetime.datetime.today() + datetime.timedelta(
            hours=12)
        scan_stop_time = datetime.datetime.today() + datetime.timedelta(
            hours=24)

        # Send one giant email to External Unit with a list  of all the
        # ipaddresses that will be scanned
        msg = "\nGreetings, \n\n"
        msg += get_system_setting('team_name') + " will be performing port scans of "
        msg += "the following products and target IPs:"
        msg += "\n\nStart Time: " + str(scan_start_time)
        msg += "\n\nStop Time (est): " + str(scan_stop_time)
        msg += "\n\nSource IP: " + settings.PORT_SCAN_SOURCE_IP
        for s in scSettings:
            msg += "\n\nProduct: " + str(Product.objects.get(
                id=s.product_id).name)

            list_addresses = s.addresses.strip().split(",")
            for la in list_addresses:
                line = la.split(":")
                addr = line[0].strip()
                msg += "\n" + str(addr)

        msg += "\n\nPlease let us know if you have any questions.\n Thanks,\n"
        msg += settings.PORT_SCAN_RESULT_EMAIL_FROM
        send_mail(get_system_setting('team_name') + ' Port Scan',
                  msg,
                  settings.PORT_SCAN_RESULT_EMAIL_FROM,
                  settings.PORT_SCAN_EXTERNAL_UNIT_EMAIL_LIST,
                  fail_silently=False)
Exemplo n.º 9
0
def critical_product_metrics(request, mtype):
    template = 'dojo/metrics.html'
    page_name = 'Critical Product Metrics'
    critical_products = Product_Type.objects.filter(critical_product=True)
    add_breadcrumb(title=page_name, top_level=not len(request.GET), request=request)
    return render(request, template, {
        'name': page_name,
        'critical_prods': critical_products,
        'url_prefix': get_system_setting('url_prefix')
    })
Exemplo n.º 10
0
def new_product(request):
    jform = None
    if request.method == 'POST':
        form = ProductForm(request.POST, instance=Product())
        if get_system_setting('enable_jira'):
                jform = JIRAPKeyForm(request.POST, instance=JIRA_PKey())
        else:
            jform = None

        if form.is_valid():
            product = form.save()
            tags = request.POST.getlist('tags')
            t = ", ".join(tags)
            product.tags = t
            messages.add_message(request,
                                 messages.SUCCESS,
                                 'Product added successfully.',
                                 extra_tags='alert-success')
            if get_system_setting('enable_jira'):
                    if jform.is_valid():
                        jira_pkey = jform.save(commit=False)
                        if jira_pkey.conf is not None:
                            jira_pkey.product = product
                            jira_pkey.save()
                            messages.add_message(request,
                                                 messages.SUCCESS,
                                                 'JIRA information added successfully.',
                                                 extra_tags='alert-success')
            create_notification(event='product_added', title=product.name, url=request.build_absolute_uri(reverse('view_product', args=(product.id,))))
            return HttpResponseRedirect(reverse('view_product', args=(product.id,)))
    else:
        form = ProductForm()
        if get_system_setting('enable_jira'):
                jform = JIRAPKeyForm()
        else:
            jform = None
    add_breadcrumb(title="New Product", top_level=False, request=request)
    return render(request, 'dojo/new_product.html',
                  {'form': form,
                   'jform': jform})
Exemplo n.º 11
0
def edit_engagement(request, eid):
    eng = Engagement.objects.get(pk=eid)
    jform = None
    if request.method == 'POST':
        form = EngForm2(request.POST, instance=eng)
        if 'jiraform-push_to_jira' in request.POST:
            jform = JIRAFindingForm(request.POST, prefix='jiraform', enabled=True)
        if form.is_valid():
            if 'jiraform-push_to_jira' in request.POST:
                try:
                    jissue = JIRA_Issue.objects.get(engagement=eng)
                    update_epic_task.delay(eng, jform.cleaned_data.get('push_to_jira'))
                    enabled = True
                except:
                    enabled = False
                    add_epic_task.delay(eng, jform.cleaned_data.get('push_to_jira'))
                    pass
            form.save()
            tags = request.POST.getlist('tags')
            t = ", ".join(tags)
            eng.tags = t
            messages.add_message(request,
                                 messages.SUCCESS,
                                 'Engagement updated successfully.',
                                 extra_tags='alert-success')
            if '_Add Tests' in request.POST:
                return HttpResponseRedirect(reverse('add_tests', args=(eng.id,)))
            else:
                return HttpResponseRedirect(reverse('view_engagement', args=(eng.id,)))
    else:
        form = EngForm2(instance=eng)
        try:
            jissue = JIRA_Issue.objects.get(engagement=eng)
            enabled = True
        except:
            enabled = False
            pass

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

    form.initial['tags'] = [tag.name for tag in eng.tags]
    add_breadcrumb(parent=eng, title="Edit Engagement", top_level=False, request=request)
    return render(request, 'dojo/new_eng.html',
                  {'form': form, 'edit': True, 'jform': jform
                   })
Exemplo n.º 12
0
def close_eng(request, eid):
    eng = Engagement.objects.get(id=eid)
    eng.active = False
    eng.status = 'Completed'
    eng.updated = timezone.now()
    eng.save()

    if get_system_setting('enable_jira'):
        jpkey_set = JIRA_PKey.objects.filter(product=eng.product)
        if jpkey_set.count() >= 1:
            close_epic_task(eng, True)
    messages.add_message(
        request,
        messages.SUCCESS,
        'Engagement closed successfully.',
        extra_tags='alert-success')
    if eng.engagement_type == 'CI/CD':
        return HttpResponseRedirect(reverse("view_engagements_cicd", args=(eng.product.id, )))
    else:
        return HttpResponseRedirect(reverse("view_engagements", args=(eng.product.id, )))
Exemplo n.º 13
0
def product_endpoint_report(request, pid):
    user = Dojo_User.objects.get(id=request.user.id)
    product = get_object_or_404(Product, id=pid)
    endpoints = Endpoint.objects.filter(
        product=product,
        finding__active=True,
        finding__verified=True,
        finding__false_p=False,
        finding__duplicate=False,
        finding__out_of_scope=False,
    )

    ids = get_endpoint_ids(endpoints)

    endpoints = Endpoint.objects.filter(id__in=ids)
    endpoints = EndpointReportFilter(request.GET, queryset=endpoints)

    paged_endpoints = get_page_items(request, endpoints.qs, 25)
    report_format = request.GET.get('report_type', 'AsciiDoc')
    include_finding_notes = int(request.GET.get('include_finding_notes', 0))
    include_finding_images = int(request.GET.get('include_finding_images', 0))
    include_executive_summary = int(
        request.GET.get('include_executive_summary', 0))
    include_table_of_contents = int(
        request.GET.get('include_table_of_contents', 0))
    generate = "_generate" in request.GET
    add_breadcrumb(parent=product,
                   title="Vulnerable Product Endpoints Report",
                   top_level=False,
                   request=request)
    report_form = ReportOptionsForm()

    filename = "product_endpoint_report.pdf"
    template = "dojo/product_endpoint_pdf_report.html"
    report_name = "Product Endpoint Report: " + str(product)
    report_title = "Product Endpoint Report"
    report_subtitle = str(product)
    report_info = "Generated By %s on %s" % (user.get_full_name(), (
        timezone.now().strftime("%m/%d/%Y %I:%M%p %Z")))

    try:
        start_date = Finding.objects.filter(
            endpoints__in=endpoints.qs).order_by('date')[:1][0].date
    except:
        start_date = timezone.now()

    end_date = timezone.now()

    risk_acceptances = Risk_Acceptance.objects.filter(
        engagement__test__finding__endpoints__in=endpoints.qs)

    accepted_findings = [
        finding for ra in risk_acceptances
        for finding in ra.accepted_findings.filter(endpoints__in=endpoints.qs)
    ]

    verified_findings = Finding.objects.filter(
        endpoints__in=endpoints.qs,
        date__range=[start_date, end_date],
        false_p=False,
        verified=True,
        duplicate=False,
        out_of_scope=False)

    open_findings = Finding.objects.filter(endpoints__in=endpoints.qs,
                                           false_p=False,
                                           verified=True,
                                           duplicate=False,
                                           out_of_scope=False,
                                           active=True,
                                           mitigated__isnull=True)

    closed_findings = Finding.objects.filter(endpoints__in=endpoints.qs,
                                             false_p=False,
                                             verified=True,
                                             duplicate=False,
                                             out_of_scope=False,
                                             mitigated__isnull=False)
    if generate:
        report_form = ReportOptionsForm(request.GET)
        if report_format == 'AsciiDoc':
            return render(
                request, 'dojo/asciidoc_report.html', {
                    'product_type': None,
                    'product': product,
                    'accepted_findings': accepted_findings,
                    'open_findings': open_findings,
                    'closed_findings': closed_findings,
                    'verified_findings': verified_findings,
                    'engagement': None,
                    'test': None,
                    'endpoints': endpoints,
                    'endpoint': None,
                    'findings': None,
                    'include_finding_notes': include_finding_notes,
                    'include_finding_images': include_finding_images,
                    'include_executive_summary': include_executive_summary,
                    'include_table_of_contents': include_table_of_contents,
                    'user': request.user,
                    'title': 'Generate Report',
                })
        elif report_format == 'PDF':
            endpoints = endpoints.qs.order_by('finding__numerical_severity')
            # lets create the report object and send it in to celery task
            if 'regen' in request.GET:
                # we should already have a report object, lets get and use it
                report = get_object_or_404(Report, id=request.GET['regen'])
                report.datetime = timezone.now()
                report.status = 'requested'
                if report.requester.username != request.user.username:
                    report.requester = request.user
            else:
                report = Report(name="Product Endpoints " + str(product),
                                type="Product Endpoint",
                                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={
                    'product': product,
                    'endpoints': endpoints,
                    'accepted_findings': accepted_findings,
                    'open_findings': open_findings,
                    'closed_findings': closed_findings,
                    'verified_findings': verified_findings,
                    'report_name': report_name,
                    'include_finding_notes': include_finding_notes,
                    'include_finding_images': include_finding_images,
                    'include_executive_summary': include_executive_summary,
                    'include_table_of_contents': include_table_of_contents,
                    'user': user,
                    'team_name': get_system_setting('team_name'),
                    'title': 'Generate Report',
                    'host': report_url_resolver(request),
                    'user_id': request.user.id
                },
                uri=request.build_absolute_uri(report.get_url()))
            messages.add_message(request,
                                 messages.SUCCESS,
                                 'Your report is building.',
                                 extra_tags='alert-success')
            return HttpResponseRedirect(reverse('reports'))
        elif report_format == 'HTML':
            return render(
                request, template, {
                    'product_type': None,
                    'product': product,
                    'engagement': None,
                    'test': None,
                    'endpoint': None,
                    'endpoints': endpoints.qs,
                    'findings': None,
                    'include_finding_notes': include_finding_notes,
                    'include_finding_images': include_finding_images,
                    'include_executive_summary': include_executive_summary,
                    'include_table_of_contents': include_table_of_contents,
                    'user': request.user,
                    'title': 'Generate Report',
                })
        else:
            raise Http404()

    product_tab = Product_Tab(product.id,
                              "Product Endpoint Report",
                              tab="endpoints")
    return render(
        request, 'dojo/request_endpoint_report.html', {
            "endpoints": paged_endpoints,
            "filtered": endpoints,
            "product_tab": product_tab,
            'report_form': report_form,
            "name": "Vulnerable Product Endpoints",
        })
Exemplo n.º 14
0
def process_jira_project_form(request, instance=None, product=None, engagement=None):
    if not get_system_setting('enable_jira'):
        return True, None

    error = False
    jira_project = None
    # supply empty instance to form so it has default values needed to make has_changed() work
    # jform = JIRAProjectForm(request.POST, instance=instance if instance else JIRA_Project(), product=product)
    jform = JIRAProjectForm(request.POST, instance=instance, product=product, engagement=engagement)
    # logging has_changed because it sometimes doesn't do what we expect
    logger.debug('jform has changed: %s', str(jform.has_changed()))

    if jform.has_changed():  # if no data was changed, no need to do anything!
        logger.debug('jform changed_data: %s', jform.changed_data)
        logger.debug('jform: %s', vars(jform))
        if jform.is_valid():
            try:
                jira_project = jform.save(commit=False)
                # could be a new jira_project, so set product_id
                if engagement:
                    jira_project.engagement_id = engagement.id
                    obj = engagement
                elif product:
                    jira_project.product_id = product.id
                    obj = product

                if not jira_project.product_id and not jira_project.engagement_id:
                    raise ValueError('encountered JIRA_Project without product_id and without engagement_id')

                # only check jira project if form is sufficiently populated
                if jira_project.jira_instance and jira_project.project_key:
                    # is_jira_project_valid already adds messages if not a valid jira project
                    if not is_jira_project_valid(jira_project):
                        logger.debug('unable to retrieve jira project from jira instance, invalid?!')
                        error = True
                    else:
                        logger.debug(vars(jira_project))
                        jira_project.save()
                        # update the in memory instance to make jira_project attribute work and it can be retrieved when pushing
                        # an epic in the next step

                        obj.jira_project = jira_project

                        messages.add_message(request,
                                                messages.SUCCESS,
                                                'JIRA Project config stored successfully.',
                                                extra_tags='alert-success')
                        error = False
                        logger.debug('stored JIRA_Project succesfully')
            except Exception as e:
                error = True
                logger.exception(e)
                pass
        else:
            logger.debug(jform.errors)
            error = True

        if error:
            messages.add_message(request,
                                    messages.ERROR,
                                    'JIRA Project config not stored due to errors.',
                                    extra_tags='alert-danger')
    return not error, jform
Exemplo n.º 15
0
def ad_hoc_finding(request, pid):
    prod = Product.objects.get(id=pid)
    test = None
    try:
        eng = Engagement.objects.get(product=prod, name="Ad Hoc Engagement")
        tests = Test.objects.filter(engagement=eng)

        if len(tests) != 0:
            test = tests[0]
        else:
            test = Test(engagement=eng,
                        test_type=Test_Type.objects.get(name="Pen Test"),
                        target_start=timezone.now(),
                        target_end=timezone.now())
            test.save()
    except:
        eng = Engagement(name="Ad Hoc Engagement",
                         target_start=timezone.now(),
                         target_end=timezone.now(),
                         active=False,
                         product=prod)
        eng.save()
        test = Test(engagement=eng,
                    test_type=Test_Type.objects.get(name="Pen Test"),
                    target_start=timezone.now(),
                    target_end=timezone.now())
        test.save()
    form_error = False
    enabled = False
    jform = None
    form = AdHocFindingForm(initial={'date': timezone.now().date()})
    if get_system_setting('enable_jira'):
        if JIRA_PKey.objects.filter(
                product=test.engagement.product).count() != 0:
            enabled = JIRA_PKey.objects.get(
                product=test.engagement.product).push_all_issues
            jform = JIRAFindingForm(enabled=enabled, prefix='jiraform')
    else:
        jform = None
    if request.method == 'POST':
        form = AdHocFindingForm(request.POST)
        if (form['active'].value() is False or form['false_p'].value()
            ) and form['duplicate'].value() is False:
            closing_disabled = Note_Type.objects.filter(
                is_mandatory=True, is_active=True).count()
            if closing_disabled != 0:
                error_inactive = ValidationError(
                    'Can not set a finding as inactive without adding all mandatory notes',
                    code='inactive_without_mandatory_notes')
                error_false_p = ValidationError(
                    'Can not set a finding as false positive without adding all mandatory notes',
                    code='false_p_without_mandatory_notes')
                if form['active'].value() is False:
                    form.add_error('active', error_inactive)
                if form['false_p'].value():
                    form.add_error('false_p', error_false_p)
                messages.add_message(
                    request,
                    messages.ERROR,
                    'Can not set a finding as inactive or false positive without adding all mandatory notes',
                    extra_tags='alert-danger')
        if form.is_valid():
            new_finding = form.save(commit=False)
            new_finding.test = test
            new_finding.reporter = request.user
            new_finding.numerical_severity = Finding.get_numerical_severity(
                new_finding.severity)
            if new_finding.false_p or new_finding.active is False:
                new_finding.mitigated = timezone.now()
                new_finding.mitigated_by = request.user
            create_template = new_finding.is_template
            # always false now since this will be deprecated soon in favor of new Finding_Template model
            new_finding.is_template = False
            new_finding.save()
            new_finding.endpoints.set(form.cleaned_data['endpoints'])
            new_finding.save()
            if 'jiraform-push_to_jira' in request.POST:
                jform = JIRAFindingForm(request.POST,
                                        prefix='jiraform',
                                        enabled=enabled)
                if jform.is_valid():
                    add_issue_task.delay(
                        new_finding, jform.cleaned_data.get('push_to_jira'))
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'Finding added successfully.',
                                     extra_tags='alert-success')
            if create_template:
                templates = Finding_Template.objects.filter(
                    title=new_finding.title)
                if len(templates) > 0:
                    messages.add_message(
                        request,
                        messages.ERROR,
                        'A finding template was not created.  A template with this title already '
                        'exists.',
                        extra_tags='alert-danger')
                else:
                    template = Finding_Template(
                        title=new_finding.title,
                        cwe=new_finding.cwe,
                        severity=new_finding.severity,
                        description=new_finding.description,
                        mitigation=new_finding.mitigation,
                        impact=new_finding.impact,
                        references=new_finding.references,
                        numerical_severity=new_finding.numerical_severity)
                    template.save()
                    messages.add_message(
                        request,
                        messages.SUCCESS,
                        'A finding template was also created.',
                        extra_tags='alert-success')
            if '_Finished' in request.POST:
                return HttpResponseRedirect(
                    reverse('view_test', args=(test.id, )))
            else:
                return HttpResponseRedirect(
                    reverse('add_findings', args=(test.id, )))
        else:
            if 'endpoints' in form.cleaned_data:
                form.fields['endpoints'].queryset = form.cleaned_data[
                    'endpoints']
            else:
                form.fields['endpoints'].queryset = Endpoint.objects.none()
            form_error = True
            messages.add_message(
                request,
                messages.ERROR,
                'The form has errors, please correct them below.',
                extra_tags='alert-danger')
    product_tab = Product_Tab(pid, title="Add Finding", tab="engagements")
    product_tab.setEngagement(eng)
    return render(
        request, 'dojo/ad_hoc_findings.html', {
            'form': form,
            'product_tab': product_tab,
            'temp': False,
            'tid': test.id,
            'pid': pid,
            'form_error': form_error,
            'jform': jform,
        })
Exemplo n.º 16
0
def product_endpoint_report(request, pid):
    user = Dojo_User.objects.get(id=request.user.id)
    product = get_object_or_404(Product.objects.all().prefetch_related('engagement_set__test_set__test_type', 'engagement_set__test_set__environment'), id=pid)
    endpoint_ids = Endpoint.objects.filter(product=product,
                                           finding__active=True,
                                           finding__verified=True,
                                           finding__false_p=False,
                                           finding__duplicate=False,
                                           finding__out_of_scope=False,
                                           ).values_list('id', flat=True)

    endpoints = prefetch_related_endpoints_for_report(Endpoint.objects.filter(id__in=endpoint_ids))
    endpoints = EndpointReportFilter(request.GET, queryset=endpoints)

    paged_endpoints = get_page_items(request, endpoints.qs, 25)
    report_format = request.GET.get('report_type', 'AsciiDoc')
    include_finding_notes = int(request.GET.get('include_finding_notes', 0))
    include_finding_images = int(request.GET.get('include_finding_images', 0))
    include_executive_summary = int(request.GET.get('include_executive_summary', 0))
    include_table_of_contents = int(request.GET.get('include_table_of_contents', 0))
    include_disclaimer = int(request.GET.get('include_disclaimer', 0))
    disclaimer = get_system_setting('disclaimer')
    if include_disclaimer and len(disclaimer) == 0:
        disclaimer = 'Please configure in System Settings.'
    generate = "_generate" in request.GET
    add_breadcrumb(parent=product, title="Vulnerable Product Endpoints Report", top_level=False, request=request)
    report_form = ReportOptionsForm()

    template = "dojo/product_endpoint_pdf_report.html"
    report_name = "Product Endpoint Report: " + str(product)
    report_title = "Product Endpoint Report"
    report_subtitle = str(product)
    report_info = "Generated By %s on %s" % (
        user.get_full_name(), (timezone.now().strftime("%m/%d/%Y %I:%M%p %Z")))

    try:
        start_date = Finding.objects.filter(endpoints__in=endpoints.qs).order_by('date')[:1][0].date
    except:
        start_date = timezone.now()

    end_date = timezone.now()

    risk_acceptances = Risk_Acceptance.objects.filter(engagement__test__finding__endpoints__in=endpoints.qs)

    accepted_findings = [finding for ra in risk_acceptances
                         for finding in ra.accepted_findings.filter(endpoints__in=endpoints.qs)]

    verified_findings = Finding.objects.filter(endpoints__in=endpoints.qs,
                                               date__range=[start_date, end_date],
                                               false_p=False,
                                               verified=True,
                                               duplicate=False,
                                               out_of_scope=False)

    open_findings = Finding.objects.filter(endpoints__in=endpoints.qs,
                                           false_p=False,
                                           verified=True,
                                           duplicate=False,
                                           out_of_scope=False,
                                           active=True,
                                           mitigated__isnull=True)

    closed_findings = Finding.objects.filter(endpoints__in=endpoints.qs,
                                             false_p=False,
                                             verified=True,
                                             duplicate=False,
                                             out_of_scope=False,
                                             mitigated__isnull=False)
    if generate:
        report_form = ReportOptionsForm(request.GET)
        if report_format == 'AsciiDoc':
            return render(request,
                          'dojo/asciidoc_report.html',
                          {'product_type': None,
                           'product': product,
                           'accepted_findings': accepted_findings,
                           'open_findings': open_findings,
                           'closed_findings': closed_findings,
                           'verified_findings': verified_findings,
                           'engagement': None,
                           'test': None,
                           'endpoints': endpoints,
                           'endpoint': None,
                           'findings': None,
                           'include_finding_notes': include_finding_notes,
                           'include_finding_images': include_finding_images,
                           'include_executive_summary': include_executive_summary,
                           'include_table_of_contents': include_table_of_contents,
                           'include_disclaimer': include_disclaimer,
                           'disclaimer': disclaimer,
                           'user': request.user,
                           'title': 'Generate Report',
                           })
        elif report_format == 'HTML':
            return render(request,
                          template,
                          {'product_type': None,
                           'product': product,
                           'engagement': None,
                           'test': None,
                           'endpoint': None,
                           'endpoints': endpoints.qs,
                           'findings': None,
                           'include_finding_notes': include_finding_notes,
                           'include_finding_images': include_finding_images,
                           'include_executive_summary': include_executive_summary,
                           'include_table_of_contents': include_table_of_contents,
                           'include_disclaimer': include_disclaimer,
                           'disclaimer': disclaimer,
                           'user': request.user,
                           'title': 'Generate Report',
                           })
        else:
            raise Http404()

    product_tab = Product_Tab(product.id, "Product Endpoint Report", tab="endpoints")
    return render(request,
                  'dojo/request_endpoint_report.html',
                  {"endpoints": paged_endpoints,
                   "filtered": endpoints,
                   "product_tab": product_tab,
                   'report_form': report_form,
                   "name": "Vulnerable Product Endpoints",
                   })
Exemplo n.º 17
0
def webhook(request, secret=None):
    if not get_system_setting('enable_jira'):
        logger.debug('ignoring incoming webhook as JIRA is disabled.')
        raise Http404('JIRA disabled')
    elif not get_system_setting('enable_jira_web_hook'):
        logger.debug('ignoring incoming webhook as JIRA Webhook is disabled.')
        raise Http404('JIRA Webhook disabled')
    elif not get_system_setting('disable_jira_webhook_secret'):
        if not get_system_setting('jira_webhook_secret'):
            logger.warning(
                'ignoring incoming webhook as JIRA Webhook secret is empty in Defect Dojo system settings.'
            )
            raise PermissionDenied('JIRA Webhook secret cannot be empty')
        if secret != get_system_setting('jira_webhook_secret'):
            logger.warning('invalid secret provided to JIRA Webhook')
            raise PermissionDenied(
                'invalid or no secret provided to JIRA Webhook')

    # if webhook secret is disabled in system_settings, we ignore the incoming secret, even if it doesn't match

    # example json bodies at the end of this file

    if request.content_type != 'application/json':
        return HttpResponseBadRequest("only application/json supported")

    if request.method == 'POST':
        try:
            parsed = json.loads(request.body.decode('utf-8'))
            if parsed.get('webhookEvent') == 'jira:issue_updated':
                # xml examples at the end of file
                jid = parsed['issue']['id']
                jissue = get_object_or_404(JIRA_Issue, jira_id=jid)
                logging.info("Received issue update for {}".format(
                    jissue.jira_key))
                if jissue.finding:
                    finding = jissue.finding

                    assignee = parsed['issue']['fields'].get('assignee')
                    assignee_name = assignee['name'] if assignee else None

                    resolution = parsed['issue']['fields']['resolution']

                    #         "resolution":{
                    #             "self":"http://www.testjira.com/rest/api/2/resolution/11",
                    #             "id":"11",
                    #             "description":"Cancelled by the customer.",
                    #             "name":"Cancelled"
                    #         },

                    # or
                    #         "resolution": null

                    # or
                    #         "resolution": "None"

                    resolution = resolution if resolution and resolution != "None" else None
                    resolution_id = resolution['id'] if resolution else None
                    resolution_name = resolution['name'] if resolution else None
                    jira_now = parse_datetime(
                        parsed['issue']['fields']['updated'])
                    jira_helper.process_resolution_from_jira(
                        finding, resolution_id, resolution_name, assignee_name,
                        jira_now)
                elif jissue.engagement:
                    # if parsed['issue']['fields']['resolution'] != None:
                    #     eng.active = False
                    #     eng.status = 'Completed'
                    #     eng.save()
                    return HttpResponse('Update for engagement ignored')
                else:
                    raise Http404(
                        'No finding or engagement found for JIRA issue {}'.
                        format(jissue.jira_key))

            if parsed.get('webhookEvent') == 'comment_created':
                """
                    example incoming requests from JIRA Server 8.14.0
                    {
                    "timestamp":1610269967824,
                    "webhookEvent":"comment_created",
                    "comment":{
                        "self":"https://jira.host.com/rest/api/2/issue/115254/comment/466578",
                        "id":"466578",
                        "author":{
                            "self":"https://jira.host.com/rest/api/2/user?username=defect.dojo",
                            "name":"defect.dojo",
                            "key":"defect.dojo", # seems to be only present on JIRA Server, not on Cloud
                            "avatarUrls":{
                                "48x48":"https://www.gravatar.com/avatar/9637bfb970eff6176357df615f548f1c?d=mm&s=48",
                                "24x24":"https://www.gravatar.com/avatar/9637bfb970eff6176357df615f548f1c?d=mm&s=24",
                                "16x16":"https://www.gravatar.com/avatar9637bfb970eff6176357df615f548f1c?d=mm&s=16",
                                "32x32":"https://www.gravatar.com/avatar/9637bfb970eff6176357df615f548f1c?d=mm&s=32"
                            },
                            "displayName":"Defect Dojo",
                            "active":true,
                            "timeZone":"Europe/Amsterdam"
                        },
                        "body":"(Valentijn Scholten):test4",
                        "updateAuthor":{
                            "self":"https://jira.host.com/rest/api/2/user?username=defect.dojo",
                            "name":"defect.dojo",
                            "key":"defect.dojo",
                            "avatarUrls":{
                                "48x48":"https://www.gravatar.com/avatar/9637bfb970eff6176357df615f548f1c?d=mm&s=48",
                                "24x24""https://www.gravatar.com/avatar/9637bfb970eff6176357df615f548f1c?d=mm&s=24",
                                "16x16":"https://www.gravatar.com/avatar/9637bfb970eff6176357df615f548f1c?d=mm&s=16",
                                "32x32":"https://www.gravatar.com/avatar/9637bfb970eff6176357df615f548f1c?d=mm&s=32"
                            },
                            "displayName":"Defect Dojo",
                            "active":true,
                            "timeZone":"Europe/Amsterdam"
                        },
                        "created":"2021-01-10T10:12:47.824+0100",
                        "updated":"2021-01-10T10:12:47.824+0100"
                    }
                    }
                """

                comment_text = parsed['comment']['body']
                commentor = ''
                if 'name' in parsed['comment']['updateAuthor']:
                    commentor = parsed['comment']['updateAuthor']['name']
                elif 'emailAddress' in parsed['comment']['updateAuthor']:
                    commentor = parsed['comment']['updateAuthor'][
                        'emailAddress']
                else:
                    logger.debug(
                        'Could not find the author of this jira comment!')
                commentor_display_name = parsed['comment']['updateAuthor'][
                    'displayName']
                # example: body['comment']['self'] = "http://www.testjira.com/jira_under_a_path/rest/api/2/issue/666/comment/456843"
                jid = parsed['comment']['self'].split('/')[-3]
                jissue = get_object_or_404(JIRA_Issue, jira_id=jid)
                logging.info("Received issue comment for {}".format(
                    jissue.jira_key))
                logger.debug('jissue: %s', vars(jissue))
                if jissue.finding:
                    # logger.debug('finding: %s', vars(jissue.finding))
                    jira_usernames = JIRA_Instance.objects.values_list(
                        'username', flat=True)
                    for jira_userid in jira_usernames:
                        # logger.debug('incoming username: %s jira config username: %s', commentor.lower(), jira_userid.lower())
                        if jira_userid.lower() == commentor.lower():
                            logger.debug(
                                'skipping incoming JIRA comment as the user id of the comment in JIRA (%s) matches the JIRA username in DefectDojo (%s)',
                                commentor.lower(), jira_userid.lower())
                            return HttpResponse('')
                            break
                    finding = jissue.finding
                    new_note = Notes()
                    new_note.entry = '(%s (%s)): %s' % (
                        commentor_display_name, commentor, comment_text)
                    new_note.author, created = User.objects.get_or_create(
                        username='******')
                    new_note.save()
                    finding.notes.add(new_note)
                    finding.jira_issue.jira_change = timezone.now()
                    finding.jira_issue.save()
                    finding.save()
                    create_notification(
                        event='other',
                        title='JIRA incoming comment - %s' % (jissue.finding),
                        url=reverse("view_finding",
                                    args=(jissue.finding.id, )),
                        icon='check')
                elif jissue.engagement:
                    return HttpResponse('Comment for engagement ignored')
                else:
                    raise Http404(
                        'No finding or engagement found for JIRA issue {}'.
                        format(jissue.jira_key))

            if parsed.get('webhookEvent') not in [
                    'comment_created', 'jira:issue_updated'
            ]:
                logger.info(
                    'Unrecognized JIRA webhook event received: {}'.format(
                        parsed.get('webhookEvent')))
        except Exception as e:
            if isinstance(e, Http404):
                logger.warning('404 error processing JIRA webhook')
            else:
                logger.exception(e)

            try:
                logger.debug('jira_webhook_body_parsed:')
                logger.debug(json.dumps(parsed, indent=4))
            except:
                logger.debug('jira_webhook_body:')
                logger.debug(request.body.decode('utf-8'))

            # reraise to make sure we don't silently swallow things
            raise
    return HttpResponse('')
Exemplo n.º 18
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,
        })
Exemplo n.º 19
0
class OpenFindingFilter(DojoFilter):
    title = CharFilter(lookup_expr='icontains')
    duplicate = ReportBooleanFilter()
    # sourcefile = CharFilter(lookup_expr='icontains')
    sourcefilepath = CharFilter(lookup_expr='icontains')
    param = CharFilter(lookup_expr='icontains')
    payload = CharFilter(lookup_expr='icontains')
    date = DateRangeFilter()
    last_reviewed = DateRangeFilter()
    cwe = MultipleChoiceFilter(choices=[])
    severity = MultipleChoiceFilter(choices=SEVERITY_CHOICES)
    test__test_type = ModelMultipleChoiceFilter(
        queryset=Test_Type.objects.all())
    test__engagement__product = ModelMultipleChoiceFilter(
        queryset=Product.objects.all(), label="Product")
    test__engagement__risk_acceptance = ReportRiskAcceptanceFilter(
        label="Risk Accepted")

    if get_system_setting('enable_jira'):
        jira_issue = BooleanFilter(field_name='jira_issue',
                                   lookup_expr='isnull',
                                   exclude=True,
                                   label='JIRA issue')

    o = OrderingFilter(
        # tuple-mapping retains order
        fields=(
            ('numerical_severity', 'numerical_severity'),
            ('date', 'date'),
            ('last_reviewed', 'last_reviewed'),
            ('title', 'title'),
            ('test__engagement__product__name',
             'test__engagement__product__name'),
        ), )

    class Meta:
        model = Finding
        exclude = [
            'url', 'description', 'mitigation', 'impact', 'endpoint',
            'references', 'test', 'is_template', 'thread_id', 'notes',
            'scanner_confidence', 'mitigated', 'numerical_severity',
            'reporter', 'last_reviewed', 'line', 'duplicate_finding',
            'hash_code', 'images', 'line_number', 'reviewers', 'mitigated_by',
            'sourcefile', 'jira_creation', 'jira_change', 'created'
        ]

    def __init__(self, *args, **kwargs):
        self.user = None
        self.pid = None
        if 'user' in kwargs:
            self.user = kwargs.pop('user')

        if 'pid' in kwargs:
            self.pid = kwargs.pop('pid')
        super(OpenFindingFilter, self).__init__(*args, **kwargs)

        cwe = dict()
        cwe = dict(
            [cwe, cwe]
            for cwe in self.queryset.values_list('cwe', flat=True).distinct()
            if type(cwe) is int and cwe is not None and cwe > 0)
        cwe = collections.OrderedDict(sorted(cwe.items()))
        self.form.fields['cwe'].choices = list(cwe.items())
        if self.user is not None and not self.user.is_staff:
            if self.form.fields.get('test__engagement__product'):
                qs = Product.objects.filter(authorized_users__in=[self.user])
                self.form.fields['test__engagement__product'].queryset = qs
            self.form.fields['endpoints'].queryset = Endpoint.objects.filter(
                product__authorized_users__in=[self.user]).distinct()

        # Don't show the product filter on the product finding view
        if self.pid:
            del self.form.fields['test__engagement__product']
Exemplo n.º 20
0
def generate_report(request, obj):
    user = Dojo_User.objects.get(id=request.user.id)
    product_type = None
    product = None
    engagement = None
    test = None
    endpoint = None
    endpoints = None
    endpoint_all_findings = None
    endpoint_monthly_counts = None
    endpoint_active_findings = None
    accepted_findings = None
    open_findings = None
    closed_findings = None
    verified_findings = None
    report_title = None
    report_subtitle = None
    report_info = "Generated By %s on %s" % (
        user.get_full_name(), (timezone.now().strftime("%m/%d/%Y %I:%M%p %Z")))

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

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

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

        end_date = timezone.now()

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

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

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

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

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

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

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

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

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

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

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

    report_form = ReportOptionsForm()

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

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

            return HttpResponseRedirect(reverse('reports'))

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

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

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

    return render(request, 'dojo/request_report.html',
                  {'product_type': product_type,
                   'product': product,
                   'product_tab': product_tab,
                   'engagement': engagement,
                   'test': test,
                   'endpoint': endpoint,
                   'findings': findings,
                   'paged_findings': paged_findings,
                   'report_form': report_form,
                   })
Exemplo n.º 21
0
    # if public=False, includes only endpoints the current user has access to
    public=True,
    # The API of a OpenSource project should be public accessible
    permission_classes=[permissions.AllowAny],
)

urlpatterns = [
    # These are the SAML2 related URLs. You can change "^saml2_auth/" regex to
    # any path you want, like "^sso_auth/", "^sso_login/", etc. (required)
    url(r'^saml2/', include('django_saml2_auth.urls')),
    # The following line will replace the default user login with SAML2 (optional)
    # If you want to specific the after-login-redirect-URL, use parameter "?next=/the/path/you/want"
    # with this view.
    url(r'^saml2/login/$', django_saml2_auth.views.signin),
    #  tastypie api
    url(r'^%sapi/' % get_system_setting('url_prefix'), include(v1_api.urls)),
    #  Django Rest Framework API v2
    url(r'^%sapi/v2/' % get_system_setting('url_prefix'), include(v2_api.urls)),
    # api doc urls
    url(r'%sapi/v1/doc/' % get_system_setting('url_prefix'),
        include((swagger_urls, 'tp_s'), namespace='tastypie_swagger'),
        kwargs={
            "tastypie_api_module": "dojo.urls.v1_api",
            "namespace": "tastypie_swagger",
            "version": "1.0"}),
    # action history
    url(r'^%shistory/(?P<cid>\d+)/(?P<oid>\d+)$' % get_system_setting('url_prefix'), views.action_history,
        name='action_history'),
    url(r'^%s' % get_system_setting('url_prefix'), include(ur)),
    url(r'^%sapi/v2/api-token-auth/' % get_system_setting('url_prefix'), tokenviews.obtain_auth_token),
    url(r'^%sapi/v2/doc/' % get_system_setting('url_prefix'), schema_view.with_ui('swagger', cache_timeout=0), name='api_v2_schema'),
Exemplo n.º 22
0
ur += notifications_urls

from tastypie_swagger.views import SwaggerView, ResourcesView, SchemaView

swagger_urls = [
    url(r'^$', SwaggerView.as_view(), name='index'),
    url(r'^resources/$', ResourcesView.as_view(), name='resources'),
    url(r'^schema/(?P<resource>\S+)$', SchemaView.as_view()),
    url(r'^schema/$', SchemaView.as_view(), name='schema'),
]



urlpatterns = [
    #  django admin
    url(r'^%sadmin/' % get_system_setting('url_prefix'), include(admin.site.urls)),
    #  tastypie api
    url(r'^%sapi/' % get_system_setting('url_prefix'), include(v1_api.urls)),
    # api doc urls
    url(r'%sapi/v1/doc/' % get_system_setting('url_prefix'),
        include(swagger_urls, namespace='tastypie_swagger'),
        kwargs={
            "tastypie_api_module": "dojo.urls.v1_api",
            "namespace": "tastypie_swagger",
            "version": "1.0"}),
    # action history
    url(r'^%shistory/(?P<cid>\d+)/(?P<oid>\d+)$' % get_system_setting('url_prefix'), views.action_history,
        name='action_history'),
    url(r'^%s' % get_system_setting('url_prefix'), include(ur)),
]
def promote_to_finding(request, fid):
    finding = get_object_or_404(Stub_Finding, id=fid)
    test = finding.test
    form_error = False
    jira_available = False

    if get_system_setting('enable_jira') and JIRA_PKey.objects.filter(product=test.engagement.product) != 0:
        jform = JIRAFindingForm(request.POST, prefix='jiraform',
                                enabled=JIRA_PKey.objects.get(product=test.engagement.product).push_all_issues)
        jira_available = True
    else:
        jform = None
        
    form = PromoteFindingForm(initial={'title': finding.title,
                                       'date': finding.date,
                                       'severity': finding.severity,
                                       'description': finding.description,
                                       'test': finding.test,
                                       'reporter': finding.reporter})
    if request.method == 'POST':
        form = PromoteFindingForm(request.POST)
        if form.is_valid():
            new_finding = form.save(commit=False)
            new_finding.test = test
            new_finding.reporter = request.user
            new_finding.numerical_severity = Finding.get_numerical_severity(
                new_finding.severity)

            new_finding.active = True
            new_finding.false_p = False
            new_finding.duplicate = False
            new_finding.mitigated = None
            new_finding.verified = True
            new_finding.out_of_scope = False

            new_finding.save()
            new_finding.endpoints = form.cleaned_data['endpoints']
            new_finding.save()

            finding.delete()
            if 'jiraform' in request.POST:
                jform = JIRAFindingForm(request.POST, prefix='jiraform',
                                        enabled=JIRA_PKey.objects.get(product=test.engagement.product).push_all_issues)
                if jform.is_valid():
                    add_issue_task.delay(new_finding, jform.cleaned_data.get('push_to_jira'))

            messages.add_message(request,
                                 messages.SUCCESS,
                                 'Finding promoted successfully.',
                                 extra_tags='alert-success')

            return HttpResponseRedirect(reverse('view_test', args=(test.id,)))
        else:
            if 'endpoints' in form.cleaned_data:
                form.fields['endpoints'].queryset = form.cleaned_data['endpoints']
            else:
                form.fields['endpoints'].queryset = Endpoint.objects.none()
            form_error = True
            messages.add_message(request,
                                 messages.ERROR,
                                 'The form has errors, please correct them below.',
                                 extra_tags='alert-danger')
    add_breadcrumb(parent=test, title="Promote Finding", top_level=False, request=request)
    return render(request, 'dojo/promote_to_finding.html',
                  {'form': form,
                   'test': test,
                   'stub_finding': finding,
                   'form_error': form_error,
                   })
def edit_finding(request, fid):
    finding = get_object_or_404(Finding, id=fid)
    old_status = finding.status()
    form = FindingForm(instance=finding)
    form.initial['tags'] = [tag.name for tag in finding.tags]
    form_error = False
    jform = None
    try:
        jissue = JIRA_Issue.objects.get(finding=finding)
        enabled = True
    except:
        enabled = False
        pass

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

    if request.method == 'POST':
        form = FindingForm(request.POST, instance=finding)
        if form.is_valid():
            new_finding = form.save(commit=False)
            new_finding.test = finding.test
            new_finding.numerical_severity = Finding.get_numerical_severity(
                new_finding.severity)
            if new_finding.false_p or new_finding.active is False:
                new_finding.mitigated = timezone.now()
                new_finding.mitigated_by = request.user
            if new_finding.active is True:
                new_finding.false_p = False
                new_finding.mitigated = None
                new_finding.mitigated_by = None

            create_template = new_finding.is_template
            # always false now since this will be deprecated soon in favor of new Finding_Template model
            new_finding.is_template = False
            new_finding.endpoints = form.cleaned_data['endpoints']
            new_finding.last_reviewed = timezone.now()
            new_finding.last_reviewed_by = request.user
            tags = request.POST.getlist('tags')
            t = ", ".join(tags)
            new_finding.tags = t
            new_finding.save()
            if 'jiraform-push_to_jira' in request.POST:
                jform = JIRAFindingForm(request.POST, prefix='jiraform', enabled=enabled)
                if jform.is_valid():
                    try:
                        jissue = JIRA_Issue.objects.get(finding=new_finding)
                        update_issue_task.delay(new_finding, old_status, jform.cleaned_data.get('push_to_jira'))
                    except:
                        add_issue_task.delay(new_finding, jform.cleaned_data.get('push_to_jira'))
                        pass
            tags = request.POST.getlist('tags')
            t = ", ".join(tags)
            new_finding.tags = t

            messages.add_message(request,
                                 messages.SUCCESS,
                                 'Finding saved successfully.',
                                 extra_tags='alert-success')
            if create_template:
                templates = Finding_Template.objects.filter(title=new_finding.title)
                if len(templates) > 0:
                    messages.add_message(request,
                                         messages.ERROR,
                                         'A finding template was not created.  A template with this title already '
                                         'exists.',
                                         extra_tags='alert-danger')
                else:
                    template = Finding_Template(title=new_finding.title,
                                                cwe=new_finding.cwe,
                                                severity=new_finding.severity,
                                                description=new_finding.description,
                                                mitigation=new_finding.mitigation,
                                                impact=new_finding.impact,
                                                references=new_finding.references,
                                                numerical_severity=new_finding.numerical_severity)
                    template.save()
                    messages.add_message(request,
                                         messages.SUCCESS,
                                         'A finding template was also created.',
                                         extra_tags='alert-success')
            return HttpResponseRedirect(reverse('view_finding', args=(new_finding.id,)))
        else:
            messages.add_message(request,
                                 messages.ERROR,
                                 'There appears to be errors on the form, please correct below.',
                                 extra_tags='alert-danger')
            form_error = True

    if form_error and 'endpoints' in form.cleaned_data:
        form.fields['endpoints'].queryset = form.cleaned_data['endpoints']
    else:
        form.fields['endpoints'].queryset = finding.endpoints.all()
    form.initial['tags'] = [tag.name for tag in finding.tags]
    add_breadcrumb(parent=finding, title="Edit", top_level=False, request=request)
    return render(request, 'dojo/edit_findings.html',
                  {'form': form,
                   'finding': finding,
                   'jform' : jform
                   })
Exemplo n.º 25
0
def send_slack_notification(event, user=None, *args, **kwargs):
    from dojo.utils import get_system_setting

    def _post_slack_message(channel):
        res = requests.request(method='POST',
                               url='https://slack.com/api/chat.postMessage',
                               data={
                                   'token':
                                   get_system_setting('slack_token'),
                                   'channel':
                                   channel,
                                   'username':
                                   get_system_setting('slack_username'),
                                   'text':
                                   create_notification_message(
                                       event, user, 'slack', *args, **kwargs)
                               })

        if 'error' in res.text:
            logger.error("Slack is complaining. See raw text below.")
            logger.error(res.text)
            raise RuntimeError('Error posting message to Slack: ' + res.text)

    try:
        # If the user has slack information on profile and chooses to receive slack notifications
        # Will receive a DM
        if user is not None:
            logger.debug('personal notification to slack for user %s', user)
            if hasattr(user, 'usercontactinfo'
                       ) and user.usercontactinfo.slack_username is not None:
                slack_user_id = user.usercontactinfo.slack_user_id
                if not slack_user_id:
                    # Lookup the slack userid the first time, then save it.
                    slack_user_id = get_slack_user_id(
                        user.usercontactinfo.slack_username)

                    if slack_user_id:
                        slack_user_save = UserContactInfo.objects.get(
                            user_id=user.id)
                        slack_user_save.slack_user_id = slack_user_id
                        slack_user_save.save()

                # only send notification if we managed to find the slack_user_id
                if slack_user_id:
                    channel = '@{}'.format(slack_user_id)
                    _post_slack_message(channel)
            else:
                logger.info(
                    "The user %s does not have a email address informed for Slack in profile.",
                    user)
        else:
            # System scope slack notifications, and not personal would still see this go through
            if get_system_setting('slack_channel') is not None:
                channel = get_system_setting('slack_channel')
                logger.info(
                    "Sending system notification to system channel {}.".format(
                        channel))
                _post_slack_message(channel)
            else:
                logger.debug(
                    'slack_channel not configured: skipping system notification'
                )

    except Exception as e:
        logger.exception(e)
        log_alert(e,
                  'Slack Notification',
                  title=kwargs['title'],
                  description=str(e),
                  url=kwargs['url'])
Exemplo n.º 26
0
def fetch_system_setting(name):
    return get_system_setting(name)
Exemplo n.º 27
0
def edit_engagement(request, eid):
    eng = Engagement.objects.get(pk=eid)
    ci_cd_form = False
    if eng.engagement_type == "CI/CD":
        ci_cd_form = True
    jform = None
    if request.method == 'POST':
        form = EngForm(request.POST, instance=eng, cicd=ci_cd_form, product=eng.product.id)
        if 'jiraform-push_to_jira' in request.POST:
            jform = JIRAFindingForm(
                request.POST, prefix='jiraform', enabled=True)

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

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

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

    title = ""
    if eng.engagement_type == "CI/CD":
        title = " CI/CD"
    product_tab = Product_Tab(eng.product.id, title="Edit" + title + " Engagement", tab="engagements")
    product_tab.setEngagement(eng)
    return render(request, 'dojo/new_eng.html', {
        'product_tab': product_tab,
        'form': form,
        'edit': True,
        'jform': jform,
        'eng': eng
    })
Exemplo n.º 28
0
def edit_product(request, pid):
    prod = Product.objects.get(pk=pid)
    system_settings = System_Settings.objects.get()
    jira_enabled = system_settings.enable_jira
    jira_inst = None
    jform = None
    try:
        jira_inst = JIRA_PKey.objects.get(product=prod)
    except:
        jira_inst = None
        pass
    if request.method == 'POST':
        form = ProductForm(request.POST, instance=prod)
        if form.is_valid():
            form.save()
            tags = request.POST.getlist('tags')
            t = ", ".join(tags)
            prod.tags = t
            messages.add_message(request,
                                 messages.SUCCESS,
                                 'Product updated successfully.',
                                 extra_tags='alert-success')

            if get_system_setting('enable_jira') and jira_inst:
                jform = JIRAPKeyForm(request.POST, instance=jira_inst)
                # need to handle delete
                try:
                    jform.save()
                except:
                    pass
            elif get_system_setting('enable_jira'):
                jform = JIRAPKeyForm(request.POST)
                if jform.is_valid():
                    new_conf = jform.save(commit=False)
                    new_conf.product_id = pid
                    new_conf.save()
                    messages.add_message(request,
                                            messages.SUCCESS,
                                            'JIRA information updated successfully.',
                                            extra_tags='alert-success')

            return HttpResponseRedirect(reverse('view_product', args=(pid,)))
    else:
        form = ProductForm(instance=prod,
                           initial={'auth_users': prod.authorized_users.all(),
                                    'tags': get_tag_list(Tag.objects.get_for_object(prod))})

        if jira_enabled and (jira_inst is not None):
            if jira_inst is not None:
                jform = JIRAPKeyForm(instance=jira_inst)
            else:
                jform = JIRAPKeyForm()
        elif jira_enabled:
            jform = JIRAPKeyForm()
        else:
            jform = None
    form.initial['tags'] = [tag.name for tag in prod.tags]
    product_tab = Product_Tab(pid, title="Edit Product", tab="settings")
    return render(request,
                  'dojo/edit_product.html',
                  {'form': form,
                   'product_tab': product_tab,
                   'jform': jform,
                   'product': prod
                   })
Exemplo n.º 29
0
ur += object_urls

from tastypie_swagger.views import SwaggerView, ResourcesView, SchemaView

swagger_urls = [
    url(r'^$', SwaggerView.as_view(), name='index'),
    url(r'^resources/$', ResourcesView.as_view(), name='resources'),
    url(r'^schema/(?P<resource>\S+)$', SchemaView.as_view()),
    url(r'^schema/$', SchemaView.as_view(), name='schema'),
]



urlpatterns = [
    #  django admin
    url(r'^%sadmin/' % get_system_setting('url_prefix'), include(admin.site.urls)),
    #  tastypie api
    url(r'^%sapi/' % get_system_setting('url_prefix'), include(v1_api.urls)),
    # api doc urls
    url(r'%sapi/v1/doc/' % get_system_setting('url_prefix'),
        include(swagger_urls, namespace='tastypie_swagger'),
        kwargs={
            "tastypie_api_module": "dojo.urls.v1_api",
            "namespace": "tastypie_swagger",
            "version": "1.0"}),
    # action history
    url(r'^%shistory/(?P<cid>\d+)/(?P<oid>\d+)$' % get_system_setting('url_prefix'), views.action_history,
        name='action_history'),
    url(r'^%s' % get_system_setting('url_prefix'), include(ur)),
]
Exemplo n.º 30
0
ur += tool_product_urls
ur += cred_urls
ur += system_settings_urls

from tastypie_swagger.views import SwaggerView, ResourcesView, SchemaView

swagger_urls = [
    url(r'^$', SwaggerView.as_view(), name='index'),
    url(r'^resources/$', ResourcesView.as_view(), name='resources'),
    url(r'^schema/(?P<resource>\S+)$', SchemaView.as_view()),
    url(r'^schema/$', SchemaView.as_view(), name='schema'),
]

urlpatterns = [
    #  django admin
    url(r'^%sadmin/' % get_system_setting('url_prefix'),
        include(admin.site.urls)),
    #  tastypie api
    url(r'^%sapi/' % get_system_setting('url_prefix'), include(v1_api.urls)),
    # api doc urls
    url(r'%sapi/v1/doc/' % get_system_setting('url_prefix'),
        include(swagger_urls, namespace='tastypie_swagger'),
        kwargs={
            "tastypie_api_module": "dojo.urls.v1_api",
            "namespace": "tastypie_swagger",
            "version": "1.0"
        }),
    # action history
    url(r'^%shistory/(?P<cid>\d+)/(?P<oid>\d+)$' %
        get_system_setting('url_prefix'),
        views.action_history,
Exemplo n.º 31
0
def edit_product(request, pid):
    prod = Product.objects.get(pk=pid)
    system_settings = System_Settings.objects.get()
    jira_enabled = system_settings.enable_jira
    jira_inst = None
    jform = None
    sonarqube_form = None
    try:
        jira_inst = JIRA_PKey.objects.get(product=prod)
    except:
        jira_inst = None
        pass

    sonarqube_conf = Sonarqube_Product.objects.filter(product=prod).first()

    if request.method == 'POST':
        form = ProductForm(request.POST, instance=prod)
        if form.is_valid():
            form.save()
            tags = request.POST.getlist('tags')
            t = ", ".join('"{0}"'.format(w) for w in tags)
            prod.tags = t
            messages.add_message(request,
                                 messages.SUCCESS,
                                 'Product updated successfully.',
                                 extra_tags='alert-success')

            if get_system_setting('enable_jira') and jira_inst:
                jform = JIRAPKeyForm(request.POST, instance=jira_inst)
                # need to handle delete
                try:
                    jform.save()
                except:
                    pass
            elif get_system_setting('enable_jira'):
                jform = JIRAPKeyForm(request.POST)
                if jform.is_valid():
                    new_conf = jform.save(commit=False)
                    new_conf.product_id = pid
                    new_conf.save()
                    messages.add_message(
                        request,
                        messages.SUCCESS,
                        'JIRA information updated successfully.',
                        extra_tags='alert-success')

            # SonarQube API Configuration
            sonarqube_form = Sonarqube_ProductForm(request.POST,
                                                   instance=sonarqube_conf)
            if sonarqube_form.is_valid():
                new_conf = sonarqube_form.save(commit=False)
                new_conf.product_id = pid
                new_conf.save()

            return HttpResponseRedirect(reverse('view_product', args=(pid, )))
    else:
        form = ProductForm(instance=prod,
                           initial={
                               'auth_users':
                               prod.authorized_users.all(),
                               'tags':
                               get_tag_list(Tag.objects.get_for_object(prod))
                           })

        if jira_enabled and (jira_inst is not None):
            if jira_inst is not None:
                jform = JIRAPKeyForm(instance=jira_inst)
            else:
                jform = JIRAPKeyForm()
        elif jira_enabled:
            jform = JIRAPKeyForm()
        else:
            jform = None

        sonarqube_form = Sonarqube_ProductForm(instance=sonarqube_conf)

    form.initial['tags'] = [tag.name for tag in prod.tags]
    product_tab = Product_Tab(pid, title="Edit Product", tab="settings")
    return render(
        request, 'dojo/edit_product.html', {
            'form': form,
            'product_tab': product_tab,
            'jform': jform,
            'sonarqube_form': sonarqube_form,
            'product': prod
        })
Exemplo n.º 32
0
def webhook(request):
    # Webhook shouldn't be active if jira isn't enabled
    if not get_system_setting('enable_jira'):
        raise PermissionDenied
    elif not get_system_setting('enable_jira_web_hook'):
        raise PermissionDenied

    if request.method == 'POST':
        parsed = json.loads(request.body.decode('utf-8'))
        if parsed.get('webhookEvent') == 'jira:issue_updated':
            jid = parsed['issue']['id']
            jissue = get_object_or_404(JIRA_Issue, jira_id=jid)
            if jissue.finding is not None:
                finding = jissue.finding
                jira_conf = finding.jira_conf()
                resolved = True
                resolution = parsed['issue']['fields']['resolution']
                if resolution is None:
                    resolved = False
                if finding.active == resolved:
                    if finding.active:
                        if jira_conf and resolution['name'] in jira_conf.accepted_resolutions:
                            finding.active = False
                            finding.mitigated = None
                            finding.is_Mitigated = False
                            finding.false_p = False
                            assignee = parsed['issue']['fields'].get('assignee')
                            assignee_name = assignee['name'] if assignee else None
                            Risk_Acceptance.objects.create(
                                accepted_by=assignee_name,
                                reporter=finding.reporter,
                            ).accepted_findings.set([finding])
                        elif jira_conf and resolution['name'] in jira_conf.false_positive_resolutions:
                            finding.active = False
                            finding.verified = False
                            finding.mitigated = None
                            finding.is_Mitigated = False
                            finding.false_p = True
                            finding.remove_from_any_risk_acceptance()
                        else:
                            # Mitigated by default as before
                            now = timezone.now()
                            finding.active = False
                            finding.mitigated = now
                            finding.endpoints.clear()
                            finding.false_p = False
                            finding.remove_from_any_risk_acceptance()
                    else:
                        # Reopen / Open Jira issue
                        finding.active = True
                        finding.mitigated = None
                        finding.is_Mitigated = False
                        finding.false_p = False
                        finding.remove_from_any_risk_acceptance()
                    finding.jira_change = timezone.now()
                    finding.save()
            """
            if jissue.engagement is not None:
                eng = jissue.engagement
                if parsed['issue']['fields']['resolution'] != None:
                    eng.active = False
                    eng.status = 'Completed'
                    eng.save()
           """
        if parsed.get('webhookEvent') == 'comment_created':
            comment_text = parsed['comment']['body']
            commentor = parsed['comment']['updateAuthor']['displayName']
            jid = parsed['comment']['self'].split('/')[7]
            jissue = JIRA_Issue.objects.get(jira_id=jid)
            finding = jissue.finding
            new_note = Notes()
            new_note.entry = '(%s): %s' % (commentor, comment_text)
            new_note.author, created = User.objects.get_or_create(username='******')
            new_note.save()
            finding.notes.add(new_note)
            finding.jira_change = timezone.now()
            finding.save()

        if parsed.get('webhookEvent') not in ['comment_created', 'jira:issue_updated']:
            logger.info('Unrecognized JIRA webhook event received: {}'.format(parsed.get('webhookEvent')))
    return HttpResponse('')
def is_jira_enabled():
    if not get_system_setting('enable_jira'):
        logger.debug('JIRA is disabled, not doing anything')
        return False

    return True
Exemplo n.º 34
0
from pytz import timezone

from dojo.celery import app
from dojo.endpoint.views import get_endpoint_ids
from dojo.filters import ReportFindingFilter, ReportAuthedFindingFilter, EndpointReportFilter, ReportFilter, \
    EndpointFilter
from dojo.forms import ReportOptionsForm, DeleteReportForm
from dojo.models import Product_Type, Finding, Product, Engagement, Test, \
    Dojo_User, Endpoint, Report, Risk_Acceptance
from dojo.reports.widgets import CoverPage, PageBreak, TableOfContents, WYSIWYGContent, FindingList, EndpointList, \
    CustomReportJsonForm, ReportOptions, report_widget_factory
from dojo.tasks import async_pdf_report, async_custom_pdf_report
from dojo.utils import get_page_items, add_breadcrumb, get_period_counts, get_system_setting
from dojo.utils import get_period_counts_legacy

localtz = timezone(get_system_setting('time_zone'))

logging.basicConfig(
    level=logging.DEBUG,
    format='[%(asctime)s] %(levelname)s [%(name)s:%(lineno)d] %(message)s',
    datefmt='%d/%b/%Y %H:%M:%S',
    filename=settings.DOJO_ROOT + '/../django_app.log',
)
logger = logging.getLogger(__name__)


def report_url_resolver(request):
    try:
        url_resolver = request.META[
            'HTTP_X_FORWARDED_PROTO'] + "://" + request.META[
                'HTTP_X_FORWARDED_FOR']
Exemplo n.º 35
0
def edit_engagement(request, eid):
    eng = Engagement.objects.get(pk=eid)
    ci_cd_form = False
    if eng.engagement_type == "CI/CD":
        ci_cd_form = True
    jform = None
    if request.method == 'POST':
        form = EngForm(request.POST,
                       instance=eng,
                       cicd=ci_cd_form,
                       product=eng.product.id)
        if 'jiraform-push_to_jira' in request.POST:
            jform = JIRAFindingForm(request.POST,
                                    prefix='jiraform',
                                    enabled=True)

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

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

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

    title = ""
    if eng.engagement_type == "CI/CD":
        title = " CI/CD"
    product_tab = Product_Tab(eng.product.id,
                              title="Edit" + title + " Engagement",
                              tab="engagements")
    product_tab.setEngagement(eng)
    return render(
        request, 'dojo/new_eng.html', {
            'product_tab': product_tab,
            'form': form,
            'edit': True,
            'jform': jform,
            'eng': eng
        })
Exemplo n.º 36
0
def new_eng_for_app(request, pid, cicd=False):
    jform = None
    prod = Product.objects.get(id=pid)
    if request.method == 'POST':
        form = EngForm(request.POST, cicd=cicd)
        if form.is_valid():
            new_eng = form.save(commit=False)
            if not new_eng.name:
                new_eng.name = str(new_eng.target_start)
            new_eng.threat_model = False
            new_eng.api_test = False
            new_eng.pen_test = False
            new_eng.check_list = False
            new_eng.product_id = form.cleaned_data.get('product').id
            if new_eng.threat_model:
                new_eng.progress = 'threat_model'
            else:
                new_eng.progress = 'other'
            if cicd:
                new_eng.engagement_type = 'CI/CD'
                new_eng.status = "In Progress"

            new_eng.save()
            tags = request.POST.getlist('tags')
            t = ", ".join('"{0}"'.format(w) for w in tags)
            new_eng.tags = t
            if get_system_setting('enable_jira'):
                # Test to make sure there is a Jira project associated the product
                try:
                    jform = JIRAFindingForm(request.POST,
                                            prefix='jiraform',
                                            enabled=JIRA_PKey.objects.get(
                                                product=prod).push_all_issues)
                    if jform.is_valid():
                        add_epic_task.delay(
                            new_eng, jform.cleaned_data.get('push_to_jira'))
                except JIRA_PKey.DoesNotExist:
                    pass

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

            create_notification(event='engagement_added',
                                title=new_eng.name + " for " + prod.name,
                                engagement=new_eng,
                                url=reverse('view_engagement',
                                            args=(new_eng.id, )),
                                objowner=new_eng.lead)

            if "_Add Tests" in request.POST:
                return HttpResponseRedirect(
                    reverse('add_tests', args=(new_eng.id, )))
            elif "_Import Scan Results" in request.POST:
                return HttpResponseRedirect(
                    reverse('import_scan_results', args=(new_eng.id, )))
            else:
                return HttpResponseRedirect(
                    reverse('view_engagement', args=(new_eng.id, )))
    else:
        form = EngForm(initial={
            'lead': request.user,
            'target_start': timezone.now().date(),
            'target_end': timezone.now().date() + timedelta(days=7),
            'product': prod.id
        },
                       cicd=cicd,
                       product=prod.id)
        if (get_system_setting('enable_jira')):
            if JIRA_PKey.objects.filter(product=prod).count() != 0:
                jform = JIRAFindingForm(prefix='jiraform',
                                        enabled=JIRA_PKey.objects.get(
                                            product=prod).push_all_issues)

    product_tab = Product_Tab(pid, title="New Engagement", tab="engagements")
    return render(request, 'dojo/new_eng.html', {
        'form': form,
        'pid': pid,
        'product_tab': product_tab,
        'jform': jform
    })
Exemplo n.º 37
0
def edit_finding(request, fid):
    finding = get_object_or_404(Finding, id=fid)
    old_status = finding.status()
    form = FindingForm(instance=finding)
    form.initial['tags'] = [tag.name for tag in finding.tags]
    form_error = False
    jform = None
    try:
        jissue = JIRA_Issue.objects.get(finding=finding)
        enabled = True
    except:
        enabled = False
        pass

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

    if request.method == 'POST':
        form = FindingForm(request.POST, instance=finding)
        if form.is_valid():
            new_finding = form.save(commit=False)
            new_finding.test = finding.test
            new_finding.numerical_severity = Finding.get_numerical_severity(
                new_finding.severity)
            if new_finding.false_p or new_finding.active is False:
                new_finding.mitigated = timezone.now()
                new_finding.mitigated_by = request.user
            if new_finding.active is True:
                new_finding.false_p = False
                new_finding.mitigated = None
                new_finding.mitigated_by = None

            create_template = new_finding.is_template
            # always false now since this will be deprecated soon in favor of new Finding_Template model
            new_finding.is_template = False
            new_finding.endpoints = form.cleaned_data['endpoints']
            new_finding.last_reviewed = timezone.now()
            new_finding.last_reviewed_by = request.user
            tags = request.POST.getlist('tags')
            t = ", ".join(tags)
            new_finding.tags = t
            new_finding.save()
            if 'jiraform-push_to_jira' in request.POST:
                jform = JIRAFindingForm(request.POST, prefix='jiraform', enabled=enabled)
                if jform.is_valid():
                    try:
                        jissue = JIRA_Issue.objects.get(finding=new_finding)
                        update_issue_task.delay(new_finding, old_status, jform.cleaned_data.get('push_to_jira'))
                    except:
                        add_issue_task.delay(new_finding, jform.cleaned_data.get('push_to_jira'))
                        pass
            tags = request.POST.getlist('tags')
            t = ", ".join(tags)
            new_finding.tags = t

            messages.add_message(request,
                                 messages.SUCCESS,
                                 'Finding saved successfully.',
                                 extra_tags='alert-success')
            if create_template:
                templates = Finding_Template.objects.filter(title=new_finding.title)
                if len(templates) > 0:
                    messages.add_message(request,
                                         messages.ERROR,
                                         'A finding template was not created.  A template with this title already '
                                         'exists.',
                                         extra_tags='alert-danger')
                else:
                    template = Finding_Template(title=new_finding.title,
                                                cwe=new_finding.cwe,
                                                severity=new_finding.severity,
                                                description=new_finding.description,
                                                mitigation=new_finding.mitigation,
                                                impact=new_finding.impact,
                                                references=new_finding.references,
                                                numerical_severity=new_finding.numerical_severity)
                    template.save()
                    messages.add_message(request,
                                         messages.SUCCESS,
                                         'A finding template was also created.',
                                         extra_tags='alert-success')
            return HttpResponseRedirect(reverse('view_finding', args=(new_finding.id,)))
        else:
            messages.add_message(request,
                                 messages.ERROR,
                                 'There appears to be errors on the form, please correct below.',
                                 extra_tags='alert-danger')
            form_error = True

    if form_error and 'endpoints' in form.cleaned_data:
        form.fields['endpoints'].queryset = form.cleaned_data['endpoints']
    else:
        form.fields['endpoints'].queryset = finding.endpoints.all()
    form.initial['tags'] = [tag.name for tag in finding.tags]
    add_breadcrumb(parent=finding, title="Edit", top_level=False, request=request)
    return render(request, 'dojo/edit_findings.html',
                  {'form': form,
                   'finding': finding,
                   'jform' : jform
                   })
Exemplo n.º 38
0
def edit_engagement(request, eid):
    engagement = Engagement.objects.get(pk=eid)
    is_ci_cd = engagement.engagement_type == "CI/CD"
    jira_epic_form = None
    jira_project = None
    jira_error = False

    if request.method == 'POST':
        form = EngForm(request.POST,
                       instance=engagement,
                       cicd=is_ci_cd,
                       product=engagement.product.id,
                       user=request.user)
        jira_project = jira_helper.get_jira_project(engagement,
                                                    use_inheritance=False)

        if form.is_valid():
            # first save engagement details
            new_status = form.cleaned_data.get('status')
            engagement = form.save(commit=False)
            if (new_status == "Cancelled" or new_status == "Completed"):
                engagement.active = False
            else:
                engagement.active = True
            engagement.save()

            tags = request.POST.getlist('tags')
            t = ", ".join('"{0}"'.format(w) for w in tags)
            engagement.tags = t

            messages.add_message(request,
                                 messages.SUCCESS,
                                 'Engagement updated successfully.',
                                 extra_tags='alert-success')

            success, jira_project_form = jira_helper.process_jira_project_form(
                request, instance=jira_project, engagement=engagement)
            error = not success

            success, jira_epic_form = jira_helper.process_jira_epic_form(
                request, engagement=engagement)
            error = error or not success

            if not error:
                if '_Add Tests' in request.POST:
                    return HttpResponseRedirect(
                        reverse('add_tests', args=(engagement.id, )))
                else:
                    return HttpResponseRedirect(
                        reverse('view_engagement', args=(engagement.id, )))
        else:
            logger.debug(form.errors)

    form = EngForm(initial={'product': engagement.product},
                   instance=engagement,
                   cicd=is_ci_cd,
                   product=engagement.product,
                   user=request.user)

    jira_project_form = None
    jira_epic_form = None
    if get_system_setting('enable_jira'):
        jira_project = jira_helper.get_jira_project(engagement,
                                                    use_inheritance=False)
        jira_project_form = JIRAProjectForm(instance=jira_project,
                                            target='engagement',
                                            product=engagement.product)
        logger.debug('showing jira-epic-form')
        jira_epic_form = JIRAEngagementForm(instance=engagement)

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

    title = ' CI/CD' if is_ci_cd else ''
    product_tab = Product_Tab(engagement.product.id,
                              title="Edit" + title + " Engagement",
                              tab="engagements")
    product_tab.setEngagement(engagement)
    return render(
        request, 'dojo/new_eng.html', {
            'product_tab': product_tab,
            'form': form,
            'edit': True,
            'jira_epic_form': jira_epic_form,
            'jira_project_form': jira_project_form,
            'engagement': engagement,
        })
Exemplo n.º 39
0
schema_view = get_schema_view(
    openapi.Info(
        title="Defect Dojo API",
        default_version='v2',
        description="To use the API you need be authorized.",
    ),
    # if public=False, includes only endpoints the current user has access to
    public=True,
    # The API of a OpenSource project should be public accessible
    permission_classes=[permissions.AllowAny],
)

urlpatterns = [
    #  Django Rest Framework API v2
    url(r'^%sapi/v2/' % get_system_setting('url_prefix'),
        include(v2_api.urls)),
    # action history
    url(r'^%shistory/(?P<cid>\d+)/(?P<oid>\d+)$' %
        get_system_setting('url_prefix'),
        views.action_history,
        name='action_history'),
    url(r'^%s' % get_system_setting('url_prefix'), include(ur)),
    url(r'^%sapi/v2/api-token-auth/' % get_system_setting('url_prefix'),
        tokenviews.obtain_auth_token,
        name='api-token-auth'),
    url(r'^%sapi/v2/user_profile/' % get_system_setting('url_prefix'),
        UserProfileView.as_view(),
        name='user_profile'),

    # drf-yasg = OpenAPI2
Exemplo n.º 40
0
def generate_report(request, obj):
    user = Dojo_User.objects.get(id=request.user.id)
    product_type = None
    product = None
    engagement = None
    test = None
    endpoint = None
    endpoints = None
    accepted_findings = None
    open_findings = None
    closed_findings = None
    verified_findings = None
    report_title = None
    report_subtitle = None
    report_info = "Generated By %s on %s" % (
        user.get_full_name(), (timezone.now().strftime("%m/%d/%Y %I:%M%p %Z")))

    if type(obj).__name__ == "Product_Type":
        if settings.FEATURE_AUTHORIZATION_V2:
            user_has_permission_or_403(request.user, obj, Permissions.Product_Type_View)
        else:
            if not (request.user.is_staff or check_auth_users_list(request.user, obj)):
                raise PermissionDenied
    elif type(obj).__name__ == "Product":
        if settings.FEATURE_AUTHORIZATION_V2:
            user_has_permission_or_403(request.user, obj, Permissions.Product_View)
        else:
            if not (request.user.is_staff or check_auth_users_list(request.user, obj)):
                raise PermissionDenied
    elif type(obj).__name__ == "Engagement":
        if settings.FEATURE_AUTHORIZATION_V2:
            user_has_permission_or_403(request.user, obj, Permissions.Engagement_View)
        else:
            if not (request.user.is_staff or check_auth_users_list(request.user, obj)):
                raise PermissionDenied
    elif type(obj).__name__ == "Test":
        if settings.FEATURE_AUTHORIZATION_V2:
            user_has_permission_or_403(request.user, obj, Permissions.Test_View)
        else:
            if not (request.user.is_staff or check_auth_users_list(request.user, obj)):
                raise PermissionDenied
    elif type(obj).__name__ == "Endpoint":
        if settings.FEATURE_AUTHORIZATION_V2:
            user_has_permission_or_403(request.user, obj, Permissions.Endpoint_View)
        else:
            if not (request.user.is_staff or check_auth_users_list(request.user, obj)):
                raise PermissionDenied
    elif type(obj).__name__ == "QuerySet" or type(obj).__name__ == "CastTaggedQuerySet":
        # authorization taken care of by only selecting findings from product user is authed to see
        pass
    else:
        if not request.user.is_staff:
            raise PermissionDenied

    report_format = request.GET.get('report_type', 'AsciiDoc')
    include_finding_notes = int(request.GET.get('include_finding_notes', 0))
    include_finding_images = int(request.GET.get('include_finding_images', 0))
    include_executive_summary = int(request.GET.get('include_executive_summary', 0))
    include_table_of_contents = int(request.GET.get('include_table_of_contents', 0))
    include_disclaimer = int(request.GET.get('include_disclaimer', 0))
    disclaimer = get_system_setting('disclaimer')
    if include_disclaimer and len(disclaimer) == 0:
        disclaimer = 'Please configure in System Settings.'
    generate = "_generate" in request.GET
    host_view = "host_view" 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
        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, prod_type=product_type, queryset=prefetch_related_findings_for_report(Finding.objects.filter(
            test__engagement__product__prod_type=product_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 len(findings.qs) > 0:
            start_date = timezone.make_aware(datetime.combine(findings.qs.last().date, datetime.min.time()))
        else:
            start_date = timezone.now()

        end_date = timezone.now()

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

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

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

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

    elif type(obj).__name__ == "Engagement":
        logger.debug('generating report for Engagement')
        engagement = obj
        findings = ReportFindingFilter(request.GET, engagement=engagement,
                                       queryset=prefetch_related_findings_for_report(Finding.objects.filter(test__engagement=engagement)))
        report_name = "Engagement Report: " + str(engagement)
        template = 'dojo/engagement_pdf_report.html'
        report_title = "Engagement Report"
        report_subtitle = str(engagement)

        ids = set(finding.id for finding in findings.qs)
        tests = Test.objects.filter(finding__id__in=ids).distinct()
        endpoints = Endpoint.objects.filter(product=engagement.product).distinct()

        context = {'engagement': engagement,
                   'tests': tests,
                   'report_name': report_name,
                   'findings': findings.qs.distinct().order_by('numerical_severity'),
                   'include_finding_notes': include_finding_notes,
                   'include_finding_images': include_finding_images,
                   'include_executive_summary': include_executive_summary,
                   'include_table_of_contents': include_table_of_contents,
                   'include_disclaimer': include_disclaimer,
                   'disclaimer': disclaimer,
                   'user': user,
                   'team_name': settings.TEAM_NAME,
                   'title': report_title,
                   'host': report_url_resolver(request),
                   'user_id': request.user.id,
                   'endpoints': endpoints}

    elif type(obj).__name__ == "Test":
        test = obj
        findings = ReportFindingFilter(request.GET, engagement=test.engagement,
                                       queryset=prefetch_related_findings_for_report(Finding.objects.filter(test=test)))
        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.distinct().order_by('numerical_severity'),
                   'include_finding_notes': include_finding_notes,
                   'include_finding_images': include_finding_images,
                   'include_executive_summary': include_executive_summary,
                   'include_table_of_contents': include_table_of_contents,
                   'include_disclaimer': include_disclaimer,
                   'disclaimer': disclaimer,
                   'user': user,
                   'team_name': settings.TEAM_NAME,
                   'title': report_title,
                   'host': report_url_resolver(request),
                   'user_id': request.user.id}

    elif type(obj).__name__ == "Endpoint":
        endpoint = obj
        if host_view:
            report_name = "Endpoint Host Report: " + endpoint.host
            endpoints = Endpoint.objects.filter(host=endpoint.host,
                                                product=endpoint.product).distinct()
            report_title = "Endpoint Host Report"
            report_subtitle = endpoint.host
        else:
            report_name = "Endpoint Report: " + str(endpoint)
            endpoints = Endpoint.objects.filter(pk=endpoint.id).distinct()
            report_title = "Endpoint Report"
            report_subtitle = str(endpoint)
        report_type = "Endpoint"
        template = 'dojo/endpoint_pdf_report.html'
        findings = ReportFindingFilter(request.GET,
                                       queryset=prefetch_related_findings_for_report(Finding.objects.filter(endpoints__in=endpoints)))

        context = {'endpoint': endpoint,
                   'endpoints': endpoints,
                   'report_name': report_name,
                   'findings': findings.qs.distinct().order_by('numerical_severity'),
                   'include_finding_notes': include_finding_notes,
                   'include_finding_images': include_finding_images,
                   'include_executive_summary': include_executive_summary,
                   'include_table_of_contents': include_table_of_contents,
                   'include_disclaimer': include_disclaimer,
                   'disclaimer': disclaimer,
                   'user': user,
                   'team_name': get_system_setting('team_name'),
                   'title': report_title,
                   'host': report_url_resolver(request),
                   'user_id': request.user.id}
    elif type(obj).__name__ == "QuerySet" or type(obj).__name__ == "CastTaggedQuerySet":
        findings = ReportFindingFilter(request.GET,
                                             queryset=prefetch_related_findings_for_report(obj).distinct())
        report_name = 'Finding'
        report_type = 'Finding'
        template = 'dojo/finding_pdf_report.html'
        report_title = "Finding Report"
        report_subtitle = ''

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

    report_form = ReportOptionsForm()

    if generate:
        report_form = ReportOptionsForm(request.GET)
        if report_format == 'AsciiDoc':
            return render(request,
                          'dojo/asciidoc_report.html',
                          {'product_type': product_type,
                           'product': product,
                           'engagement': engagement,
                           'test': test,
                           'endpoint': endpoint,
                           'findings': findings.qs.distinct().order_by('numerical_severity'),
                           'include_finding_notes': include_finding_notes,
                           'include_finding_images': include_finding_images,
                           'include_executive_summary': include_executive_summary,
                           'include_table_of_contents': include_table_of_contents,
                           'include_disclaimer': include_disclaimer,
                           'disclaimer': disclaimer,
                           'user': user,
                           'team_name': settings.TEAM_NAME,
                           'title': report_title,
                           'user_id': request.user.id,
                           'host': report_url_resolver(request),
                           'host_view': host_view,
                           'context': context,
                           })
        elif report_format == 'HTML':
            return render(request,
                          template,
                          {'product_type': product_type,
                           'product': product,
                           'engagement': engagement,
                           'report_name': report_name,
                           'test': test,
                           'endpoint': endpoint,
                           'endpoints': endpoints,
                           'findings': findings.qs.distinct().order_by('numerical_severity'),
                           'include_finding_notes': include_finding_notes,
                           'include_finding_images': include_finding_images,
                           'include_executive_summary': include_executive_summary,
                           'include_table_of_contents': include_table_of_contents,
                           'include_disclaimer': include_disclaimer,
                           'disclaimer': disclaimer,
                           'user': user,
                           'team_name': settings.TEAM_NAME,
                           'title': report_title,
                           'user_id': request.user.id,
                           'host': "",
                           'host_view': host_view,
                           'context': context,
                           })

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

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

    return render(request, 'dojo/request_report.html',
                  {'product_type': product_type,
                   'product': product,
                   'product_tab': product_tab,
                   'engagement': engagement,
                   'test': test,
                   'endpoint': endpoint,
                   'findings': findings,
                   'paged_findings': paged_findings,
                   'report_form': report_form,
                   'host_view': host_view,
                   'context': context,
                   })
Exemplo n.º 41
0
def add_temp_finding(request, tid, fid):
    jform = None
    test = get_object_or_404(Test, id=tid)
    finding = get_object_or_404(Finding_Template, id=fid)
    findings = Finding_Template.objects.all()

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

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

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

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

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

    add_breadcrumb(parent=test, title="Add Finding", top_level=False, request=request)
    return render(request, 'dojo/add_findings.html',
                  {'form': form,
                   'jform': jform,
                   'findings': findings,
                   'temp': True,
                   'fid': finding.id,
                   'tid': test.id,
                   'test': test,
                   })
Exemplo n.º 42
0
def generate_report(request, obj):
    user = Dojo_User.objects.get(id=request.user.id)
    product_type = None
    product = None
    engagement = None
    test = None
    endpoint = None
    endpoints = None
    endpoint_all_findings = None
    endpoint_monthly_counts = None
    endpoint_active_findings = None
    accepted_findings = None
    open_findings = None
    closed_findings = None
    verified_findings = None
    report_title = None
    report_subtitle = None
    report_info = "Generated By %s on %s" % (user.get_full_name(), (
        timezone.now().strftime("%m/%d/%Y %I:%M%p %Z")))

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

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

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

        end_date = timezone.now()

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

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

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

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

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

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

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

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

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

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

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

    report_form = ReportOptionsForm()

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

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

            return HttpResponseRedirect(reverse('reports'))

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

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

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

    return render(
        request, 'dojo/request_report.html', {
            'product_type': product_type,
            'product': product,
            'product_tab': product_tab,
            'engagement': engagement,
            'test': test,
            'endpoint': endpoint,
            'findings': findings,
            'paged_findings': paged_findings,
            'report_form': report_form,
            'context': context,
        })
Exemplo n.º 43
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,
    })
Exemplo n.º 44
0
 def process_request(self, request):
     timezone.activate(get_system_setting('time_zone'))
Exemplo n.º 45
0
def action_history(request, cid, oid):
    try:
        ct = ContentType.objects.get_for_id(cid)
        obj = ct.get_object_for_this_type(pk=oid)
    except (KeyError, ObjectDoesNotExist):
        raise Http404()

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

    if ct.model == "product":
        user_has_permission_or_403(request.user, obj, Permissions.Product_View)
        product_id = obj.id
        active_tab = "overview"
        object_value = Product.objects.get(id=obj.id)
    elif ct.model == "engagement":
        user_has_permission_or_403(request.user, obj,
                                   Permissions.Engagement_View)
        object_value = Engagement.objects.get(id=obj.id)
        product_id = object_value.product.id
        active_tab = "engagements"
    elif ct.model == "test":
        user_has_permission_or_403(request.user, obj, Permissions.Test_View)
        object_value = Test.objects.get(id=obj.id)
        product_id = object_value.engagement.product.id
        active_tab = "engagements"
        test = True
    elif ct.model == "finding":
        user_has_permission_or_403(request.user, obj, Permissions.Finding_View)
        object_value = Finding.objects.get(id=obj.id)
        product_id = object_value.test.engagement.product.id
        active_tab = "findings"
        finding = object_value
    elif ct.model == "endpoint":
        user_has_permission_or_403(request.user, obj,
                                   Permissions.Endpoint_View)
        object_value = Endpoint.objects.get(id=obj.id)
        product_id = object_value.product.id
        active_tab = "endpoints"
    elif ct.model == "risk_acceptance":
        engagements = Engagement.objects.filter(risk_acceptance=obj)
        authorized = False
        for engagement in engagements:
            if user_has_permission(request.user, engagement,
                                   Permissions.Engagement_View):
                authorized = True
                break
        if not authorized:
            raise PermissionDenied
    elif ct.model == "user":
        user_has_configuration_permission_or_403(request.user,
                                                 'auth.view_user',
                                                 legacy='superuser')
    else:
        if not request.user.is_superuser:
            raise PermissionDenied

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

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

    if not get_system_setting('enable_auditlog'):
        messages.add_message(
            request,
            messages.WARNING,
            'Audit logging is currently disabled in System Settings.',
            extra_tags='alert-danger')

    return render(
        request, 'dojo/action_history.html', {
            "history": paged_history,
            'product_tab': product_tab,
            "filtered": history,
            "obj": obj,
            "test": test,
            "object_value": object_value,
            "finding": finding
        })
Exemplo n.º 46
0
def add_temp_finding(request, tid, fid):
    jform = None
    test = get_object_or_404(Test, id=tid)
    finding = get_object_or_404(Finding_Template, id=fid)
    findings = Finding_Template.objects.all()

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

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

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

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

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

    add_breadcrumb(parent=test, title="Add Finding", top_level=False, request=request)
    return render(request, 'dojo/add_findings.html',
                  {'form': form,
                   'jform': jform,
                   'findings': findings,
                   'temp': True,
                   'fid': finding.id,
                   'tid': test.id,
                   'test': test,
                   })
Exemplo n.º 47
0
def edit_engagement(request, eid):
    engagement = Engagement.objects.get(pk=eid)
    is_ci_cd = engagement.engagement_type == "CI/CD"
    jira_project_form = None
    jira_epic_form = None
    jira_project = None
    jira_error = False

    if request.method == 'POST':
        form = EngForm(request.POST,
                       instance=engagement,
                       cicd=is_ci_cd,
                       product=engagement.product,
                       user=request.user)
        jira_project = jira_helper.get_jira_project(engagement,
                                                    use_inheritance=False)

        if form.is_valid():
            # first save engagement details
            new_status = form.cleaned_data.get('status')
            engagement = form.save(commit=False)
            if (new_status == "Cancelled" or new_status == "Completed"):
                engagement.active = False
                create_notification(
                    event='close_engagement',
                    title='Closure of %s' % engagement.name,
                    description='The engagement "%s" was closed' %
                    (engagement.name),
                    engagement=engagement,
                    url=reverse('engagment_all_findings',
                                args=(engagement.id, ))),
            else:
                engagement.active = True
            engagement.save()
            form.save_m2m()

            messages.add_message(request,
                                 messages.SUCCESS,
                                 'Engagement updated successfully.',
                                 extra_tags='alert-success')

            success, jira_project_form = jira_helper.process_jira_project_form(
                request,
                instance=jira_project,
                target='engagement',
                engagement=engagement,
                product=engagement.product)
            error = not success

            success, jira_epic_form = jira_helper.process_jira_epic_form(
                request, engagement=engagement)
            error = error or not success

            if not error:
                if '_Add Tests' in request.POST:
                    return HttpResponseRedirect(
                        reverse('add_tests', args=(engagement.id, )))
                else:
                    return HttpResponseRedirect(
                        reverse('view_engagement', args=(engagement.id, )))
        else:
            logger.debug(form.errors)

    else:
        form = EngForm(initial={'product': engagement.product},
                       instance=engagement,
                       cicd=is_ci_cd,
                       product=engagement.product,
                       user=request.user)

        jira_epic_form = None
        if get_system_setting('enable_jira'):
            jira_project = jira_helper.get_jira_project(engagement,
                                                        use_inheritance=False)
            jira_project_form = JIRAProjectForm(instance=jira_project,
                                                target='engagement',
                                                product=engagement.product)
            logger.debug('showing jira-epic-form')
            jira_epic_form = JIRAEngagementForm(instance=engagement)

    if is_ci_cd:
        title = 'Edit CI/CD Engagement'
    else:
        title = 'Edit Interactive Engagement'

    product_tab = Product_Tab(engagement.product.id,
                              title=title,
                              tab="engagements")
    product_tab.setEngagement(engagement)
    return render(
        request, 'dojo/new_eng.html', {
            'product_tab': product_tab,
            'title': title,
            'form': form,
            'edit': True,
            'jira_epic_form': jira_epic_form,
            'jira_project_form': jira_project_form,
            'engagement': engagement,
        })
Exemplo n.º 48
0
def promote_to_finding(request, fid):
    finding = get_object_or_404(Stub_Finding, id=fid)
    test = finding.test
    form_error = False
    jira_available = False

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

    form = PromoteFindingForm(initial={'title': finding.title,
                                       'date': finding.date,
                                       'severity': finding.severity,
                                       'description': finding.description,
                                       'test': finding.test,
                                       'reporter': finding.reporter})
    if request.method == 'POST':
        form = PromoteFindingForm(request.POST)
        if form.is_valid():
            new_finding = form.save(commit=False)
            new_finding.test = test
            new_finding.reporter = request.user
            new_finding.numerical_severity = Finding.get_numerical_severity(
                new_finding.severity)

            new_finding.active = True
            new_finding.false_p = False
            new_finding.duplicate = False
            new_finding.mitigated = None
            new_finding.verified = True
            new_finding.out_of_scope = False

            new_finding.save()
            new_finding.endpoints = form.cleaned_data['endpoints']
            new_finding.save()

            finding.delete()
            if 'jiraform' in request.POST:
                jform = JIRAFindingForm(request.POST, prefix='jiraform',
                                        enabled=JIRA_PKey.objects.get(product=test.engagement.product).push_all_issues)
                if jform.is_valid():
                    add_issue_task.delay(new_finding, jform.cleaned_data.get('push_to_jira'))

            messages.add_message(request,
                                 messages.SUCCESS,
                                 'Finding promoted successfully.',
                                 extra_tags='alert-success')

            return HttpResponseRedirect(reverse('view_test', args=(test.id,)))
        else:
            if 'endpoints' in form.cleaned_data:
                form.fields['endpoints'].queryset = form.cleaned_data['endpoints']
            else:
                form.fields['endpoints'].queryset = Endpoint.objects.none()
            form_error = True
            messages.add_message(request,
                                 messages.ERROR,
                                 'The form has errors, please correct them below.',
                                 extra_tags='alert-danger')
    add_breadcrumb(parent=test, title="Promote Finding", top_level=False, request=request)
    return render(request, 'dojo/promote_to_finding.html',
                  {'form': form,
                   'test': test,
                   'stub_finding': finding,
                   'form_error': form_error,
                   })
Exemplo n.º 49
0
def product_endpoint_report(request, pid):
    user = Dojo_User.objects.get(id=request.user.id)
    product = get_object_or_404(Product, id=pid)
    endpoints = Endpoint.objects.filter(product=product,
                                        finding__active=True,
                                        finding__verified=True,
                                        finding__false_p=False,
                                        finding__duplicate=False,
                                        finding__out_of_scope=False,
                                        )

    ids = get_endpoint_ids(endpoints)

    endpoints = Endpoint.objects.filter(id__in=ids)

    if request.user.is_staff or request.user in product.authorized_users.all():
        pass  # user is authorized for this product
    else:
        raise PermissionDenied

    endpoints = EndpointReportFilter(request.GET, queryset=endpoints)

    paged_endpoints = get_page_items(request, endpoints.qs, 25)
    report_format = request.GET.get('report_type', 'AsciiDoc')
    include_finding_notes = int(request.GET.get('include_finding_notes', 0))
    include_finding_images = int(request.GET.get('include_finding_images', 0))
    include_executive_summary = int(request.GET.get('include_executive_summary', 0))
    include_table_of_contents = int(request.GET.get('include_table_of_contents', 0))
    generate = "_generate" in request.GET
    add_breadcrumb(parent=product, title="Vulnerable Product Endpoints Report", top_level=False, request=request)
    report_form = ReportOptionsForm()

    filename = "product_endpoint_report.pdf"
    template = "dojo/product_endpoint_pdf_report.html"
    report_name = "Product Endpoint Report: " + str(product)
    report_title = "Product Endpoint Report"
    report_subtitle = str(product)
    report_info = "Generated By %s on %s" % (
        user.get_full_name(), (timezone.now().strftime("%m/%d/%Y %I:%M%p %Z")))

    try:
        start_date = Finding.objects.filter(endpoints__in=endpoints.qs).order_by('date')[:1][0].date
    except:
        start_date = timezone.now()

    end_date = timezone.now()

    risk_acceptances = Risk_Acceptance.objects.filter(engagement__test__finding__endpoints__in=endpoints.qs)

    accepted_findings = [finding for ra in risk_acceptances
                         for finding in ra.accepted_findings.filter(endpoints__in=endpoints.qs)]

    verified_findings = Finding.objects.filter(endpoints__in=endpoints.qs,
                                               date__range=[start_date, end_date],
                                               false_p=False,
                                               verified=True,
                                               duplicate=False,
                                               out_of_scope=False)

    open_findings = Finding.objects.filter(endpoints__in=endpoints.qs,
                                           false_p=False,
                                           verified=True,
                                           duplicate=False,
                                           out_of_scope=False,
                                           active=True,
                                           mitigated__isnull=True)

    closed_findings = Finding.objects.filter(endpoints__in=endpoints.qs,
                                             false_p=False,
                                             verified=True,
                                             duplicate=False,
                                             out_of_scope=False,
                                             mitigated__isnull=False)
    if generate:
        report_form = ReportOptionsForm(request.GET)
        if report_format == 'AsciiDoc':
            return render(request,
                          'dojo/asciidoc_report.html',
                          {'product_type': None,
                           'product': product,
                           'accepted_findings': accepted_findings,
                           'open_findings': open_findings,
                           'closed_findings': closed_findings,
                           'verified_findings': verified_findings,
                           'engagement': None,
                           'test': None,
                           'endpoints': endpoints,
                           'endpoint': None,
                           'findings': None,
                           'include_finding_notes': include_finding_notes,
                           'include_finding_images': include_finding_images,
                           'include_executive_summary': include_executive_summary,
                           'include_table_of_contents': include_table_of_contents,
                           'user': request.user,
                           'title': 'Generate Report',
                           })
        elif report_format == 'PDF':
            endpoints = endpoints.qs.order_by('finding__numerical_severity')
            # lets create the report object and send it in to celery task
            if 'regen' in request.GET:
                # we should already have a report object, lets get and use it
                report = get_object_or_404(Report, id=request.GET['regen'])
                report.datetime = timezone.now()
                report.status = 'requested'
                if report.requester.username != request.user.username:
                    report.requester = request.user
            else:
                report = Report(name="Product Endpoints " + str(product),
                                type="Product Endpoint",
                                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={'product': product,
                                            'endpoints': endpoints,
                                            'accepted_findings': accepted_findings,
                                            'open_findings': open_findings,
                                            'closed_findings': closed_findings,
                                            'verified_findings': verified_findings,
                                            'report_name': report_name,
                                            'include_finding_notes': include_finding_notes,
                                            'include_finding_images': include_finding_images,
                                            'include_executive_summary': include_executive_summary,
                                            'include_table_of_contents': include_table_of_contents,
                                            'user': user,
                                            'team_name': get_system_setting('team_name'),
                                            'title': 'Generate Report',
                                            'host': report_url_resolver(request),
                                            'user_id': request.user.id},
                                   uri=request.build_absolute_uri(report.get_url()))
            messages.add_message(request, messages.SUCCESS,
                                 'Your report is building.',
                                 extra_tags='alert-success')
            return HttpResponseRedirect(reverse('reports'))
        else:
            raise Http404()

    product_tab = Product_Tab(product.id, "Product Endpoint Report", tab="endpoints")
    return render(request,
                  'dojo/request_endpoint_report.html',
                  {"endpoints": paged_endpoints,
                   "filtered": endpoints,
                   "product_tab": product_tab,
                   'report_form': report_form,
                   "name": "Vulnerable Product Endpoints",
                   })
Exemplo n.º 50
0
def add_findings(request, tid):
    test = Test.objects.get(id=tid)
    form_error = False
    enabled = False
    jform = None
    form = AddFindingForm(initial={'date': timezone.now().date()})

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

    if request.method == 'POST':
        form = AddFindingForm(request.POST)
        if form.is_valid():
            new_finding = form.save(commit=False)
            new_finding.test = test
            new_finding.reporter = request.user
            new_finding.numerical_severity = Finding.get_numerical_severity(
                new_finding.severity)
            if new_finding.false_p or new_finding.active is False:
                new_finding.mitigated = timezone.now()
                new_finding.mitigated_by = request.user
            create_template = new_finding.is_template
            # always false now since this will be deprecated soon in favor of new Finding_Template model
            new_finding.is_template = False
            new_finding.save()
            new_finding.endpoints = form.cleaned_data['endpoints']
            new_finding.save()
            if 'jiraform-push_to_jira' in request.POST:
                jform = JIRAFindingForm(request.POST, prefix='jiraform', enabled=enabled)
                if jform.is_valid():
                    add_issue_task.delay(new_finding, jform.cleaned_data.get('push_to_jira'))
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'Finding added successfully.',
                                     extra_tags='alert-success')
            if create_template:
                templates = Finding_Template.objects.filter(title=new_finding.title)
                if len(templates) > 0:
                    messages.add_message(request,
                                         messages.ERROR,
                                         'A finding template was not created.  A template with this title already '
                                         'exists.',
                                         extra_tags='alert-danger')
                else:
                    template = Finding_Template(title=new_finding.title,
                                                cwe=new_finding.cwe,
                                                severity=new_finding.severity,
                                                description=new_finding.description,
                                                mitigation=new_finding.mitigation,
                                                impact=new_finding.impact,
                                                references=new_finding.references,
                                                numerical_severity=new_finding.numerical_severity)
                    template.save()
                    messages.add_message(request,
                                         messages.SUCCESS,
                                         'A finding template was also created.',
                                         extra_tags='alert-success')
            if '_Finished' in request.POST:
                return HttpResponseRedirect(reverse('view_test', args=(test.id,)))
            else:
                return HttpResponseRedirect(reverse('add_findings', args=(test.id,)))
        else:
            if 'endpoints' in form.cleaned_data:
                form.fields['endpoints'].queryset = form.cleaned_data['endpoints']
            else:
                form.fields['endpoints'].queryset = Endpoint.objects.none()
            form_error = True
            messages.add_message(request,
                                 messages.ERROR,
                                 'The form has errors, please correct them below.',
                                 extra_tags='alert-danger')
    add_breadcrumb(parent=test, title="Add Finding", top_level=False, request=request)
    return render(request, 'dojo/add_findings.html',
                  {'form': form,
                   'test': test,
                   'temp': False,
                   'tid': tid,
                   'form_error': form_error,
                   'jform': jform,
                   })
Exemplo n.º 51
0
def edit_product(request, pid):
    prod = Product.objects.get(pk=pid)
    jira_enabled = True
    jira_inst = None
    jform = None
    try:
        jira_inst = JIRA_PKey.objects.get(product=prod)
    except:
        jira_enabled = False
        pass
    if request.method == 'POST':
        form = ProductForm(request.POST, instance=prod)
        if form.is_valid():
            form.save()
            tags = request.POST.getlist('tags')
            t = ", ".join(tags)
            prod.tags = t
            messages.add_message(request,
                                 messages.SUCCESS,
                                 'Product updated successfully.',
                                 extra_tags='alert-success')

            if get_system_setting('enable_jira') and jira_enabled:
                jform = JIRAPKeyForm(request.POST, instance=jira_inst)
                #need to handle delete
                try:
                    jform.save()
                except:
                    pass
            else:
                jform = JIRAPKeyForm(request.POST)
                if jform.is_valid():
                    new_conf = jform.save(commit=False)
                    new_conf.product_id = pid
                    new_conf.save()
                    messages.add_message(
                        request,
                        messages.SUCCESS,
                        'JIRA information updated successfully.',
                        extra_tags='alert-success')

            return HttpResponseRedirect(reverse('view_product', args=(pid, )))
    else:
        form = ProductForm(instance=prod,
                           initial={
                               'auth_users':
                               prod.authorized_users.all(),
                               'tags':
                               get_tag_list(Tag.objects.get_for_object(prod))
                           })

        if get_system_setting('enable_jira') and jira_enabled:
            if jira_enabled:
                jform = JIRAPKeyForm(instance=jira_inst)
            else:
                jform = JIRAPKeyForm()
        else:
            jform = None
    add_breadcrumb(parent=prod, title="Edit", top_level=False, request=request)

    return render(request, 'dojo/edit_product.html', {
        'form': form,
        'jform': jform,
        'product': prod,
    })
Exemplo n.º 52
0
def new_eng_for_app(request, pid):
    jform = None
    prod = Product.objects.get(id=pid)
    if request.method == 'POST':
        form = EngForm(request.POST)
        if form.is_valid():
            new_eng = form.save(commit=False)
            new_eng.product = prod
            if new_eng.threat_model:
                new_eng.progress = 'threat_model'
            else:
                new_eng.progress = 'other'
            new_eng.save()
            if get_system_setting('enable_jira'):
                #Test to make sure there is a Jira project associated the product
                try:
                    jform = JIRAFindingForm(request.POST,
                                            prefix='jiraform',
                                            enabled=JIRA_PKey.objects.get(
                                                product=prod).push_all_issues)
                    if jform.is_valid():
                        add_epic_task.delay(
                            new_eng, jform.cleaned_data.get('push_to_jira'))
                except JIRA_PKey.DoesNotExist:
                    pass

            #else:
            #    print >>sys.stderr, 'no prefix is found'

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

            create_notification(event='engagement_added',
                                title='Engagement added',
                                engagement=new_eng,
                                url=request.build_absolute_uri(
                                    reverse('view_engagement',
                                            args=(new_eng.id, ))),
                                objowner=new_eng.lead)

            if "_Add Tests" in request.POST:
                return HttpResponseRedirect(
                    reverse('add_tests', args=(new_eng.id, )))
            else:
                return HttpResponseRedirect(
                    reverse('view_engagement', args=(new_eng.id, )))
    else:
        form = EngForm(initial={})
        if (get_system_setting('enable_jira')):
            if JIRA_PKey.objects.filter(product=prod).count() != 0:
                jform = JIRAFindingForm(prefix='jiraform',
                                        enabled=JIRA_PKey.objects.get(
                                            product=prod).push_all_issues)

    add_breadcrumb(parent=prod,
                   title="New Engagement",
                   top_level=False,
                   request=request)

    return render(request, 'dojo/new_eng.html', {
        'form': form,
        'pid': pid,
        'jform': jform
    })
Exemplo n.º 53
0
def add_findings(request, tid):
    test = Test.objects.get(id=tid)
    form_error = False
    enabled = False
    jform = None
    form = AddFindingForm(initial={'date': datetime.now(tz=localtz).date()})

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

    if request.method == 'POST':
        form = AddFindingForm(request.POST)
        if form.is_valid():
            new_finding = form.save(commit=False)
            new_finding.test = test
            new_finding.reporter = request.user
            new_finding.numerical_severity = Finding.get_numerical_severity(
                new_finding.severity)
            if new_finding.false_p or new_finding.active is False:
                new_finding.mitigated = datetime.now(tz=localtz)
                new_finding.mitigated_by = request.user
            create_template = new_finding.is_template
            # always false now since this will be deprecated soon in favor of new Finding_Template model
            new_finding.is_template = False
            new_finding.save()
            new_finding.endpoints = form.cleaned_data['endpoints']
            new_finding.save()
            if 'jiraform-push_to_jira' in request.POST:
                jform = JIRAFindingForm(request.POST, prefix='jiraform', enabled=enabled)
                if jform.is_valid():
                    add_issue_task.delay(new_finding, jform.cleaned_data.get('push_to_jira'))
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'Finding added successfully.',
                                     extra_tags='alert-success')
            if create_template:
                templates = Finding_Template.objects.filter(title=new_finding.title)
                if len(templates) > 0:
                    messages.add_message(request,
                                         messages.ERROR,
                                         'A finding template was not created.  A template with this title already '
                                         'exists.',
                                         extra_tags='alert-danger')
                else:
                    template = Finding_Template(title=new_finding.title,
                                                cwe=new_finding.cwe,
                                                severity=new_finding.severity,
                                                description=new_finding.description,
                                                mitigation=new_finding.mitigation,
                                                impact=new_finding.impact,
                                                references=new_finding.references,
                                                numerical_severity=new_finding.numerical_severity)
                    template.save()
                    messages.add_message(request,
                                         messages.SUCCESS,
                                         'A finding template was also created.',
                                         extra_tags='alert-success')
            if '_Finished' in request.POST:
                return HttpResponseRedirect(reverse('view_test', args=(test.id,)))
            else:
                return HttpResponseRedirect(reverse('add_findings', args=(test.id,)))
        else:
            if 'endpoints' in form.cleaned_data:
                form.fields['endpoints'].queryset = form.cleaned_data['endpoints']
            else:
                form.fields['endpoints'].queryset = Endpoint.objects.none()
            form_error = True
            messages.add_message(request,
                                 messages.ERROR,
                                 'The form has errors, please correct them below.',
                                 extra_tags='alert-danger')
    add_breadcrumb(parent=test, title="Add Finding", top_level=False, request=request)
    return render(request, 'dojo/add_findings.html',
                  {'form': form,
                   'test': test,
                   'temp': False,
                   'tid': tid,
                   'form_error': form_error,
                   'jform': jform,
                   })
Exemplo n.º 54
0
from auditlog.models import LogEntry
from django import forms
from django.contrib.auth.models import User
from django.utils import six
from django.utils.translation import ugettext_lazy as _
from django_filters import FilterSet, CharFilter, OrderingFilter, \
    ModelMultipleChoiceFilter, ModelChoiceFilter, MultipleChoiceFilter, \
    BooleanFilter
from django_filters.filters import ChoiceFilter, _truncate, DateTimeFilter
from pytz import timezone

from dojo.models import Dojo_User, Product_Type, Finding, Product, Test_Type, \
    Endpoint, Development_Environment, Finding_Template, Report
from dojo.utils import get_system_setting

local_tz = timezone(get_system_setting('time_zone'))

SEVERITY_CHOICES = (('Info', 'Info'), ('Low', 'Low'), ('Medium', 'Medium'),
                    ('High', 'High'), ('Critical', 'Critical'))
BOOLEAN_CHOICES = (('false', 'No'), ('true', 'Yes'),)

EARLIEST_FINDING = None


def now():
    return local_tz.localize(datetime.today())


def get_earliest_finding():
    global EARLIEST_FINDING
    if EARLIEST_FINDING is not None:
Exemplo n.º 55
0
def fetch_system_setting(name):
    return get_system_setting(name)