Skip to content

Commit 091d479

Browse files
committed
Leverage Etags in openssl importer
Signed-off-by: Shivam Sandbhor <shivam.sandbhor@gmail.com>
1 parent f6e1bca commit 091d479

2 files changed

Lines changed: 45 additions & 8 deletions

File tree

vulnerabilities/importer_yielder.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,9 @@
149149
'license': '',
150150
'last_run': None,
151151
'data_source': 'OpenSSLDataSource',
152-
'data_source_cfg': {},
152+
'data_source_cfg': {
153+
'etags': {}
154+
},
153155
},
154156
{
155157
'name': 'ubuntu_usn',

vulnerabilities/importers/openssl.py

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,27 +20,58 @@
2020
# VulnerableCode is a free software code scanning tool from nexB Inc. and others.
2121
# Visit https://github.com/nexB/vulnerablecode/ for support and download.
2222

23+
import dataclasses
24+
import re
2325
from typing import Set
26+
import xml.etree.ElementTree as ET
2427

2528
from packageurl import PackageURL
2629
import requests
27-
import re
2830

2931
from vulnerabilities.data_source import Advisory
3032
from vulnerabilities.data_source import DataSource
3133
from vulnerabilities.data_source import Reference
34+
from vulnerabilities.data_source import DataSourceConfiguration
3235

33-
import xml.etree.ElementTree as ET
36+
37+
@dataclasses.dataclass
38+
class OpenSSLDataSourceConfiguration(DataSourceConfiguration):
39+
etags: dict
3440

3541

3642
class OpenSSLDataSource(DataSource):
43+
CONFIG_CLASS = OpenSSLDataSourceConfiguration
44+
45+
url = "https://www.openssl.org/news/vulnerabilities.xml"
46+
3747
def updated_advisories(self) -> Set[Advisory]:
38-
raw_data = self.fetch()
39-
advisories = self.to_advisories(raw_data)
40-
return self.batch_advisories(advisories)
48+
# Etags are like hashes of web responses. We maintain
49+
# (url, etag) mappings in the DB. `create_etag` creates
50+
# (url, etag) pair. If a (url, etag) already exists then the code
51+
# skips processing the response further to avoid duplicate work
52+
if self.create_etag(self.url):
53+
raw_data = self.fetch()
54+
advisories = self.to_advisories(raw_data)
55+
return self.batch_advisories(advisories)
56+
57+
return []
58+
59+
def create_etag(self, url):
60+
etag = requests.head(url).headers.get("ETag")
61+
if not etag:
62+
# Kind of inaccurate to return True since etag is
63+
# not created
64+
return True
65+
66+
elif url in self.config.etags:
67+
if self.config.etags[url] == etag:
68+
return False
69+
70+
self.config.etags[url] = etag
71+
return True
4172

4273
def fetch(self):
43-
return requests.get("https://www.openssl.org/news/vulnerabilities.xml").content
74+
return requests.get(self.url).content
4475

4576
@staticmethod
4677
def to_advisories(xml_response: str) -> Set[Advisory]:
@@ -58,7 +89,11 @@ def to_advisories(xml_response: str) -> Set[Advisory]:
5889
for info in element:
5990

6091
if info.tag == "cve":
61-
cve_id = "CVE-" + info.attrib.get("name")
92+
if info.attrib.get("name"):
93+
cve_id = "CVE-" + info.attrib.get("name")
94+
95+
else:
96+
continue
6297

6398
if info.tag == "affects":
6499
# Vulnerable package versions

0 commit comments

Comments
 (0)