Skip to content

Commit

Permalink
Backported #140, #141 (#145)
Browse files Browse the repository at this point in the history
Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
  • Loading branch information
prabhu authored Jun 4, 2024
1 parent 6ae5e8c commit 5c76b03
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 9 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "appthreat-vulnerability-db"
version = "5.6.8"
version = "5.7.0"
description = "AppThreat's vulnerability database and package search library with a built-in file based storage. OSV, CVE, GitHub, npm are the primary sources of vulnerabilities."
authors = [
{name = "Team AppThreat", email = "cloud@appthreat.com"},
Expand Down
56 changes: 56 additions & 0 deletions test/data/MAL-2024-1333.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"id": "MAL-2024-1333",
"summary": "Malicious code in threadxpools (PyPI)",
"details": "\n---\n_-= Per source details. Do not edit below this line.=-_\n\n## Source: ossf-package-analysis (41a0be6e9aa8db3965bae9f646d47ad6cb85ac9600c8bd71358409062b8fe105)\nThe OpenSSF Package Analysis project identified 'threadxpools' @ 1.2 (pypi) as malicious.\n\nIt is considered malicious because:\n\n- The package communicates with a domain associated with malicious activity.\n",
"modified": "2024-05-06T02:38:12Z",
"published": "2024-05-05T19:10:54Z",
"database_specific": {
"malicious-packages-origins": [
{
"modified_time": "2024-05-05T19:17:29Z",
"import_time": "2024-05-06T02:37:56.710209536Z",
"versions": [
"1.2"
],
"source": "ossf-package-analysis",
"sha256": "41a0be6e9aa8db3965bae9f646d47ad6cb85ac9600c8bd71358409062b8fe105"
},
{
"modified_time": "2024-05-05T19:10:54Z",
"import_time": "2024-05-06T02:37:56.622833878Z",
"versions": [
"1.0"
],
"source": "ossf-package-analysis",
"sha256": "d1017e118ad5a001211a639263fb872dfa5dde20fcd41e1674155a2d7977fb47"
}
]
},
"affected": [
{
"package": {
"name": "threadxpools",
"ecosystem": "PyPI",
"purl": "pkg:pypi/threadxpools"
},
"versions": [
"1.2",
"1.0"
],
"database_specific": {
"source": "https://github.com/ossf/malicious-packages/blob/main/osv/malicious/pypi/threadxpools/MAL-2024-1333.json"
}
}
],
"schema_version": "1.6.0",
"credits": [
{
"name": "OpenSSF: Package Analysis",
"contact": [
"https://github.com/ossf/package-analysis",
"https://openssf.slack.com/channels/package_analysis"
],
"type": "FINDER"
}
]
}
46 changes: 46 additions & 0 deletions test/data/MAL-2024-1396.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"id": "MAL-2024-1396",
"summary": "Malicious code in numberpy (PyPI)",
"details": "\n---\n_-= Per source details. Do not edit below this line.=-_\n\n## Source: ossf-package-analysis (e10120613afbbf32d487584c68eaf1ae7f4fc0674f1f119d86beae630a3b9070)\nThe OpenSSF Package Analysis project identified 'numberpy' @ 0.1.0 (pypi) as malicious.\n\nIt is considered malicious because:\n\n- The package communicates with a domain associated with malicious activity.\n",
"modified": "2024-05-31T08:26:49Z",
"published": "2024-05-31T08:26:49Z",
"database_specific": {
"malicious-packages-origins": [
{
"modified_time": "2024-05-31T08:26:49Z",
"import_time": "2024-05-31T08:34:06.567219558Z",
"versions": [
"0.1.0"
],
"source": "ossf-package-analysis",
"sha256": "e10120613afbbf32d487584c68eaf1ae7f4fc0674f1f119d86beae630a3b9070"
}
]
},
"affected": [
{
"package": {
"name": "numberpy",
"ecosystem": "PyPI",
"purl": "pkg:pypi/numberpy"
},
"versions": [
"0.1.0"
],
"database_specific": {
"source": "https://github.com/ossf/malicious-packages/blob/main/osv/malicious/pypi/numberpy/MAL-2024-1396.json"
}
}
],
"schema_version": "1.6.0",
"credits": [
{
"name": "OpenSSF: Package Analysis",
"contact": [
"https://github.com/ossf/package-analysis",
"https://openssf.slack.com/channels/package_analysis"
],
"type": "FINDER"
}
]
}
26 changes: 26 additions & 0 deletions test/test_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,24 @@ def test_osv_pypi3_json():
return json.loads(fp.read())


@pytest.fixture
def test_osv_mal_json():
test_cve_data = os.path.join(
os.path.dirname(os.path.realpath(__file__)), "data", "MAL-2024-1396.json"
)
with open(test_cve_data, "r") as fp:
return json.loads(fp.read())


@pytest.fixture
def test_osv_mal2_json():
test_cve_data = os.path.join(
os.path.dirname(os.path.realpath(__file__)), "data", "MAL-2024-1333.json"
)
with open(test_cve_data, "r") as fp:
return json.loads(fp.read())


@pytest.fixture
def test_aqua_alsa_json():
test_cve_data = os.path.join(
Expand Down Expand Up @@ -477,6 +495,14 @@ def test_osv_convert(
assert not cve_data


def test_osv_mal_convert(test_osv_mal_json, test_osv_mal2_json):
osvlatest = OSVSource()
cve_data = osvlatest.convert(test_osv_mal2_json)
assert len(cve_data) == 1
cve_data = osvlatest.convert(test_osv_mal_json)
assert len(cve_data) == 1


def test_aqua_convert(
test_aqua_alsa_json,
test_aqua_alas_json,
Expand Down
8 changes: 4 additions & 4 deletions vdb/lib/osv.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ def to_vuln(self, cve_data):
# Problem 2: The versions_list may be unsorted and trying to sort based on semantic versions can fail
# Solution: We do our best to sort the versions_list. If it fails, we assume the input is sorted and store the first and last entry as min and max.
# The assumption seems to be working as of today, but could result in false positives or false negatives in the future.
needs_version_backup = False
needs_version_backup = len(ranges) == 0
possible_fix_version = ""
for r in ranges:
events = r.get("events")
Expand All @@ -258,10 +258,10 @@ def to_vuln(self, cve_data):
needs_version_backup = True
if ev.get("fixed"):
possible_fix_version = ev.get("fixed")
if needs_version_backup and len(versions_list) > 1:
if needs_version_backup and len(versions_list):
try:
min_ver = min(versions_list, key=Version.parse)
max_ver = max(versions_list, key=Version.parse)
min_ver = min(versions_list, key=lambda x: Version.parse(x, optional_minor_and_patch=True))
max_ver = max(versions_list, key=lambda x: Version.parse(x, optional_minor_and_patch=True))
except Exception:
min_ver = versions_list[0]
max_ver = versions_list[-1]
Expand Down
8 changes: 4 additions & 4 deletions vdb/lib/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -588,9 +588,9 @@ def version_compare(
return False
if mae:
if VersionInfo.is_valid(compare_ver) and VersionInfo.is_valid(mae):
cmp_value = VersionInfo.parse(compare_ver).compare(mae)
cmp_value = VersionInfo.parse(compare_ver, optional_minor_and_patch=True).compare(mae)
return cmp_value < 0
elif "." not in compare_ver and "." not in mae:
if "." not in compare_ver and "." not in mae:
compare_ver = re.split(r"[+~]", compare_ver)[0]
mae = re.split(r"[+~]", mae)[0]
exnum = list(filter(str.isdigit, compare_ver))
Expand Down Expand Up @@ -629,8 +629,8 @@ def version_compare(
# Perform semver match once we have all the required versions
if compare_ver and min_version and max_version:
if semver_compatible(compare_ver, min_version, max_version):
min_value = VersionInfo.parse(compare_ver).compare(min_version)
max_value = VersionInfo.parse(compare_ver).compare(max_version)
min_value = VersionInfo.parse(compare_ver, optional_minor_and_patch=True).compare(min_version)
max_value = VersionInfo.parse(compare_ver, optional_minor_and_patch=True).compare(max_version)
min_check = min_value > 0 if is_min_exclude else min_value >= 0
max_check = max_value < 0 if is_max_exclude else max_value <= 0
return min_check and max_check
Expand Down

0 comments on commit 5c76b03

Please sign in to comment.