|
7 | 7 | # Known application package types
|
8 | 8 | KNOWN_PKG_TYPES = ["composer", "maven", "npm", "nuget", "pypi", "rubygems", "golang"]
|
9 | 9 |
|
| 10 | +# Maps variations of string to package types |
| 11 | +PKG_TYPES_MAP = { |
| 12 | + "composer": ["php", "laravel", "wordpress", "joomla"], |
| 13 | + "maven": ["jenkins", "java", "kotlin", "groovy"], |
| 14 | + "npm": ["javascript", "node.js", "nodejs"], |
| 15 | + "nuget": [".net_framework", "csharp", ".net_core"], |
| 16 | + "pypi": ["python"], |
| 17 | + "rubygems": ["ruby"], |
| 18 | + "golang": ["go"], |
| 19 | +} |
| 20 | + |
10 | 21 | # CPE Regex
|
11 | 22 | CPE_REGEX = re.compile(
|
12 | 23 | "cpe:?:[^:]+:[^:]+:(?P<vendor>[^:]+):(?P<package>[^:]+):(?P<version>[^:]+)?"
|
13 | 24 | )
|
14 | 25 |
|
| 26 | +# CPE Full Regex including unused parameters |
| 27 | +CPE_FULL_REGEX = re.compile( |
| 28 | + "cpe:?:[^:]+:[^:]+:(?P<vendor>[^:]+):(?P<package>[^:]+):(?P<version>[^:]+):(?P<update>[^:]+):(?P<edition>[^:]+):(?P<lang>[^:]+):(?P<sw_edition>[^:]+):(?P<target_sw>[^:]+):(?P<target_hw>[^:]+):(?P<other>[^:]+)" |
| 29 | +) |
| 30 | + |
15 | 31 |
|
16 | 32 | class VulnerabilitySource(metaclass=ABCMeta):
|
17 | 33 | @classmethod
|
@@ -191,15 +207,31 @@ def get_type(cpe_uri, package_type):
|
191 | 207 | if package_type in KNOWN_PKG_TYPES:
|
192 | 208 | return package_type
|
193 | 209 | parts = CPE_REGEX.match(cpe_uri)
|
| 210 | + # cpe:2.3:a:netaddr_project:netaddr:*:*:*:*:*:ruby:*:* |
| 211 | + all_parts = CPE_FULL_REGEX.match(cpe_uri) |
194 | 212 | if parts:
|
195 | 213 | type = parts.group("vendor")
|
196 | 214 | if type in KNOWN_PKG_TYPES:
|
197 | 215 | return type
|
| 216 | + elif all_parts and ( |
| 217 | + (all_parts.group("target_sw") and all_parts.group("target_sw") != "*") |
| 218 | + or ( |
| 219 | + all_parts.group("sw_edition") |
| 220 | + and all_parts.group("sw_edition") != "*" |
| 221 | + ) |
| 222 | + ): |
| 223 | + for vk, vv in PKG_TYPES_MAP.items(): |
| 224 | + target_sw = all_parts.group("target_sw") |
| 225 | + sw_edition = all_parts.group("sw_edition") |
| 226 | + if target_sw == vk or sw_edition == vk: |
| 227 | + return vk |
| 228 | + if target_sw in vv or sw_edition in vv: |
| 229 | + return vk |
| 230 | + return type |
198 | 231 | else:
|
199 | 232 | # Unknown type. Just pass-through for now
|
200 | 233 | return type
|
201 |
| - else: |
202 |
| - return None |
| 234 | + return None |
203 | 235 |
|
204 | 236 | @staticmethod
|
205 | 237 | def from_dict(detail):
|
|
0 commit comments