当前位置:   article > 正文

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

dependency-check

原理说明:首先使用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

3、安装DependencyCheck

开箱即用:

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

命令如下:

  1. dependency-check.sh --project "第三方依赖CVE漏洞扫描报告" --scan "**/*.jar" -n -f JSON -o "第三方依赖CVE漏洞扫描报告.json"
  2. --project 给这次扫描的项目起个名称
  3. --scan 要扫描的文件路径
  4. -n 此次扫描不更新漏洞库:不加这个会先去更新漏洞库,然后再进行扫描
  5. -f 要输出的报告格式,有HTMLJSON
  6. -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

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

  1. package com.yunhuang.autosafe.common.service.impl;
  2. import cn.hutool.core.date.DateUtil;
  3. import cn.hutool.core.io.resource.ClassPathResource;
  4. import cn.hutool.json.JSONObject;
  5. import cn.hutool.json.JSONUtil;
  6. import com.alibaba.fastjson.JSON;
  7. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  8. import com.yunhuang.autosafe.common.cve.CveObj;
  9. import com.yunhuang.autosafe.common.entity.Cve;
  10. import com.yunhuang.autosafe.common.mapper.CveMapper;
  11. import com.yunhuang.autosafe.common.service.CveService;
  12. import org.apache.commons.io.FileUtils;
  13. import org.springframework.stereotype.Service;
  14. import java.io.*;
  15. import java.nio.file.Files;
  16. import java.nio.file.Paths;
  17. import java.util.ArrayList;
  18. import java.util.List;
  19. @Service
  20. public class CveServiceImpl extends ServiceImpl<CveMapper, Cve> implements CveService {
  21. /**
  22. * 拉去cve漏洞数据库
  23. * @param loadType 0-全量初始化 1-增量更新
  24. */
  25. @Override
  26. public void loadCveData(Integer loadType) {
  27. String workspace = System.getProperty("user.dir");
  28. String nvdcachePath = workspace + "/nvdcache";
  29. System.out.println("工作空间="+workspace);
  30. //1、拉取NVD的cve漏洞文件
  31. syncCveList(workspace,nvdcachePath);
  32. //2、将拉取到的json文件进行解析并提取为对象,转存mysql
  33. if(0==loadType){
  34. readFilesAll(nvdcachePath);
  35. }else if(1==loadType){
  36. updateRecentCve(nvdcachePath);
  37. }
  38. }
  39. /**
  40. * 拉取NVD的cve漏洞文件(json文件)
  41. * @param workspace 工作空间:默认当前jar的路径
  42. * @param nvdcachePath 存储漏洞库文件(json文件)的路径
  43. */
  44. public void syncCveList(String workspace,String nvdcachePath) {
  45. //1、检查缓存目录是否存在
  46. File nvdcacheFile = new File(nvdcachePath);
  47. if(!nvdcacheFile.exists()){
  48. System.out.println("缓存目录不存在,创建!");
  49. nvdcacheFile.mkdirs();
  50. }
  51. String nistDataMirror = workspace + "/nist-data-mirror.jar";
  52. File nistDataMirrorFile = new File(nistDataMirror);
  53. if(!nistDataMirrorFile.exists()){
  54. System.out.println("nist-data-mirror.jar不存在,创建!");
  55. try{
  56. ClassPathResource classPathResource = new ClassPathResource("utils/nist-data-mirror.jar");
  57. InputStream inputStream = classPathResource.getStream();
  58. String destPath = workspace + "/nist-data-mirror.jar";
  59. FileUtils.copyInputStreamToFile(inputStream, new File(destPath));
  60. }catch (Exception e){
  61. e.printStackTrace();
  62. }
  63. }
  64. //1、拉取NVD的cve漏洞文件
  65. String command = "java -jar "+workspace+"/nist-data-mirror.jar "+nvdcachePath;
  66. try {
  67. Process process = Runtime.getRuntime().exec(command);
  68. // 读取命令执行的输出
  69. InputStream inputStream = process.getInputStream();
  70. BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
  71. String line;
  72. while ((line = reader.readLine()) != null) {
  73. System.out.println(line);
  74. }
  75. // 等待命令执行结束
  76. int exitCode = process.waitFor();
  77. System.out.println("命令执行结束,退出码:" + exitCode);
  78. } catch (IOException | InterruptedException e) {
  79. e.printStackTrace();
  80. }
  81. }
  82. private void readFilesAll(String nvdcachePath){
  83. System.out.println("------------全量初始化------------");
  84. File nvdcacheFile = new File(nvdcachePath);
  85. File[] files = nvdcacheFile.listFiles((dir, name) -> name.toLowerCase().endsWith(".json"));
  86. for(File f : files){
  87. System.out.println(f.getAbsolutePath());
  88. parseJson(f.getAbsolutePath());
  89. System.out.println("");
  90. }
  91. System.out.println("------------全量初始化-完成------------");
  92. }
  93. private void updateRecentCve(String nvdcachePath){
  94. System.out.println("------------增量更新------------");
  95. File nvdcacheFile = new File(nvdcachePath);
  96. File[] files = nvdcacheFile.listFiles((dir, name) -> name.toLowerCase().endsWith(DateUtil.thisYear()+".json") || name.toLowerCase().endsWith("modified.json") || name.toLowerCase().endsWith("recent.json"));
  97. for(File f : files){
  98. System.out.println(f.getAbsolutePath());
  99. parseJson(f.getAbsolutePath());
  100. System.out.println("");
  101. }
  102. System.out.println("------------增量更新-完成------------");
  103. }
  104. private void parseJson(String filePath){
  105. try {
  106. String jsonStr = new String( Files.readAllBytes( Paths.get(filePath)));
  107. JSONObject jsonObject = JSONUtil.parseObj(jsonStr);
  108. String CVE_Items = jsonObject.getStr("CVE_Items");
  109. List<CveObj> cveObjs = JSONUtil.toList(CVE_Items, CveObj.class);
  110. List<Cve> list = new ArrayList<>();
  111. // 对解析后的对象数组进行操作
  112. for (CveObj obj : cveObjs) {
  113. Cve cve = new Cve();
  114. cve.setId(obj.getCve().getCVE_data_meta().getID());
  115. try{
  116. cve.setSeverity(obj.getImpact().getBaseMetricV2().getSeverity()+"");
  117. }catch (Exception e){
  118. }
  119. cve.setDescription(JSON.toJSONString(obj.getCve().getDescription().getDescription_data()).replaceAll("'",""));
  120. cve.setPublishedDate(DateUtil.parseDate(obj.getPublishedDate()));
  121. cve.setLastModifiedDate(DateUtil.parseDate(obj.getLastModifiedDate()));
  122. list.add(cve);
  123. }
  124. this.saveOrUpdateBatch(list);
  125. } catch (IOException e) {
  126. e.printStackTrace();
  127. }
  128. }
  129. }

2、获取cnnvd漏洞库

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

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

获取方式:

3、转换为自定义漏洞库

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

  1. @GetMapping
  2. public void insertCnnvd(int type) throws JAXBException {
  3. if(type==0){
  4. for(int i=1999;i<=2023;i++){
  5. System.out.println("-------->开始读取"+i+"年数据:");
  6. List<Cnnvd> nvdList = parseXml(i);
  7. System.out.println("-------->成功读取"+i+"年数据:"+nvdList.size());
  8. cnnvdService.saveOrUpdateBatch(nvdList);
  9. System.out.println("-------->成功写入数据:"+nvdList.size());
  10. System.out.println("");
  11. System.out.println("");
  12. }
  13. }else{
  14. System.out.println("-------->开始读取"+DateUtil.thisYear()+"年数据:");
  15. List<Cnnvd> cnnvdList = parseXml(2023);
  16. System.out.println("-------->成功读取"+DateUtil.thisYear()+"年数据:"+cnnvdList.size());
  17. cnnvdService.saveOrUpdateBatch(cnnvdList);
  18. System.out.println("-------->成功写入数据:"+cnnvdList.size());
  19. }
  20. }
  21. public List<Cnnvd> parseXml(int fileName) throws JAXBException {
  22. //可能的问题:[org.xml.sax.SAXParseException; lineNumber: 2292; columnNumber: 191; 元素类型 "use" 必须由匹配的结束标记 "</use>" 终止。]] with root cause
  23. //解决的方案:在内网的签名添加字符串:<![CDATA[ 在内网的结尾添加字符串:]]>
  24. InputStream stream = this.getClass().getClassLoader().getResourceAsStream("cnnvd/"+fileName+".xml");
  25. JAXBContext jaxbContext = JAXBContext.newInstance(VulnerabilityList.class);
  26. Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
  27. VulnerabilityList vulnerabilityList = (VulnerabilityList) jaxbUnmarshaller.unmarshal(stream);
  28. List<Cnnvd> vulnerabilities = vulnerabilityList.vulnerabilities;
  29. return vulnerabilities;
  30. }
  1. @Data
  2. @XmlRootElement(name = "entry")
  3. @XmlAccessorType(XmlAccessType.FIELD)
  4. public class Cnnvd implements Serializable {
  5. @TableId(type = IdType.INPUT)
  6. @XmlElement(name = "vuln-id")
  7. public String id;
  8. @XmlElement(name = "name")
  9. public String name;
  10. @XmlElement(name = "published")
  11. public String published;
  12. @XmlElement(name = "modified")
  13. public String modified;
  14. @XmlElement(name = "source")
  15. public String source;
  16. @XmlElement(name = "severity")
  17. public String severity;
  18. @XmlElement(name = "vuln-type")
  19. public String vulnType;
  20. @XmlElement(name = "vuln-descript")
  21. public String description;
  22. @XmlElement(name = "cve-id")
  23. public String cveId;
  24. @XmlElement(name = "bugtraq-id")
  25. public String bugtraqId;
  26. @XmlElement(name = "vuln-solution")
  27. public String solution;
  28. }

三、使用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模板

2、解析json生成word报告

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

  1. /**
  2. * 根据json报告解析漏洞信息并入库:方便后续直接构建word和excel
  3. * @param name 报告名称
  4. * @param sourePath json报告路径
  5. * @param reportPath word报告路径
  6. * @param gitHttpUrl git的http地址
  7. * @param gitBranch git分支
  8. * @return
  9. * @throws IOException
  10. */
  11. @GetMapping
  12. public String vulScanReport(String name, String sourePath,String reportPath,String gitHttpUrl,String gitBranch) throws IOException {
  13. //解析扫描的json报告,并将数据写入数据库
  14. int num = cnnvdService.analysisCveJsonv2(name,sourePath, gitHttpUrl, gitBranch);
  15. if(num>0){
  16. //读取扫描的漏洞数据,填充自定义模板,生成word报告
  17. String fileName = cnnvdService.createWord(name,reportPath,gitHttpUrl,gitBranch);
  18. return fileName;
  19. }else{
  20. return "";
  21. }
  22. }
  1. package com.yunhuang.autosafe.common.service.impl;
  2. import cn.hutool.core.date.DateUtil;
  3. import cn.hutool.json.JSONArray;
  4. import cn.hutool.json.JSONObject;
  5. import cn.hutool.json.JSONUtil;
  6. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  7. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  8. import com.deepoove.poi.XWPFTemplate;
  9. import com.deepoove.poi.config.Configure;
  10. import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
  11. import com.deepoove.poi.util.PoitlIOUtils;
  12. import com.yunhuang.autosafe.common.entity.*;
  13. import com.yunhuang.autosafe.common.mapper.CnnvdMapper;
  14. import com.yunhuang.autosafe.common.service.*;
  15. import lombok.Data;
  16. import org.apache.commons.lang3.StringUtils;
  17. import org.springframework.beans.factory.annotation.Autowired;
  18. import org.springframework.data.redis.core.RedisTemplate;
  19. import org.springframework.stereotype.Service;
  20. import javax.annotation.Resource;
  21. import java.io.*;
  22. import java.util.*;
  23. import java.util.function.Function;
  24. import java.util.stream.Collectors;
  25. @Service
  26. public class CnnvdServiceImpl extends ServiceImpl<CnnvdMapper, Cnnvd> implements CnnvdService {
  27. @Autowired
  28. private NvdMyService nvdMyService;
  29. @Autowired
  30. private CveService cveService;
  31. @Autowired
  32. private ScanDependencieService dependencieService;
  33. @Autowired
  34. private ScanVulnerabilitieService vulnerabilitieService;
  35. @Resource
  36. private RedisTemplate redisTemplate;
  37. private final static String REDIS_NVD_KEY = "cve_data";
  38. /**
  39. * 根据json报告解析漏洞信息并入库:方便后续直接构建word和excel
  40. * @param name 报告名称
  41. * @param sourePath json报告路径
  42. * @param gitHttpUrl git的http地址
  43. * @param gitBranch git分支
  44. * @return
  45. * @throws IOException
  46. */
  47. @Override
  48. public Integer analysisCveJsonv2(String name, String sourePath, String gitHttpUrl, String gitBranch) throws IOException {
  49. //数据库统一记录时间
  50. Date createTime = new Date();
  51. String jsonStr = readFileContent(sourePath);
  52. JSONObject jsonObject = JSONUtil.parseObj(jsonStr);
  53. //依赖
  54. String dependencies = jsonObject.getStr("dependencies");
  55. JSONArray array = JSONUtil.parseArray(dependencies);
  56. //依赖下的漏洞
  57. List<ScanDependencie> dependencieList = JSONUtil.toList(array, ScanDependencie.class);
  58. System.out.println("--------------->依赖项总数:"+dependencieList.size());
  59. //漏洞详情列表
  60. List<ScanDependencie> dependencieVulList = new ArrayList<>();
  61. //漏洞清单汇总
  62. List<ScanVulnerabilitie> vulnerabilitiesAll = new ArrayList<>();
  63. //扫描到的漏洞清单
  64. List<String> cveScanList = new ArrayList<>();
  65. int i = 1;
  66. //遍历依赖:构建导出数据
  67. for(ScanDependencie d :dependencieList){
  68. if(d.getVulnerabilities()==null || d.getVulnerabilities().size()==0) continue;
  69. int pindex = i++;
  70. String depId = UUID.randomUUID().toString().replaceAll("-","");
  71. d.setId(depId);
  72. d.setName(name);
  73. d.setSortIndex(pindex);
  74. d.setFileName(d.getFileName().replaceAll(" ",""));
  75. d.setGitHttpUrl(gitHttpUrl);
  76. d.setGitBranch(gitBranch);
  77. d.setScanDate(createTime);
  78. if(StringUtils.isNotBlank(d.getDescription())) d.setDescription(d.getDescription().trim());
  79. int m = 1;
  80. //遍历依赖下的漏洞
  81. List<ScanVulnerabilitie> vulnerabilities = d.getVulnerabilities();
  82. for(ScanVulnerabilitie vul : vulnerabilities){
  83. if(vul.getName().indexOf("CVE")==-1) continue;
  84. //添加到扫描漏洞清单
  85. cveScanList.add(vul.getName());
  86. int index = m++;
  87. vul.setDependencieId(depId);
  88. vul.setSortIndex(index);
  89. vul.setSortIndexStr(pindex+"."+index);
  90. vul.setScanDate(createTime);
  91. vulnerabilitiesAll.add(vul);
  92. }
  93. dependencieVulList.add(d);
  94. }
  95. //清除之前的数据
  96. QueryWrapper<ScanDependencie> wrapper = new QueryWrapper<>();
  97. wrapper.eq("git_http_url",gitHttpUrl);
  98. List<ScanDependencie> oldList = dependencieService.list(wrapper);
  99. List<String> depIds = oldList.stream().map(ScanDependencie::getId).collect(Collectors.toList());
  100. if(depIds.size()>0){
  101. QueryWrapper<ScanVulnerabilitie> wrapper2 = new QueryWrapper<>();
  102. wrapper2.in("dependencie_id",depIds);
  103. vulnerabilitieService.remove(wrapper2);
  104. }
  105. dependencieService.remove(wrapper);
  106. //保存扫描到的依赖数据:dependencieVulList
  107. dependencieService.saveBatch(dependencieVulList);
  108. //保存扫描到的依赖数据:vulnerabilitiesAll
  109. vulnerabilitieService.saveBatch(vulnerabilitiesAll);
  110. System.out.println("--------------->有漏洞的依赖项:"+dependencieVulList.size());
  111. System.out.println("--------------->漏洞总数:"+vulnerabilitiesAll.size());
  112. System.out.println("");
  113. return vulnerabilitiesAll.size();
  114. }
  115. @Override
  116. public String createWord(String name, String reportPath, String gitHttpUrl, String gitBranch) throws IOException {
  117. //所有的有漏洞的依赖
  118. List<ScanDependencie> dependencieList = new ArrayList<>();
  119. //所有的漏洞清单
  120. List<ScanVulnerabilitie> vulList = new ArrayList<>();
  121. //漏洞清单分组
  122. Map<String, List<ScanVulnerabilitie>> listMap = new HashMap<>();
  123. //漏洞编码
  124. List<String> cveIds = new ArrayList<>();
  125. //对应的cnnvd信息(中文解释)
  126. Map<String, Cnnvd> cnnvdMap = new HashMap<>();
  127. //nvd漏洞原始信息(英文内容)
  128. Map<String, Cve> cveMap = new HashMap<>();
  129. QueryWrapper<ScanDependencie> wrapper1 = new QueryWrapper();
  130. wrapper1.eq("name",name).eq("git_http_url",gitHttpUrl).orderByAsc("sort_index");
  131. dependencieList = dependencieService.list(wrapper1);
  132. List<String> depIds = dependencieList.stream().map(ScanDependencie::getId).collect(Collectors.toList());
  133. if(depIds==null || depIds.size()==0) return null;
  134. QueryWrapper<ScanVulnerabilitie> wrapper2 = new QueryWrapper<>();
  135. wrapper2.in("dependencie_id",depIds).orderByAsc("id");
  136. vulList = vulnerabilitieService.list(wrapper2);
  137. //漏洞根据依赖id分组
  138. listMap = vulList.stream().collect(Collectors.groupingBy(ScanVulnerabilitie::getDependencieId));
  139. cveIds = vulList.stream().map(ScanVulnerabilitie::getName).distinct().collect(Collectors.toList());
  140. //根据漏洞编码查询cnnvd漏洞库
  141. QueryWrapper<Cnnvd> wrapper3 = new QueryWrapper<>();
  142. wrapper3.in("cve_id",cveIds);
  143. List<Cnnvd> nvdList = this.list(wrapper3);
  144. cnnvdMap = nvdList.stream().collect(Collectors.toMap(Cnnvd::getCveId, Function.identity()));
  145. //根据漏洞编码查询nvd漏洞库
  146. QueryWrapper<Cve> wrapper4 = new QueryWrapper<>();
  147. wrapper4.in("id",cveIds);
  148. List<Cve> cveList = cveService.list(wrapper4);
  149. cveMap = cveList.stream().collect(Collectors.toMap(Cve::getId, Function.identity()));
  150. //--------------------------------开始准备word数据----------------------------------//
  151. for(ScanDependencie d : dependencieList){
  152. if(!listMap.containsKey(d.getId())) continue;
  153. List<ScanVulnerabilitie> vuls = listMap.get(d.getId());
  154. for(ScanVulnerabilitie vul : vuls){
  155. if(cnnvdMap.containsKey(vul.getName())){
  156. Cnnvd cnnvd = cnnvdMap.get(vul.getName());
  157. if(cnnvd==null) continue;
  158. vul.setSeverity(cnnvd.getSeverity());
  159. vul.setVulnType(cnnvd.getVulnType());
  160. vul.setCnnvd(cnnvd.getId());
  161. vul.setTitle(cnnvd.getName());
  162. vul.setDescription(cnnvd.getDescription());
  163. }else{
  164. Cve cve = cveMap.get(vul.getName());
  165. if(cve==null) continue;
  166. vul.setSeverity(cve.getSeverity());
  167. vul.setDescription(cve.getDescription());
  168. }
  169. }
  170. d.setVulnerabilities(vuls);
  171. }
  172. Map<String,Object> map = new HashMap<>();
  173. map.put("gitHttpUrl", gitHttpUrl);
  174. map.put("gitBranch", gitBranch);
  175. map.put("reportDate", DateUtil.today());
  176. map.put("projectName",name);
  177. map.put("vulnerabilitieDependencie",dependencieList.size());
  178. map.put("vulnerabilitieNum",vulList.size());
  179. map.put("dependencieList",dependencieList);
  180. map.put("depList",dependencieList);
  181. map.put("vulList",vulList);
  182. LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
  183. Configure config = Configure.builder().bind("depList", policy).bind("vulList", policy).build();
  184. String fileName = name+"-第三方依赖CVE漏洞扫描报告.docx";
  185. String outputFile = reportPath+fileName;
  186. XWPFTemplate template = XWPFTemplate.compile(this.getClass().getClassLoader().getResourceAsStream("templates/第三方依赖CVE漏洞扫描报告模板.docx"),config).render(map);
  187. template.write(new FileOutputStream(outputFile));
  188. PoitlIOUtils.closeQuietlyMulti(template);
  189. return fileName;
  190. }
  191. public String readFileContent(String filePath) throws IOException {
  192. // 指定文件路径
  193. File file = new File(filePath);
  194. // 创建 BufferedReader 和 InputStreamReader 实例以读取文件
  195. FileInputStream fileInputStream = new FileInputStream(file);
  196. InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");
  197. BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
  198. // 创建 StringBuilder 实例存储文件内容
  199. StringBuilder sb = new StringBuilder();
  200. String line;
  201. while ((line = bufferedReader.readLine()) != null) {
  202. sb.append(line);
  203. sb.append("\n"); // 每行后添加换行符
  204. }
  205. // 关闭 BufferedReader 和 InputStreamReader
  206. bufferedReader.close();
  207. inputStreamReader.close();
  208. fileInputStream.close();
  209. // 返回文件内容的字符串形式
  210. return sb.toString();
  211. }
  212. }

五、使用jenkins实现自动化

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

  1. def nameStr = 'xxx'
  2. def gitHttpUrl = 'https://git.xxx.com/aaaa/xxx.git'
  3. def gitsshUrl = 'git@git.xxx.com:aaaa/xxx.git'
  4. def gitBranch = 'master'
  5. pipeline {
  6. agent any
  7. stages {
  8. stage('拉取代码') {
  9. steps {
  10. script{
  11. echo '----拉取代码----'
  12. git branch: gitBranch, credentialsId: 'xxxxxxxx', url: gitHttpUrl
  13. }
  14. }
  15. }
  16. stage('编译jar包') {
  17. steps {
  18. echo '----编译jar包----'
  19. sh 'mvn clean package -DskipTests=true'
  20. }
  21. }
  22. stage('依赖检查') {
  23. steps {
  24. script{
  25. echo '----第三方jar包依赖检查-----开始'
  26. sh '/root/dependency-check/bin/dependency-check.sh --project "'+nameStr+'-服务端第三方依赖CVE漏洞扫描报告" --scan "**/*.jar" -n -f JSON -o "/var/www/html/'+nameStr+'-服务端第三方依赖CVE漏洞扫描报告.json"'
  27. echo '----第三方jar包依赖检查-----结束'
  28. }
  29. }
  30. }
  31. stage('生成报告') {
  32. steps {
  33. script{
  34. echo '----开始-生成报告----'
  35. 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"')
  36. echo response
  37. echo '报告访问地址:http://192.168.1.x/'+response
  38. echo '----结束-生成报告----'
  39. }
  40. }
  41. }
  42. }
  43. }

六、补充两句

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

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

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

4、后续我有时间了会将这个项目整理一下放到开源网站上,静待后续...

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/木道寻08/article/detail/976835
推荐阅读
相关标签
  

闽ICP备14008679号