DependencyCheck+Jenkins扫描JAVA第三方依赖(CVE)漏洞

这篇具有很好参考价值的文章主要介绍了DependencyCheck+Jenkins扫描JAVA第三方依赖(CVE)漏洞。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

原理说明:首先使用DependencyCheck更新漏洞库到本地,然后DependencyCheck扫描扫描项目,得到一个json报告,然后再使用json报告填充我们的自定义模板,最后输出填充后的模板为漏洞报告。至于jenkins只是最后帮我们实现全自动扫描、输出的一个工具而已。

一、部署DependencyCheck

1、DependencyCheck是什么

  • Dependency-Check 是 OWASP(Open Web Application Security Project)的一个实用开源程序,用于识别项目依赖项并检查是否存在任何已知的,公开披露的漏洞。目前,已支持Java、.NET、Ruby、Node.js、Python等语言编写的程序,并为C/C++构建系统(autoconf和cmake)提供了有限的支持。而且该工具还是OWASP Top 10的解决方案的一部分。
  • Dependency-Check 支持面广(支持多种语言)、可集成性强,作为一款开源工具,在多年来的发展中已经支持和许多主流的软件进行集成,比如:命令行、Ant、Maven、Gradle、Jenkins、Sonar等;具备使用方便,落地简单等优势。

2、下载DependencyCheck

官方网站:OWASP Dependency-Check | OWASP Foundation

dependency-check 扫描,网络安全,jenkins,运维,web安全,java,自动化

3、安装DependencyCheck

开箱即用:

        将zip压缩包解压即可,我就放这里了:/root/dependency-check。执行bin目录下的dependency-check.bat或者dependency-check.sh。

命令如下:

dependency-check.sh --project "第三方依赖CVE漏洞扫描报告" --scan "**/*.jar" -n -f JSON -o "第三方依赖CVE漏洞扫描报告.json"

--project 给这次扫描的项目起个名称
--scan    要扫描的文件路径
-n        此次扫描不更新漏洞库:不加这个会先去更新漏洞库,然后再进行扫描
-f        要输出的报告格式,有HTML ,JSON等
-o        扫描报告的存放路径

二、本地漏洞库搭建(NVD+CNNVD)

1、获取nvd漏洞库

这里要使用大佬的开源工具:nist-data-mirror.jar。开源地址:stevespringett/nist-data-mirror: A simple Java command-line utility to mirror the CVE JSON data from NIST. (github.com)

为了方便管理我把这个工具放在这里:/root/dependency-check/data/nist-data-mirror.jar。加载nvd漏洞库(第一次有点慢,从2000年开始的):

java -jar /root/dependency-check/data/nist-data-mirror.jar /root/dependency-check/data/nvdcache

dependency-check 扫描,网络安全,jenkins,运维,web安全,java,自动化

将更新下来的JSON数据提取,保存在数据库表里面,核心代码:

package com.yunhuang.autosafe.common.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yunhuang.autosafe.common.cve.CveObj;
import com.yunhuang.autosafe.common.entity.Cve;
import com.yunhuang.autosafe.common.mapper.CveMapper;
import com.yunhuang.autosafe.common.service.CveService;
import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Service;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;


@Service
public class CveServiceImpl extends ServiceImpl<CveMapper, Cve> implements CveService {

    /**
     * 拉去cve漏洞数据库
     * @param loadType 0-全量初始化 1-增量更新
     */
    @Override
    public void loadCveData(Integer loadType) {
        String workspace = System.getProperty("user.dir");
        String nvdcachePath = workspace + "/nvdcache";
        System.out.println("工作空间="+workspace);
        //1、拉取NVD的cve漏洞文件
        syncCveList(workspace,nvdcachePath);

        //2、将拉取到的json文件进行解析并提取为对象,转存mysql
        if(0==loadType){
            readFilesAll(nvdcachePath);
        }else if(1==loadType){
            updateRecentCve(nvdcachePath);
        }
    }

    /**
     * 拉取NVD的cve漏洞文件(json文件)
     * @param workspace       工作空间:默认当前jar的路径
     * @param nvdcachePath    存储漏洞库文件(json文件)的路径
     */
    public void syncCveList(String workspace,String nvdcachePath) {
        //1、检查缓存目录是否存在
        File nvdcacheFile = new File(nvdcachePath);
        if(!nvdcacheFile.exists()){
            System.out.println("缓存目录不存在,创建!");
            nvdcacheFile.mkdirs();
        }

        String nistDataMirror = workspace + "/nist-data-mirror.jar";
        File nistDataMirrorFile = new File(nistDataMirror);
        if(!nistDataMirrorFile.exists()){
            System.out.println("nist-data-mirror.jar不存在,创建!");
            try{
                ClassPathResource classPathResource = new ClassPathResource("utils/nist-data-mirror.jar");
                InputStream inputStream = classPathResource.getStream();
                String destPath = workspace + "/nist-data-mirror.jar";

                FileUtils.copyInputStreamToFile(inputStream, new File(destPath));

            }catch (Exception e){
                e.printStackTrace();
            }
        }


        //1、拉取NVD的cve漏洞文件
        String command = "java -jar "+workspace+"/nist-data-mirror.jar "+nvdcachePath;

        try {
            Process process = Runtime.getRuntime().exec(command);

            // 读取命令执行的输出
            InputStream inputStream = process.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }

            // 等待命令执行结束
            int exitCode = process.waitFor();
            System.out.println("命令执行结束,退出码:" + exitCode);

        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }





    private void readFilesAll(String nvdcachePath){
        System.out.println("------------全量初始化------------");
        File nvdcacheFile = new File(nvdcachePath);
        File[] files = nvdcacheFile.listFiles((dir, name) -> name.toLowerCase().endsWith(".json"));
        for(File f : files){
            System.out.println(f.getAbsolutePath());
            parseJson(f.getAbsolutePath());
            System.out.println("");
        }
        System.out.println("------------全量初始化-完成------------");
    }

    private void updateRecentCve(String nvdcachePath){
        System.out.println("------------增量更新------------");
        File nvdcacheFile = new File(nvdcachePath);
        File[] files = nvdcacheFile.listFiles((dir, name) -> name.toLowerCase().endsWith(DateUtil.thisYear()+".json") || name.toLowerCase().endsWith("modified.json") || name.toLowerCase().endsWith("recent.json"));
        for(File f : files){
            System.out.println(f.getAbsolutePath());
            parseJson(f.getAbsolutePath());
            System.out.println("");
        }
        System.out.println("------------增量更新-完成------------");
    }


    private void parseJson(String filePath){
        try {
            String jsonStr = new String( Files.readAllBytes( Paths.get(filePath)));
            JSONObject jsonObject = JSONUtil.parseObj(jsonStr);
            String CVE_Items = jsonObject.getStr("CVE_Items");
            List<CveObj> cveObjs = JSONUtil.toList(CVE_Items, CveObj.class);

            List<Cve> list = new ArrayList<>();
            // 对解析后的对象数组进行操作
            for (CveObj obj : cveObjs) {
                Cve cve = new Cve();
                cve.setId(obj.getCve().getCVE_data_meta().getID());
                try{
                    cve.setSeverity(obj.getImpact().getBaseMetricV2().getSeverity()+"");
                }catch (Exception e){

                }
                cve.setDescription(JSON.toJSONString(obj.getCve().getDescription().getDescription_data()).replaceAll("'",""));
                cve.setPublishedDate(DateUtil.parseDate(obj.getPublishedDate()));
                cve.setLastModifiedDate(DateUtil.parseDate(obj.getLastModifiedDate()));

                list.add(cve);
            }

            this.saveOrUpdateBatch(list);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

dependency-check 扫描,网络安全,jenkins,运维,web安全,java,自动化

2、获取cnnvd漏洞库

官网地址:国家信息安全漏洞库 (cnnvd.org.cn)

CNNVD是我们国家的信息安全漏洞库,咱们这个漏洞库不仅仅收录了NVD的漏洞数据(CVE),还收录咱们国内的漏洞信息(CNNVD),也就是说同样一条漏洞信息,CNNVD的漏洞数据上面既有CVE漏洞编码,也有CNNVD编码,而且描述信息还是中文的。

获取方式:

dependency-check 扫描,网络安全,jenkins,运维,web安全,java,自动化

dependency-check 扫描,网络安全,jenkins,运维,web安全,java,自动化

3、转换为自定义漏洞库

CNNVD漏洞数据库下载后是xml格式的文件,我们需要写代码将xml里面我们需要的数据提取出来,保存在数据库表里面

@GetMapping
    public void insertCnnvd(int type) throws JAXBException {


        if(type==0){
            for(int i=1999;i<=2023;i++){
                System.out.println("-------->开始读取"+i+"年数据:");
                List<Cnnvd> nvdList = parseXml(i);
                System.out.println("-------->成功读取"+i+"年数据:"+nvdList.size());
                cnnvdService.saveOrUpdateBatch(nvdList);
                System.out.println("-------->成功写入数据:"+nvdList.size());
                System.out.println("");
                System.out.println("");
            }
        }else{
            System.out.println("-------->开始读取"+DateUtil.thisYear()+"年数据:");
            List<Cnnvd> cnnvdList = parseXml(2023);
            System.out.println("-------->成功读取"+DateUtil.thisYear()+"年数据:"+cnnvdList.size());
            cnnvdService.saveOrUpdateBatch(cnnvdList);
            System.out.println("-------->成功写入数据:"+cnnvdList.size());
        }
    }

    public List<Cnnvd> parseXml(int fileName) throws JAXBException {
        //可能的问题:[org.xml.sax.SAXParseException; lineNumber: 2292; columnNumber: 191; 元素类型 "use" 必须由匹配的结束标记 "</use>" 终止。]] with root cause
        //解决的方案:在内网的签名添加字符串:<![CDATA[             在内网的结尾添加字符串:]]>
        InputStream stream = this.getClass().getClassLoader().getResourceAsStream("cnnvd/"+fileName+".xml");

        JAXBContext jaxbContext = JAXBContext.newInstance(VulnerabilityList.class);
        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        VulnerabilityList vulnerabilityList = (VulnerabilityList) jaxbUnmarshaller.unmarshal(stream);
        List<Cnnvd> vulnerabilities = vulnerabilityList.vulnerabilities;

        return vulnerabilities;
    }
@Data
@XmlRootElement(name = "entry")
@XmlAccessorType(XmlAccessType.FIELD)
public class Cnnvd implements Serializable {
    @TableId(type = IdType.INPUT)
    @XmlElement(name = "vuln-id")
    public String id;
    @XmlElement(name = "name")
    public String name;
    @XmlElement(name = "published")
    public String published;
    @XmlElement(name = "modified")
    public String modified;
    @XmlElement(name = "source")
    public String source;
    @XmlElement(name = "severity")
    public String severity;
    @XmlElement(name = "vuln-type")
    public String vulnType;
    @XmlElement(name = "vuln-descript")
    public String description;
    @XmlElement(name = "cve-id")
    public String cveId;
    @XmlElement(name = "bugtraq-id")
    public String bugtraqId;
    @XmlElement(name = "vuln-solution")
    public String solution;
}

dependency-check 扫描,网络安全,jenkins,运维,web安全,java,自动化

三、使用DependencyCheck扫描

/root/dependency-check/bin/dependency-check.sh --project "test-服务端第三方依赖CVE漏洞扫描报告" --scan "**/*.jar" -n -f JSON -o "/var/www/html/test-服务端第三方依赖CVE漏洞扫描报告.json"

四、输出自定义扫描报告

1、使用pot-tl自定义word模板

dependency-check 扫描,网络安全,jenkins,运维,web安全,java,自动化

2、解析json生成word报告

将上面扫描的“test-服务端第三方依赖CVE漏洞扫描报告.json”数据解析出来,填充到我们的自定义模板中,最终生成我们的word报告。

/**
     * 根据json报告解析漏洞信息并入库:方便后续直接构建word和excel
     * @param name   报告名称
     * @param sourePath   json报告路径
     * @param reportPath  word报告路径
     * @param gitHttpUrl  git的http地址
     * @param gitBranch   git分支
     * @return
     * @throws IOException
     */
    @GetMapping
    public String vulScanReport(String name, String sourePath,String reportPath,String gitHttpUrl,String gitBranch) throws IOException {
        //解析扫描的json报告,并将数据写入数据库
        int num = cnnvdService.analysisCveJsonv2(name,sourePath, gitHttpUrl, gitBranch);
        if(num>0){
            //读取扫描的漏洞数据,填充自定义模板,生成word报告
            String fileName = cnnvdService.createWord(name,reportPath,gitHttpUrl,gitBranch);
            return fileName;
        }else{
            return "";
        }
    }
package com.yunhuang.autosafe.common.service.impl;


import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import com.deepoove.poi.util.PoitlIOUtils;
import com.yunhuang.autosafe.common.entity.*;
import com.yunhuang.autosafe.common.mapper.CnnvdMapper;
import com.yunhuang.autosafe.common.service.*;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.*;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;


@Service
public class CnnvdServiceImpl extends ServiceImpl<CnnvdMapper, Cnnvd> implements CnnvdService {

    @Autowired
    private NvdMyService nvdMyService;
    @Autowired
    private CveService cveService;
    @Autowired
    private ScanDependencieService dependencieService;
    @Autowired
    private ScanVulnerabilitieService vulnerabilitieService;
    @Resource
    private RedisTemplate redisTemplate;

    private final static String REDIS_NVD_KEY = "cve_data";

    /**
     * 根据json报告解析漏洞信息并入库:方便后续直接构建word和excel
     * @param name   报告名称
     * @param sourePath   json报告路径
     * @param gitHttpUrl  git的http地址
     * @param gitBranch   git分支
     * @return
     * @throws IOException
     */
    @Override
    public Integer analysisCveJsonv2(String name, String sourePath, String gitHttpUrl, String gitBranch) throws IOException {
        //数据库统一记录时间
        Date createTime = new Date();
        String jsonStr = readFileContent(sourePath);
        JSONObject jsonObject = JSONUtil.parseObj(jsonStr);

        //依赖
        String dependencies = jsonObject.getStr("dependencies");
        JSONArray array = JSONUtil.parseArray(dependencies);

        //依赖下的漏洞
        List<ScanDependencie> dependencieList = JSONUtil.toList(array, ScanDependencie.class);
        System.out.println("--------------->依赖项总数:"+dependencieList.size());

        //漏洞详情列表
        List<ScanDependencie> dependencieVulList = new ArrayList<>();
        //漏洞清单汇总
        List<ScanVulnerabilitie> vulnerabilitiesAll = new ArrayList<>();
        //扫描到的漏洞清单
        List<String> cveScanList = new ArrayList<>();


        int i = 1;

        //遍历依赖:构建导出数据
        for(ScanDependencie d :dependencieList){
            if(d.getVulnerabilities()==null || d.getVulnerabilities().size()==0) continue;

            int pindex = i++;
            String depId = UUID.randomUUID().toString().replaceAll("-","");
            d.setId(depId);
            d.setName(name);
            d.setSortIndex(pindex);
            d.setFileName(d.getFileName().replaceAll(" ",""));
            d.setGitHttpUrl(gitHttpUrl);
            d.setGitBranch(gitBranch);
            d.setScanDate(createTime);
            if(StringUtils.isNotBlank(d.getDescription())) d.setDescription(d.getDescription().trim());

            int m = 1;
            //遍历依赖下的漏洞
            List<ScanVulnerabilitie> vulnerabilities = d.getVulnerabilities();
            for(ScanVulnerabilitie vul : vulnerabilities){
                if(vul.getName().indexOf("CVE")==-1) continue;

                //添加到扫描漏洞清单
                cveScanList.add(vul.getName());

                int index = m++;
                vul.setDependencieId(depId);
                vul.setSortIndex(index);
                vul.setSortIndexStr(pindex+"."+index);
                vul.setScanDate(createTime);

                vulnerabilitiesAll.add(vul);
            }

            dependencieVulList.add(d);
        }


        //清除之前的数据
        QueryWrapper<ScanDependencie> wrapper = new QueryWrapper<>();
        wrapper.eq("git_http_url",gitHttpUrl);
        List<ScanDependencie> oldList = dependencieService.list(wrapper);
        List<String> depIds = oldList.stream().map(ScanDependencie::getId).collect(Collectors.toList());

        if(depIds.size()>0){
            QueryWrapper<ScanVulnerabilitie> wrapper2 = new QueryWrapper<>();
            wrapper2.in("dependencie_id",depIds);
            vulnerabilitieService.remove(wrapper2);
        }
        dependencieService.remove(wrapper);

        //保存扫描到的依赖数据:dependencieVulList
        dependencieService.saveBatch(dependencieVulList);
        //保存扫描到的依赖数据:vulnerabilitiesAll
        vulnerabilitieService.saveBatch(vulnerabilitiesAll);
        System.out.println("--------------->有漏洞的依赖项:"+dependencieVulList.size());
        System.out.println("--------------->漏洞总数:"+vulnerabilitiesAll.size());
        System.out.println("");
        return vulnerabilitiesAll.size();
    }

    @Override
    public String createWord(String name, String reportPath, String gitHttpUrl, String gitBranch) throws IOException {

        //所有的有漏洞的依赖
        List<ScanDependencie> dependencieList = new ArrayList<>();
        //所有的漏洞清单
        List<ScanVulnerabilitie> vulList = new ArrayList<>();
        //漏洞清单分组
        Map<String, List<ScanVulnerabilitie>> listMap = new HashMap<>();
        //漏洞编码
        List<String> cveIds = new ArrayList<>();
        //对应的cnnvd信息(中文解释)
        Map<String, Cnnvd> cnnvdMap = new HashMap<>();
        //nvd漏洞原始信息(英文内容)
        Map<String, Cve> cveMap = new HashMap<>();

        QueryWrapper<ScanDependencie> wrapper1 = new QueryWrapper();
        wrapper1.eq("name",name).eq("git_http_url",gitHttpUrl).orderByAsc("sort_index");
        dependencieList = dependencieService.list(wrapper1);

        List<String> depIds = dependencieList.stream().map(ScanDependencie::getId).collect(Collectors.toList());
        if(depIds==null || depIds.size()==0) return null;

        QueryWrapper<ScanVulnerabilitie> wrapper2 = new QueryWrapper<>();
        wrapper2.in("dependencie_id",depIds).orderByAsc("id");
        vulList = vulnerabilitieService.list(wrapper2);
        //漏洞根据依赖id分组
        listMap = vulList.stream().collect(Collectors.groupingBy(ScanVulnerabilitie::getDependencieId));

        cveIds = vulList.stream().map(ScanVulnerabilitie::getName).distinct().collect(Collectors.toList());
        //根据漏洞编码查询cnnvd漏洞库
        QueryWrapper<Cnnvd> wrapper3 = new QueryWrapper<>();
        wrapper3.in("cve_id",cveIds);
        List<Cnnvd> nvdList = this.list(wrapper3);
        cnnvdMap = nvdList.stream().collect(Collectors.toMap(Cnnvd::getCveId, Function.identity()));

        //根据漏洞编码查询nvd漏洞库
        QueryWrapper<Cve> wrapper4 = new QueryWrapper<>();
        wrapper4.in("id",cveIds);
        List<Cve> cveList = cveService.list(wrapper4);
        cveMap = cveList.stream().collect(Collectors.toMap(Cve::getId, Function.identity()));


        //--------------------------------开始准备word数据----------------------------------//
        for(ScanDependencie d : dependencieList){

            if(!listMap.containsKey(d.getId())) continue;
            List<ScanVulnerabilitie> vuls = listMap.get(d.getId());
            for(ScanVulnerabilitie vul : vuls){
                if(cnnvdMap.containsKey(vul.getName())){
                    Cnnvd cnnvd = cnnvdMap.get(vul.getName());
                    if(cnnvd==null) continue;

                    vul.setSeverity(cnnvd.getSeverity());
                    vul.setVulnType(cnnvd.getVulnType());
                    vul.setCnnvd(cnnvd.getId());
                    vul.setTitle(cnnvd.getName());
                    vul.setDescription(cnnvd.getDescription());
                }else{
                    Cve cve = cveMap.get(vul.getName());
                    if(cve==null) continue;

                    vul.setSeverity(cve.getSeverity());
                    vul.setDescription(cve.getDescription());
                }
            }

            d.setVulnerabilities(vuls);
        }





        Map<String,Object> map = new HashMap<>();
        map.put("gitHttpUrl", gitHttpUrl);
        map.put("gitBranch", gitBranch);
        map.put("reportDate", DateUtil.today());
        map.put("projectName",name);
        map.put("vulnerabilitieDependencie",dependencieList.size());
        map.put("vulnerabilitieNum",vulList.size());
        map.put("dependencieList",dependencieList);
        map.put("depList",dependencieList);
        map.put("vulList",vulList);

        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
        Configure config = Configure.builder().bind("depList", policy).bind("vulList", policy).build();

        String fileName = name+"-第三方依赖CVE漏洞扫描报告.docx";
        String outputFile = reportPath+fileName;
        XWPFTemplate template = XWPFTemplate.compile(this.getClass().getClassLoader().getResourceAsStream("templates/第三方依赖CVE漏洞扫描报告模板.docx"),config).render(map);
        template.write(new FileOutputStream(outputFile));
        PoitlIOUtils.closeQuietlyMulti(template);
        return fileName;
    }





    public String readFileContent(String filePath) throws IOException {

        // 指定文件路径
        File file = new File(filePath);

        // 创建 BufferedReader 和 InputStreamReader 实例以读取文件
        FileInputStream fileInputStream = new FileInputStream(file);
        InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

        // 创建 StringBuilder 实例存储文件内容
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            sb.append(line);
            sb.append("\n"); // 每行后添加换行符
        }

        // 关闭 BufferedReader 和 InputStreamReader
        bufferedReader.close();
        inputStreamReader.close();
        fileInputStream.close();

        // 返回文件内容的字符串形式
        return sb.toString();
    }

}

dependency-check 扫描,网络安全,jenkins,运维,web安全,java,自动化

dependency-check 扫描,网络安全,jenkins,运维,web安全,java,自动化

五、使用jenkins实现自动化

我这里是使用jenkins的流水线SCM

def nameStr = 'xxx'
def gitHttpUrl = 'https://git.xxx.com/aaaa/xxx.git'
def gitsshUrl = 'git@git.xxx.com:aaaa/xxx.git'
def gitBranch = 'master'

pipeline {
    agent any
    stages {
        stage('拉取代码') {
            steps {
                script{
                    echo '----拉取代码----'
                    git branch: gitBranch, credentialsId: 'xxxxxxxx', url: gitHttpUrl
                }
            }
        }
        stage('编译jar包') {
            steps {
                echo '----编译jar包----'
                sh 'mvn clean package -DskipTests=true'
            }
        }
        stage('依赖检查') {
            steps {
                script{
                    echo '----第三方jar包依赖检查-----开始'
                    sh '/root/dependency-check/bin/dependency-check.sh --project "'+nameStr+'-服务端第三方依赖CVE漏洞扫描报告" --scan "**/*.jar" -n -f JSON -o "/var/www/html/'+nameStr+'-服务端第三方依赖CVE漏洞扫描报告.json"'
                    echo '----第三方jar包依赖检查-----结束'
                }
            }
        }
        stage('生成报告') {
            steps {
                script{
                    echo '----开始-生成报告----'
                    def response = sh(returnStdout: true, script: 'curl -G -s  --data-urlencode "name='+nameStr+'"  --data-urlencode  "sourePath=/var/www/html/'+nameStr+'-服务端第三方依赖CVE漏洞扫描报告.json" --data-urlencode "reportPath=/var/www/html/" --data-urlencode "gitHttpUrl='+gitHttpUrl+'"  --data-urlencode "gitBranch='+gitBranch+'"  "http://localhost:9000/api/v1/report"')
                    echo response
                    echo '报告访问地址:http://192.168.1.x/'+response
                    echo '----结束-生成报告----'
                }
            }
        }
    }
}

六、补充两句

1、DependencyCheck有对应的maven插件,开发者可以单独集成使用。

2、DependencyCheck可以直接输出html报告,全英文的,有很多信息我们并不关心。

3、本篇文章里面涉及到的提取cve数据和cnnvd数据到数据,解析json和生成word报告,我单独做了一个服务全部整合进去了,jenkins自动化其实就是拉代码,打jar包,调用DependencyCheck扫描jar包并输出json报告,然后再调用我自己整个的这个服务,把报告的名称,git仓库地址,json漏洞报告的路径,以及word最终存放的路径作为参数传进去。最后在jenkins控制点打印一个下载地址。方便下载扫描报告。

4、后续我有时间了会将这个项目整理一下放到开源网站上,静待后续...文章来源地址https://www.toymoban.com/news/detail-763097.html

到了这里,关于DependencyCheck+Jenkins扫描JAVA第三方依赖(CVE)漏洞的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 打包jar服务,如何提取第三方依赖包

    很多时候有这个需求,编译源码的时候无法联网,需要把源代码和依赖包一起离线用。 那么怎么把可以联网的工程依赖包,下载后提供给无网环境用呢。war的很多时候是默认提供好的,那么maven打包jar包服务的,assembly.xml 配置需要增加以下内容: 再执行maven打包就可以了。所

    2024年01月25日
    浏览(48)
  • Python之离线安装第三方库(依赖包)

    在一些服务器上,我们搭建完Python环境之后,因为服务器的网络限制原因,不能直接通过pip命令 下载安装 Python的依赖包。 因此,我们需要在可以正常上网的服务器上 下载 好所需的依赖包文件,然后拷贝到目标服务器,通过pip命令在目标服务器上进行 安装 。 requirements.txt文

    2024年02月06日
    浏览(43)
  • SpringBoot 自动扫描第三方包及spring.factories失效的问题

    Spring 依赖注入 就是要让spring找到要注入的类 并且识别到了 @Component、@Service 等注解。 1. 当在开发的第三方包里写明了 @Component、@Service 等等 2. 引入了包,不论第三方库的引入,还是本地jar。总之是要引入到工程的 这时候还加入不到 IOC 容器,那就说明SpringBoot工程没有扫描到

    2024年02月03日
    浏览(48)
  • 离线安装Python第三方库及依赖包

    在工作中经常需要在内网环境中安装python第三方库,使用从pypi上下载的whl文件来安装又经常遇到该库也需要依赖包,以至于并不能成功安装。 (1)查看所需第三方库安装是否需要依赖库(以requests为例) (2)使用命令将库及依赖包下载到本地(以requests为例) (3)将下载

    2024年02月13日
    浏览(47)
  • OpenAi最简洁的Java流式返回接入方式,没有第三方依赖,只需要使用Spring Boot即可!轻松构建你的带有聊天记忆、画图功能的chatgpt!

    OpenAi最简洁的Java流式返回接入方式,没有第三方依赖,只需要使用Spring Boot即可!轻松构建你的带有聊天记忆、画图功能的chatgpt! GitHub - NiuXiangQian/chatgpt-stream: OpenAi最简洁的Java流式返回接入方式,没有第三方依赖,只需要使用Spring Boot即可!轻松构建你的带有聊天记忆、画图

    2024年02月12日
    浏览(55)
  • 【微信小程序】从 npm 引入第三方依赖时提示依赖异常的解决方法

           微信小程序不允许使用 Node.js 的内建模块。但是部分第三方依赖(如 crypto-js)在运行时会尝试引入 Node.js 内建模块(实际非强制调用),这一举动被微信开发工具误以为是未知的依赖调用。 移除构建 npm 时生成的外部依赖项即可。 1. 找到并打开“/miniprogram_npm/crypto

    2024年02月15日
    浏览(48)
  • idea如何快速手动从mvn仓库中导入如所需要的第三方依赖

    当我们自己在进行项目的开发时,可能会遇到在项目开发时需要引入其他的依赖,通常我们是在配置文件中利用在dependencies标签中填写依赖的名字和坐标以及版本号,可是当我们利用标签遇到引入不了的依赖时,我们就需要下载对应的jar包放在本地mvn仓库中,然后再进行引入

    2024年02月13日
    浏览(42)
  • android使用fat-aar打包,本地aar和第三方依赖库以及遇到的问题

    需要把有个模块打包成aar,直接打包的话,模块中引用的jar、aar、第三方依赖库都不会打包进去。直接生成的aar缺少内部引用的以来,所以要用到fat-aar来把模块中用到的依赖也打包进去。 1.首先在项目的gradle加入 2.在repositories加入 3. 在需要打包aar的build.gradle中加入 4.第三方

    2024年02月15日
    浏览(40)
  • 修改node_modules中安装的依赖(如第三方ui组件样式)并在下次安装时保留

    场景:需要修改安装的某个ui库的样式或者其他依赖,直接去node_modules中修改后,重新安装,或者其他小伙伴的电脑上并不能同时修改 方案:用patch-package 可以保留修改 步骤一 安装 patch-package — npm i patch-package --save 步骤二 配置package.json script加上‘‘postinstall’’:“patch-

    2024年02月08日
    浏览(54)
  • Maven 配置本地jar,通过下载第三方jar包,然后手动配置maven jar包依赖 例如:IKExpression

    说明:有时候有一些jar包 maven中央仓库和阿里云仓库没有收录的jar包需要手动下载至本地进行手动添加maven依赖,就拿 IK表达式 IKExpression jar 包来说 第一步 下载IKExpression 包 没有这个包的同学可以点击下载阿里云盘分享   第二步 找到自己项目本地maven仓库位置,如果不清楚可

    2024年02月12日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包