Skip to content

Commit efdf987

Browse files
authored
json fallback (#16)
* orjson fallback * orjson fallback * orjson fallback
1 parent a78f1d4 commit efdf987

File tree

13 files changed

+98
-68
lines changed

13 files changed

+98
-68
lines changed

.github/workflows/pythonapp.yml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ on: [push]
55
jobs:
66
build:
77

8-
runs-on: ubuntu-latest
8+
runs-on: ubuntu-20.04
99
strategy:
1010
matrix:
11-
os: [ubuntu-latest, macos-latest, windows-latest]
12-
python-version: [3.8]
11+
os: [ubuntu-20.04, macos-latest, windows-latest]
12+
python-version: [3.8, 3.9]
1313
steps:
1414
- uses: actions/checkout@v2
1515
- name: Set up Python 3.7
@@ -31,6 +31,10 @@ jobs:
3131
- name: Test with pytest
3232
run: |
3333
pytest --cov=vdb test
34+
- name: Test without orjson
35+
run: |
36+
pip uninstall -y orjson
37+
pytest --cov=vdb test
3438
- name: Self sast-scan
3539
uses: AppThreat/sast-scan-action@master
3640
with:

.github/workflows/pythonpublish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ on:
99
jobs:
1010
deploy:
1111

12-
runs-on: ubuntu-latest
12+
runs-on: ubuntu-20.04
1313

1414
steps:
1515
- uses: actions/checkout@v2

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ requests
22
appdirs
33
tabulate
44
msgpack
5-
orjson==3.3.1
5+
orjson
66
semver

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setuptools.setup(
77
name="appthreat-vulnerability-db",
8-
version="1.5.2",
8+
version="1.6.0",
99
author="Team AppThreat",
1010
author_email="cloud@appthreat.com",
1111
description="AppThreat's vulnerability database and package search library with a built-in file based storage. CVE, GitHub, npm are the primary sources of vulnerabilities.",
@@ -14,7 +14,7 @@
1414
long_description_content_type="text/markdown",
1515
url="https://github.com/appthreat/vulnerability-db",
1616
packages=setuptools.find_packages(),
17-
install_requires=["requests", "appdirs", "tabulate", "msgpack", "orjson==3.3.1", "semver"],
17+
install_requires=["requests", "appdirs", "tabulate", "msgpack", "orjson", "semver"],
1818
classifiers=[
1919
"Development Status :: 5 - Production/Stable",
2020
"Intended Audience :: Developers",

test/test_db.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,11 @@ def test_gha_search_slow(test_db, test_gha_data):
9696
for d in all_data:
9797
version = d["details"]["max_affected_version_including"]
9898
if version and version != "*":
99-
res = db.pkg_search(table, d["details"]["package"], version,)
99+
res = db.pkg_search(
100+
table,
101+
d["details"]["package"],
102+
version,
103+
)
100104
assert len(res)
101105
assert res[0].to_dict()["package_issue"]
102106

@@ -113,7 +117,12 @@ def test_gha_vendor_search(test_db, test_gha_data):
113117
vendor, _, _ = parse_cpe(d["details"]["cpe_uri"])
114118
version = d["details"]["max_affected_version_including"]
115119
if version and version != "*":
116-
res = db.vendor_pkg_search(table, vendor, d["details"]["package"], version,)
120+
res = db.vendor_pkg_search(
121+
table,
122+
vendor,
123+
d["details"]["package"],
124+
version,
125+
)
117126
assert len(res)
118127
assert res[0].to_dict()["package_issue"]
119128

vdb/cli.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,7 @@ def build_args():
9494

9595

9696
def print_results(results):
97-
"""Pretty print report summary
98-
"""
97+
"""Pretty print report summary"""
9998
table = []
10099
added_list = []
101100
headers = [

vdb/lib/__init__.py

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,7 @@ def convert_time(time_str):
8080

8181

8282
class Vulnerability(object):
83-
"""Vulnerability
84-
"""
83+
"""Vulnerability"""
8584

8685
def __init__(
8786
self,
@@ -124,8 +123,7 @@ def __repr__(self):
124123

125124

126125
class VulnerabilityDetail(object):
127-
"""Vulnerability detail class
128-
"""
126+
"""Vulnerability detail class"""
129127

130128
def __init__(
131129
self,
@@ -202,8 +200,7 @@ def from_dict(detail):
202200

203201

204202
class PackageIssue(object):
205-
"""Package issue class
206-
"""
203+
"""Package issue class"""
207204

208205
def __init__(
209206
self,
@@ -253,8 +250,7 @@ def __str__(self):
253250

254251

255252
class CvssV3(object):
256-
"""CVSS v3 representation
257-
"""
253+
"""CVSS v3 representation"""
258254

259255
base_score: float
260256
exploitability_score: float
@@ -370,8 +366,7 @@ def __str__(self):
370366

371367

372368
class VulnerabilityOccurrence:
373-
"""Class to represent an occurrence of a vulnerability
374-
"""
369+
"""Class to represent an occurrence of a vulnerability"""
375370

376371
id: str
377372
problem_type: str
@@ -409,8 +404,7 @@ def __init__(
409404
self.effective_severity = effective_severity
410405

411406
def to_dict(self):
412-
"""Convert the object to dict
413-
"""
407+
"""Convert the object to dict"""
414408
return {
415409
"id": self.id,
416410
"problem_type": self.problem_type,

vdb/lib/db.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,7 @@ def _key_func(data, match_list):
159159

160160

161161
def bulk_index_search(pkg_list):
162-
"""
163-
"""
162+
""""""
164163
ret_list = set()
165164
for pkg in pkg_list:
166165
version_list = None

vdb/lib/gha.py

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,15 @@
1212
import os
1313
import re
1414

15-
import orjson
15+
try:
16+
import orjson
17+
18+
ORJSON_AVAILABLE = True
19+
except ImportError:
20+
import json
21+
22+
ORJSON_AVAILABLE = False
23+
1624
import requests
1725

1826
from vdb.lib import config as config
@@ -27,10 +35,11 @@
2735
api_token = os.environ.get("GITHUB_TOKEN")
2836
headers = {"Authorization": "token %s" % api_token}
2937

38+
json_lib = orjson if ORJSON_AVAILABLE else json
39+
3040

3141
def get_query(type="recent"):
32-
"""
33-
"""
42+
""""""
3443
extra_args = ""
3544
if type == "recent" or not type:
3645
extra_args = "first: 100"
@@ -85,12 +94,10 @@ def get_query(type="recent"):
8594

8695

8796
class GitHubSource(NvdSource):
88-
"""GitHub CVE source
89-
"""
97+
"""GitHub CVE source"""
9098

9199
def download_all(self, local_store=True):
92-
"""Download all historic cve data
93-
"""
100+
"""Download all historic cve data"""
94101
data_list = []
95102
lastId = None
96103
for y in range(0, int(config.gha_pages_count)):
@@ -104,16 +111,14 @@ def download_all(self, local_store=True):
104111
return data_list
105112

106113
def download_recent(self, local_store=True):
107-
"""Method which downloads the recent CVE
108-
"""
114+
"""Method which downloads the recent CVE"""
109115
data, page_info = self.fetch("recent")
110116
if data and local_store:
111117
self.store(data)
112118
return data
113119

114120
def fetch(self, type):
115-
"""Private method to fetch the advisory data via GraphQL api
116-
"""
121+
"""Private method to fetch the advisory data via GraphQL api"""
117122
LOG.debug(
118123
"Download GitHub advisory from {} with cursor {}".format(
119124
config.gha_url, type
@@ -171,8 +176,7 @@ def get_version_range(self, version_str):
171176
)
172177

173178
def convert(self, cve_data):
174-
"""Convert the GitHub advisory data into Vulnerability objects
175-
"""
179+
"""Convert the GitHub advisory data into Vulnerability objects"""
176180
ret_data = []
177181
if cve_data.get("errors"):
178182
return ret_data, None
@@ -195,6 +199,9 @@ def convert(self, cve_data):
195199
if not cve_id:
196200
cve_id = cve["ghsaId"]
197201
assigner = "@github"
202+
references = json_lib.dumps(references)
203+
if isinstance(references, bytes):
204+
references = references.decode("utf-8", "ignore")
198205
for p in cve["vulnerabilities"]["nodes"]:
199206
vendor = p["package"]["ecosystem"]
200207
product = p["package"]["name"]
@@ -234,11 +241,12 @@ def convert(self, cve_data):
234241
""".format(
235242
cve.get("summary"), cve.get("description")
236243
)
244+
237245
tdata = config.CVE_TPL % dict(
238246
cve_id=cve_id,
239247
cwe_id="UNKNOWN",
240248
assigner=assigner,
241-
references=orjson.dumps(references).decode("utf-8"),
249+
references=references,
242250
description="",
243251
vectorString=vectorString,
244252
vendor=vendor.lower(),
@@ -260,7 +268,7 @@ def convert(self, cve_data):
260268
lastModifiedDate=cve["updatedAt"],
261269
)
262270
try:
263-
tdata_json = orjson.loads(tdata)
271+
tdata_json = json_lib.loads(tdata)
264272
vuln = NvdSource.convert_vuln(tdata_json)
265273
vuln.description = description
266274
ret_data.append(vuln)

vdb/lib/npm.py

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,15 @@
55
"""
66
import logging
77

8-
import orjson
8+
try:
9+
import orjson
10+
11+
ORJSON_AVAILABLE = True
12+
except ImportError:
13+
import json
14+
15+
ORJSON_AVAILABLE = False
16+
917
import requests
1018

1119
from vdb.lib import config as config
@@ -23,6 +31,9 @@
2331
)
2432
LOG = logging.getLogger(__name__)
2533

34+
json_lib = orjson if ORJSON_AVAILABLE else json
35+
import traceback
36+
2637

2738
class NpmSource(NvdSource):
2839
"""
@@ -67,8 +78,7 @@ def fetch(self, payload):
6778
return self.convert(json_data)
6879

6980
def download_recent(self, local_store=True):
70-
"""Method which downloads the recent CVE
71-
"""
81+
"""Method which downloads the recent CVE"""
7282
url = config.npm_advisories_url + "?perPage=100&page=1"
7383
r = requests.get(url=url)
7484
if r.ok:
@@ -80,8 +90,7 @@ def download_recent(self, local_store=True):
8090
return None
8191

8292
def download_all(self, local_store=True):
83-
"""Download all historic cve data
84-
"""
93+
"""Download all historic cve data"""
8594
data_list = []
8695
url = config.npm_advisories_url + "?perPage=100&page=1"
8796
for y in range(0, int(config.npm_pages_count)):
@@ -185,6 +194,9 @@ def to_vuln(self, v, ret_data):
185194
)
186195
if v.get("references"):
187196
references = convert_md_references(v.get("references"))
197+
references = json_lib.dumps(references)
198+
if isinstance(references, bytes):
199+
references = references.decode("utf-8", "ignore")
188200
severity = v.get("severity")
189201
vendor = "npm"
190202
product = v["module_name"]
@@ -223,11 +235,12 @@ def to_vuln(self, v, ret_data):
223235
"version_end_excluding", ""
224236
)
225237
description = fix_text(description)
238+
226239
tdata = config.CVE_TPL % dict(
227240
cve_id=cve_id,
228241
cwe_id=cwe_id,
229242
assigner=assigner,
230-
references=orjson.dumps(references).decode("utf-8"),
243+
references=references,
231244
description="",
232245
vectorString=vectorString,
233246
vendor=vendor,
@@ -249,10 +262,12 @@ def to_vuln(self, v, ret_data):
249262
lastModifiedDate=lastModifiedDate,
250263
)
251264
try:
252-
vuln = NvdSource.convert_vuln(orjson.loads(tdata))
265+
vuln = NvdSource.convert_vuln(json_lib.loads(tdata))
253266
vuln.description = description
254267
ret_data.append(vuln)
255-
except Exception:
256-
pass
268+
except Exception as e:
269+
LOG.debug(e)
270+
traceback.print_exc()
271+
print(tdata)
257272
vr = vr + 1
258273
return ret_data

0 commit comments

Comments
 (0)