com.denimgroup.threadfix.webapp.controller.VulnerabilitySearchController.java Source code

Java tutorial

Introduction

Here is the source code for com.denimgroup.threadfix.webapp.controller.VulnerabilitySearchController.java

Source

////////////////////////////////////////////////////////////////////////
//
//     Copyright (c) 2009-2015 Denim Group, Ltd.
//
//     The contents of this file are subject to the Mozilla Public License
//     Version 2.0 (the "License"); you may not use this file except in
//     compliance with the License. You may obtain a copy of the License at
//     http://www.mozilla.org/MPL/
//
//     Software distributed under the License is distributed on an "AS IS"
//     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
//     License for the specific language governing rights and limitations
//     under the License.
//
//     The Original Code is ThreadFix.
//
//     The Initial Developer of the Original Code is Denim Group, Ltd.
//     Portions created by Denim Group, Ltd. are Copyright (C)
//     Denim Group, Ltd. All Rights Reserved.
//
//     Contributor(s): Denim Group, Ltd.
//
////////////////////////////////////////////////////////////////////////
package com.denimgroup.threadfix.webapp.controller;

import com.denimgroup.threadfix.ObjectToSSVLParser;
import com.denimgroup.threadfix.data.entities.*;
import com.denimgroup.threadfix.logging.SanitizedLogger;
import com.denimgroup.threadfix.remote.response.RestResponse;
import com.denimgroup.threadfix.service.*;
import com.denimgroup.threadfix.service.enterprise.EnterpriseTest;
import com.denimgroup.threadfix.service.report.ReportsService;
import com.denimgroup.threadfix.service.util.ControllerUtils;
import com.denimgroup.threadfix.service.util.PermissionUtils;
import com.denimgroup.threadfix.views.AllViews;
import com.fasterxml.jackson.annotation.JsonView;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

import static com.denimgroup.threadfix.CollectionUtils.list;
import static com.denimgroup.threadfix.CollectionUtils.map;
import static org.apache.commons.lang3.StringEscapeUtils.escapeHtml4;

@Controller
@RequestMapping("/reports/")
public class VulnerabilitySearchController {

    private static final SanitizedLogger LOG = new SanitizedLogger(VulnerabilitySearchController.class);

    @Autowired
    public VulnerabilitySearchService vulnerabilitySearchService;
    @Autowired
    public OrganizationService organizationService;
    @Autowired
    public ChannelTypeService channelTypeService;
    @Autowired
    private GenericVulnerabilityService genericVulnerabilityService;
    @Autowired
    private ApplicationService applicationService;
    @Autowired
    private FilterJsonBlobService filterJsonBlobService;
    @Autowired
    private FilterDateService filterDateService;
    @Autowired
    private ReportsService reportsService;
    @Autowired
    private TagService tagService;
    @Autowired
    GenericSeverityService genericSeverityService;
    @Autowired(required = false)
    EnterpriseTagService enterpriseTagService;
    @Autowired
    private ApplicationVersionService applicationVersionService;

    // Turn Date.getTime() javascript numbers into java.util.Date objects.
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(Date.class, new NumericDatePropertyEditorSupport());
    }

    @RequestMapping(value = "tree", method = RequestMethod.POST)
    public @ResponseBody Object getTree(@ModelAttribute VulnerabilitySearchParameters parameters) {
        return RestResponse.success(map("tree", vulnerabilitySearchService.getTree(parameters), "severities",
                genericSeverityService.loadAll()));
    }

    @JsonView(AllViews.UIVulnSearch.class)
    @RequestMapping(value = "search", method = RequestMethod.POST)
    public @ResponseBody Object searchVulnerabilities(@ModelAttribute VulnerabilitySearchParameters parameters)
            throws IOException {

        long start = System.currentTimeMillis();

        // Query all vulnerabilities of Sonatype and Dependency Check for
        // OWASP Top Ten 2013 Category A9 - Using Components with Known Vulnerabilities
        if (parameters.getUsingComponentsWithKnownVulnerabilities()) {
            parameters.getChannelTypes()
                    .add(channelTypeService.loadChannel(ScannerType.DEPENDENCY_CHECK.getDisplayName()));
            parameters.getChannelTypes().add(channelTypeService.loadChannel(ScannerType.SONATYPE.getDisplayName()));
        }

        Object response = RestResponse.success(getElementInfo(parameters));
        LOG.info("Loading vulns took " + (System.currentTimeMillis() - start) + " ms");

        return response;
    }

    private Map<String, Object> getElementInfo(VulnerabilitySearchParameters parameters) {
        Map<String, Object> responseMap = map();
        responseMap.put("vulns", vulnerabilitySearchService.performLookup(parameters));
        responseMap.put("vulnCount", vulnerabilitySearchService.getCount(parameters));
        return responseMap;
    }

    @RequestMapping(value = "search/export/csv", method = { RequestMethod.POST, RequestMethod.GET })
    public String exportVulnsInCSV(@ModelAttribute VulnerabilitySearchParameters parameters,
            HttpServletResponse response) throws IOException {

        LOG.info("Exporting vulnerabilities in CSV format.");

        long start = System.currentTimeMillis();

        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment; filename=\"search_export.csv\"");

        List<Vulnerability> vulnerabilityList = retrieveExportVulnList(parameters);

        boolean isExportable = false;

        ReportCheckResultBean reportCheckResultBean = reportsService.generateSearchReport(vulnerabilityList);
        if (reportCheckResultBean != null
                && reportCheckResultBean.getReportCheckResult() == ReportsService.ReportCheckResult.VALID) {
            StringBuffer report = reportCheckResultBean.getReport();
            if (report != null) {
                String pageString = report.toString();
                isExportable = sendFileContentToClient(pageString, response);
            }
        }

        if (!isExportable)
            return ReportsService.ReportCheckResult.OTHER_ERROR.toString();

        LOG.info("Exporting vulns took " + (System.currentTimeMillis() - start) + " ms");
        return null;
    }

    @RequestMapping(value = "search/export/ssvl", method = { RequestMethod.POST, RequestMethod.GET })
    public String exportVulnsInSSVL(@ModelAttribute VulnerabilitySearchParameters parameters,
            HttpServletResponse response) throws IOException {

        LOG.info("Exporting vulnerabilities in SSVL format.");

        long start = System.currentTimeMillis();

        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment; filename=\"search_export.ssvl\"");

        List<Vulnerability> vulnerabilityList = retrieveExportVulnList(parameters);

        String content = ObjectToSSVLParser.parse(vulnerabilityList);

        if (!sendFileContentToClient(content, response))
            return ReportsService.ReportCheckResult.OTHER_ERROR.toString();

        LOG.info("Exporting vulns took " + (System.currentTimeMillis() - start) + " ms");

        return null;
    }

    @JsonView(AllViews.VulnSearchApplications.class)
    @RequestMapping(value = "parameters", method = RequestMethod.GET)
    @ResponseBody
    public Object getParameters(HttpServletRequest request) {

        Map<String, Object> responseObject = new HashMap<>();

        List<Organization> teams = organizationService.loadAllActiveFilter();
        responseObject.put("teams", teams);
        responseObject.put("scanners", channelTypeService.loadAll());
        responseObject.put("genericSeverities", genericSeverityService.loadAll());
        responseObject.put("vulnTypes", genericVulnerabilityService.loadAll());
        responseObject.put("applications", PermissionUtils.filterAppsList(teams));
        responseObject.put("savedFilters", filterJsonBlobService.loadAllActive());
        responseObject.put("savedDateRanges", filterDateService.loadAllActive());
        responseObject.put("filterParameters", ControllerUtils.getItem(request, ControllerUtils.FILTER_PARAMETER));
        responseObject.put("tags", sanitize(tagService.loadAllApplicationTags()));
        responseObject.put("vulnTags", tagService.loadAllVulnTags());
        responseObject.put("commentTags", tagService.loadAllCommentTags());
        responseObject.put("versionsMap", applicationVersionService.getAllVersionsByAppId(null));

        if (EnterpriseTest.isEnterprise() && enterpriseTagService != null) {
            responseObject.put("enterpriseTags", enterpriseTagService.loadEnterpriseTags());
        }

        return RestResponse.success(responseObject);
    }

    private Object sanitize(List<Tag> tags) {
        for (Tag tag : tags) {
            tag.setEncodedName(escapeHtml4(tag.getName()));
        }

        return tags;
    }

    @RequestMapping(value = "update/heading/{appId}", method = RequestMethod.GET)
    @ResponseBody
    @JsonView(AllViews.TableRow.class)
    public RestResponse<Map<String, Object>> getHeadingInfo(@PathVariable("appId") Integer appId) {

        Map<String, Object> responseObject = new HashMap<>();

        long numVulns = applicationService.getVulnCount(appId, true);
        Application application = applicationService.loadApplication(appId);
        responseObject.put("scans", application.getScans());
        responseObject.put("numVulns", numVulns);

        return RestResponse.success(responseObject);
    }

    @RequestMapping(value = "saveParameters", method = RequestMethod.POST)
    @ResponseBody
    public void saveParameters(@ModelAttribute VulnerabilitySearchParameters parameters,
            HttpServletRequest request) {
        ControllerUtils.addItem(request, ControllerUtils.FILTER_PARAMETER, parameters);
    }

    private List<Vulnerability> retrieveExportVulnList(VulnerabilitySearchParameters parameters) {
        parameters.setPage(null);
        parameters.setNumberVulnerabilities(null);

        parameters.setDescList(list("severity.intValue"));
        parameters.setAscList(list("genericVulnAlias.name", "surface.path", "surface.parameter"));
        return vulnerabilitySearchService.performLookup(parameters);
    }

    private boolean sendFileContentToClient(String content, HttpServletResponse response) throws IOException {
        if (content == null) {
            return false;
        }
        InputStream in = new ByteArrayInputStream(content.getBytes("UTF-8"));

        if (in != null) {
            ServletOutputStream out = response.getOutputStream();

            byte[] outputByteBuffer = new byte[65535];

            int remainingSize = in.read(outputByteBuffer, 0, 65535);

            // copy binary content to output stream
            while (remainingSize != -1) {
                out.write(outputByteBuffer, 0, remainingSize);
                remainingSize = in.read(outputByteBuffer, 0, 65535);
            }
            in.close();
            out.flush();
            out.close();
            return true;
        } else {
            return false;
        }
    }
}