1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.owasp.dependencycheck.data.nvdcve;
19
20 import io.github.jeremylong.openvulnerability.client.nvd.Config;
21
22 import java.util.Objects;
23 import java.util.stream.Collectors;
24 import org.owasp.dependencycheck.data.nvd.ecosystem.Ecosystem;
25
26 import io.github.jeremylong.openvulnerability.client.nvd.DefCveItem;
27 import io.github.jeremylong.openvulnerability.client.nvd.LangString;
28 import io.github.jeremylong.openvulnerability.client.nvd.Node;
29 import java.util.List;
30 import org.owasp.dependencycheck.dependency.VulnerableSoftware;
31
32
33
34
35
36
37
38
39 public class CveItemOperator {
40
41
42
43
44
45 private final String cpeStartsWithFilter;
46
47
48
49
50
51
52 public CveItemOperator(String cpeStartsWithFilter) {
53 this.cpeStartsWithFilter = cpeStartsWithFilter;
54 }
55
56
57
58
59
60
61
62 public String extractDescription(DefCveItem cve) {
63 return cve.getCve().getDescriptions().stream().filter((desc)
64 -> "en".equals(desc.getLang())).map(LangString::getValue).collect(Collectors.joining(" "));
65 }
66
67
68
69
70
71
72
73
74
75
76
77
78 private String extractEcosystem(String baseEcosystem, String vendor, String product, String targetSw) {
79
80
81
82
83 if (("mysql".equals(vendor) && "mysql".equals(product))
84 || ("postgresql".equals(vendor) && "postgresql".equals(product))
85 || ("picketlink".equals(vendor) && "picketlink".equals(product))
86 || ("libxl_project".equals(vendor) && "libxl".equals(product))
87 || ("ocaml".equals(vendor) && "postgresql-ocaml".equals(product))
88 || ("curses_project".equals(vendor) && "curses".equals(product))
89 || ("dalekjs".equals(vendor) && "dalekjs".equals(product))
90 || ("microsoft".equals(vendor) && "internet_explorer".equals(product))
91 || ("jenkins".equals(vendor) && "ssh_credentials".equals(product))
92 || ("kubernetes".equals(vendor) && "kubernetes".equals(product))
93 || ("gnome".equals(vendor) && "nautilus-python".equals(product))
94 || ("apache".equals(vendor) && "qpid_proton".equals(product))
95 || ("mysql-ocaml".equals(vendor) && "mysql-ocaml".equals(product))
96 || ("google".equals(vendor) && "chrome".equals(product))
97 || ("canonical".equals(vendor) && "ltsp_display_manager".equals(product))
98 || ("gnome".equals(vendor) && "vala".equals(product))
99 || ("apple".equals(vendor) && "safari".equals(product))
100 || ("mapbox".equals(vendor) && "npm-test-sqlite3-trunk".equals(product))
101 || ("apple".equals(vendor) && "webkit".equals(product))
102 || ("mozilla".equals(vendor) && "firefox".equals(product))
103 || ("apache".equals(vendor) && "thrift".equals(product))
104 || ("apache".equals(vendor) && "qpid".equals(product))
105 || ("mozilla".equals(vendor) && "thunderbird".equals(product))
106 || ("mozilla".equals(vendor) && "firefox_esr".equals(product))
107 || ("redhat".equals(vendor) && "jboss_amq_clients_2".equals(product))
108 || ("node-opencv_project".equals(vendor) && "node-opencv".equals(product))
109 || ("mozilla".equals(vendor) && "seamonkey".equals(product))
110 || ("mozilla".equals(vendor) && "thunderbird_esr".equals(product))
111 || ("mnet_soft_factory".equals(vendor) && "nodemanager_professional".equals(product))
112 || ("mozilla".equals(vendor) && "mozilla_suite".equals(product))
113 || ("theforeman".equals(vendor) && "hammer_cli".equals(product))
114 || ("ibm".equals(vendor) && "websphere_application_server".equals(product))
115 || ("sap".equals(vendor) && "hana_extend_application_services".equals(product))
116 || ("apache".equals(vendor) && "zookeeper".equals(product))) {
117 return null;
118 }
119
120 if ("ibm".equals(vendor)
121 && "java".equals(product)) {
122 return Ecosystem.NATIVE;
123 }
124
125 if ("oracle".equals(vendor)
126 && "vm".equals(product)) {
127 return Ecosystem.NATIVE;
128 }
129 switch (targetSw) {
130 case "asp.net":
131 case "c#":
132 case ".net":
133 case "dotnetnuke":
134 return Ecosystem.DOTNET;
135 case "android":
136 case "java":
137 return Ecosystem.JAVA;
138 case "c/c++":
139 case "borland_c++":
140 case "visual_c++":
141 case "gnu_c++":
142 case "linux_kernel":
143 case "linux":
144 case "unix":
145 case "suse_linux":
146 case "redhat_enterprise_linux":
147 case "debian":
148 return Ecosystem.NATIVE;
149 case "coldfusion":
150 return Ecosystem.COLDFUSION;
151 case "ios":
152 case "iphone":
153 case "ipad":
154 case "iphone_os":
155 return Ecosystem.IOS;
156 case "jquery":
157 return Ecosystem.JAVASCRIPT;
158 case "node.js":
159 case "nodejs":
160 return Ecosystem.NODEJS;
161 case "perl":
162 return Ecosystem.PERL;
163 case "joomla!":
164 case "joomla":
165 case "mybb":
166 case "simplesamlphp":
167 case "craft_cms":
168 case "moodle":
169 case "phpcms":
170 case "buddypress":
171 case "typo3":
172 case "php":
173 case "wordpress":
174 case "drupal":
175 case "mediawiki":
176 case "symfony":
177 case "openpne":
178 case "vbulletin3":
179 case "vbulletin4":
180 return Ecosystem.PHP;
181 case "python":
182 return Ecosystem.PYTHON;
183 case "ruby":
184 return Ecosystem.RUBY;
185 }
186 return baseEcosystem;
187 }
188
189
190
191
192
193
194
195
196
197
198 public String extractEcosystem(String baseEcosystem, VulnerableSoftware parsedCpe) {
199 return extractEcosystem(baseEcosystem, parsedCpe.getVendor(), parsedCpe.getProduct(), parsedCpe.getTargetSw());
200 }
201
202
203
204
205
206
207
208
209 public boolean isRejected(String description) {
210 return description.startsWith("** REJECT **") || description.startsWith("DO NOT USE THIS CANDIDATE NUMBER");
211 }
212
213
214
215
216
217
218
219
220
221 boolean testCveCpeStartWithFilter(final DefCveItem cve) {
222 if (cve.getCve().getConfigurations() != null) {
223
224 return cve.getCve().getConfigurations().stream()
225 .map(Config::getNodes)
226 .flatMap(List::stream)
227 .filter(Objects::nonNull)
228 .map(Node::getCpeMatch)
229 .filter(Objects::nonNull)
230 .flatMap(List::stream)
231 .filter(cpe -> cpe != null && cpe.getCriteria() != null)
232 .anyMatch(cpe -> cpe.getCriteria().startsWith(cpeStartsWithFilter));
233 }
234 return false;
235 }
236 }