|
8 | 8 | #
|
9 | 9 |
|
10 | 10 | import logging
|
| 11 | +import re |
11 | 12 | import urllib
|
12 | 13 |
|
13 | 14 | import requests
|
|
23 | 24 | from vulnerabilities.importer import Reference
|
24 | 25 | from vulnerabilities.importer import VulnerabilitySeverity
|
25 | 26 | from vulnerabilities.severity_systems import APACHE_HTTPD
|
| 27 | +from vulnerabilities.utils import create_weaknesses_list |
| 28 | +from vulnerabilities.utils import cwe_regex |
26 | 29 | from vulnerabilities.utils import get_item
|
27 | 30 |
|
28 | 31 | logger = logging.getLogger(__name__)
|
@@ -102,11 +105,14 @@ def to_advisory(self, data):
|
102 | 105 | )
|
103 | 106 | )
|
104 | 107 |
|
| 108 | + weaknesses = get_weaknesses(data) |
| 109 | + |
105 | 110 | return AdvisoryData(
|
106 | 111 | aliases=[alias],
|
107 | 112 | summary=description or "",
|
108 | 113 | affected_packages=affected_packages,
|
109 | 114 | references=[reference],
|
| 115 | + weaknesses=weaknesses, |
110 | 116 | url=reference.url,
|
111 | 117 | )
|
112 | 118 |
|
@@ -152,3 +158,97 @@ def fetch_links(url):
|
152 | 158 | continue
|
153 | 159 | links.append(urllib.parse.urljoin(url, link))
|
154 | 160 | return links
|
| 161 | + |
| 162 | + |
| 163 | +def get_weaknesses(cve_data): |
| 164 | + """ |
| 165 | + Extract CWE IDs from CVE data. |
| 166 | +
|
| 167 | + Args: |
| 168 | + cve_data (dict): The CVE data in a dictionary format. |
| 169 | +
|
| 170 | + Returns: |
| 171 | + List[int]: A list of unique CWE IDs. |
| 172 | +
|
| 173 | + Examples: |
| 174 | + >>> mock_cve_data1 = { |
| 175 | + ... "containers": { |
| 176 | + ... "cna": { |
| 177 | + ... "providerMetadata": { |
| 178 | + ... "orgId": "f0158376-9dc2-43b6-827c-5f631a4d8d09" |
| 179 | + ... }, |
| 180 | + ... "title": "mod_macro buffer over-read", |
| 181 | + ... "problemTypes": [ |
| 182 | + ... { |
| 183 | + ... "descriptions": [ |
| 184 | + ... { |
| 185 | + ... "description": "CWE-125 Out-of-bounds Read", |
| 186 | + ... "lang": "en", |
| 187 | + ... "cweId": "CWE-125", |
| 188 | + ... "type": "CWE" |
| 189 | + ... } |
| 190 | + ... ] |
| 191 | + ... } |
| 192 | + ... ] |
| 193 | + ... } |
| 194 | + ... } |
| 195 | + ... } |
| 196 | + >>> mock_cve_data2 = { |
| 197 | + ... "data_type": "CVE", |
| 198 | + ... "data_format": "MITRE", |
| 199 | + ... "data_version": "4.0", |
| 200 | + ... "generator": { |
| 201 | + ... "engine": "Vulnogram 0.0.9" |
| 202 | + ... }, |
| 203 | + ... "CVE_data_meta": { |
| 204 | + ... "ID": "CVE-2022-28614", |
| 205 | + ... "ASSIGNER": "[email protected]", |
| 206 | + ... "TITLE": "read beyond bounds via ap_rwrite() ", |
| 207 | + ... "STATE": "PUBLIC" |
| 208 | + ... }, |
| 209 | + ... "problemtype": { |
| 210 | + ... "problemtype_data": [ |
| 211 | + ... { |
| 212 | + ... "description": [ |
| 213 | + ... { |
| 214 | + ... "lang": "eng", |
| 215 | + ... "value": "CWE-190 Integer Overflow or Wraparound" |
| 216 | + ... } |
| 217 | + ... ] |
| 218 | + ... }, |
| 219 | + ... { |
| 220 | + ... "description": [ |
| 221 | + ... { |
| 222 | + ... "lang": "eng", |
| 223 | + ... "value": "CWE-200 Exposure of Sensitive Information to an Unauthorized Actor" |
| 224 | + ... } |
| 225 | + ... ] |
| 226 | + ... } |
| 227 | + ... ] |
| 228 | + ... } |
| 229 | + ... } |
| 230 | +
|
| 231 | + >>> get_weaknesses(mock_cve_data1) |
| 232 | + [125] |
| 233 | +
|
| 234 | + >>> get_weaknesses(mock_cve_data2) |
| 235 | + [190, 200] |
| 236 | + """ |
| 237 | + alias = get_item(cve_data, "CVE_data_meta", "ID") |
| 238 | + cwe_strings = [] |
| 239 | + if alias: |
| 240 | + problemtype_data = get_item(cve_data, "problemtype", "problemtype_data") or [] |
| 241 | + for problem in problemtype_data: |
| 242 | + for desc in problem.get("description", []): |
| 243 | + value = desc.get("value", "") |
| 244 | + cwe_id_string_list = re.findall(cwe_regex, value) |
| 245 | + cwe_strings.extend(cwe_id_string_list) |
| 246 | + else: |
| 247 | + problemTypes = cve_data.get("containers", {}).get("cna", {}).get("problemTypes", []) |
| 248 | + descriptions = problemTypes[0].get("descriptions", []) if len(problemTypes) > 0 else [] |
| 249 | + for description in descriptions: |
| 250 | + cwe_id_string = description.get("cweId", "") |
| 251 | + cwe_strings.append(cwe_id_string) |
| 252 | + |
| 253 | + weaknesses = create_weaknesses_list(cwe_strings) |
| 254 | + return weaknesses |
0 commit comments