|
31 | 31 | import com.fasterxml.jackson.databind.ObjectMapper; |
32 | 32 | import com.redhat.exhort.api.SeverityUtils; |
33 | 33 | import com.redhat.exhort.api.v4.Issue; |
34 | | -import com.redhat.exhort.api.v4.Severity; |
35 | 34 | import com.redhat.exhort.integration.providers.ProviderResponseHandler; |
36 | 35 | import com.redhat.exhort.model.CvssParser; |
37 | 36 | import com.redhat.exhort.model.DependencyTree; |
@@ -63,89 +62,93 @@ public Map<String, List<Issue>> responseToIssues( |
63 | 62 | .elements() |
64 | 63 | .forEachRemaining( |
65 | 64 | cveJson -> { |
66 | | - String cve = cveJson.get("id").asText().toUpperCase(); |
| 65 | + String cve = cveJson.get("cveMetadata").get("cveId").asText().toUpperCase(); |
67 | 66 | cvesJson.put(cve, cveJson); |
68 | 67 | }); |
69 | 68 | response |
70 | 69 | .get("analysis") |
71 | 70 | .fields() |
72 | 71 | .forEachRemaining( |
73 | | - e -> { |
74 | | - String ref = e.getKey(); |
| 72 | + analysisEntry -> { |
| 73 | + String ref = analysisEntry.getKey(); |
75 | 74 | if (!issuesData.containsKey(ref)) { |
76 | 75 | issuesData.put(ref, new ArrayList<>()); |
77 | 76 | } |
78 | 77 | List<Issue> issues = issuesData.get(ref); |
79 | | - e.getValue() |
| 78 | + analysisEntry |
| 79 | + .getValue() |
80 | 80 | .forEach( |
81 | 81 | analysis -> { |
82 | 82 | String vendor = analysis.get("vendor").asText(); |
83 | 83 | analysis |
84 | 84 | .get("vulnerable") |
85 | 85 | .forEach( |
86 | 86 | vulnerable -> { |
87 | | - String vulnId = vulnerable.get("id").asText().toUpperCase(); |
88 | | - Issue issue = new Issue().id(vulnId).source(vendor); |
89 | | - vulnerable |
90 | | - .get("severity") |
91 | | - .forEach( |
92 | | - severity -> { |
93 | | - if (severity |
94 | | - .get("source") |
95 | | - .asText() |
96 | | - .toLowerCase() |
97 | | - .equals(vendor)) { |
98 | | - Double dscore = severity.get("score").asDouble(0); |
99 | | - issue.cvssScore(dscore.floatValue()); |
100 | | - } |
101 | | - }); |
102 | | - |
103 | | - if (isCVE(vulnId)) { |
104 | | - issue.addCvesItem(vulnId); |
| 87 | + var issue = newIssueFromVulnerability(vulnerable, vendor); |
| 88 | + if (issue.getCves() != null && !issue.getCves().isEmpty()) { |
| 89 | + completeIssueData(issue, cvesJson); |
| 90 | + issues.add(issue); |
105 | 91 | } |
106 | | - vulnerable |
107 | | - .get("aliases") |
108 | | - .forEach( |
109 | | - a -> { |
110 | | - String alias = a.asText(); |
111 | | - if (isCVE(alias)) { |
112 | | - issue.addCvesItem(alias.toUpperCase()); |
113 | | - } |
114 | | - ; |
115 | | - }); |
116 | | - completeIssueData(issue, cvesJson); |
117 | | - issues.add(issue); |
118 | 92 | }); |
119 | 93 | }); |
120 | 94 | }); |
121 | 95 |
|
122 | 96 | return issuesData; |
123 | 97 | } |
124 | 98 |
|
| 99 | + private Issue newIssueFromVulnerability(JsonNode vulnerable, String vendor) { |
| 100 | + var vulnId = vulnerable.get("id").asText().toUpperCase(); |
| 101 | + var issue = new Issue().id(vulnId).source(vendor); |
| 102 | + vulnerable |
| 103 | + .get("severity") |
| 104 | + .forEach( |
| 105 | + severity -> { |
| 106 | + if (severity.get("source").asText().toLowerCase().equals(vendor)) { |
| 107 | + Double dscore = severity.get("score").asDouble(0); |
| 108 | + issue.cvssScore(dscore.floatValue()); |
| 109 | + } |
| 110 | + }); |
| 111 | + |
| 112 | + if (isCVE(vulnId)) { |
| 113 | + issue.addCvesItem(vulnId); |
| 114 | + } |
| 115 | + vulnerable |
| 116 | + .get("aliases") |
| 117 | + .forEach( |
| 118 | + a -> { |
| 119 | + String alias = a.asText(); |
| 120 | + if (isCVE(alias)) { |
| 121 | + issue.addCvesItem(alias.toUpperCase()); |
| 122 | + } |
| 123 | + ; |
| 124 | + }); |
| 125 | + return issue; |
| 126 | + } |
| 127 | + |
125 | 128 | private void completeIssueData(Issue issue, Map<String, JsonNode> cvesJson) { |
126 | 129 | Optional<String> firstCve = |
127 | 130 | issue.getCves().stream().filter(cve -> cvesJson.keySet().contains(cve)).findFirst(); |
128 | 131 | if (firstCve.isEmpty()) { |
129 | | - issue.severity(SeverityUtils.fromScore(issue.getCvssScore())); |
130 | 132 | issue.unique(Boolean.TRUE); |
131 | 133 | return; |
132 | 134 | } |
133 | | - JsonNode cveJson = cvesJson.get(firstCve.get()); |
134 | | - issue.title(cveJson.get("cisaVulnerabilityName").asText()); |
135 | | - |
136 | | - cveJson |
137 | | - .get("metrics") |
138 | | - .get("cvssMetricV31") |
139 | | - .forEach( |
140 | | - metric -> { |
141 | | - if ("Primary".equalsIgnoreCase(metric.get("type").asText())) { |
142 | | - issue.cvss( |
143 | | - CvssParser.fromVectorString( |
144 | | - metric.get("cvssData").get("vectorString").asText())); |
145 | | - issue.severity( |
146 | | - Severity.fromValue(metric.get("cvssData").get("baseSeverity").asText())); |
147 | | - } |
148 | | - }); |
| 135 | + issue.severity(SeverityUtils.fromScore(issue.getCvssScore())); |
| 136 | + var cveJson = cvesJson.get(firstCve.get()); |
| 137 | + var cnaContainer = cveJson.get("containers").get("cna"); |
| 138 | + var title = cnaContainer.get("title"); |
| 139 | + if (title != null) { |
| 140 | + issue.title(title.asText()); |
| 141 | + } |
| 142 | + var metrics = cnaContainer.get("metrics"); |
| 143 | + if (metrics != null) { |
| 144 | + metrics.forEach( |
| 145 | + metric -> { |
| 146 | + if (metric.has("cvssV3_1")) { |
| 147 | + issue.cvss( |
| 148 | + CvssParser.fromVectorString(metric.get("cvssV3_1").get("vectorString").asText())); |
| 149 | + } |
| 150 | + }); |
| 151 | + } |
149 | 152 | } |
150 | 153 |
|
151 | 154 | private boolean isCVE(String vulnerabilityId) { |
|
0 commit comments