Skip to content

Commit b18b2ed

Browse files
committed
Merge remote-tracking branch 'keshav-space/oss_index_datasource' into vulntotal-clean
2 parents 97c2f79 + e639b5e commit b18b2ed

File tree

4 files changed

+361
-0
lines changed

4 files changed

+361
-0
lines changed

vulntotal/datasources/oss_index.py

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
#
2+
# Copyright (c) nexB Inc. and others. All rights reserved.
3+
# http://nexb.com and https://github.com/nexB/vulnerablecode/
4+
# The VulnTotal software is licensed under the Apache License version 2.0.
5+
# Data generated with VulnTotal require an acknowledgment.
6+
#
7+
# You may not use this software except in compliance with the License.
8+
# You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0
9+
# Unless required by applicable law or agreed to in writing, software distributed
10+
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
11+
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
12+
# specific language governing permissions and limitations under the License.
13+
#
14+
# When you publish or redistribute any data created with VulnTotal or any VulnTotal
15+
# derivative work, you must accompany this data with the following acknowledgment:
16+
#
17+
# Generated with VulnTotal and provided on an "AS IS" BASIS, WITHOUT WARRANTIES
18+
# OR CONDITIONS OF ANY KIND, either express or implied. No content created from
19+
# VulnTotal should be considered or used as legal advice. Consult an Attorney
20+
# for any legal advice.
21+
# VulnTotal is a free software tool from nexB Inc. and others.
22+
# Visit https://github.com/nexB/vulnerablecode/ for support and download.
23+
24+
import json
25+
import logging
26+
import os
27+
from typing import Iterable
28+
29+
import requests
30+
31+
from vulntotal.validator import DataSource
32+
from vulntotal.validator import VendorData
33+
34+
logger = logging.getLogger(__name__)
35+
36+
37+
class OSSDataSource(DataSource):
38+
spdx_license_expression = "TODO"
39+
license_url = "TODO"
40+
api_unauthenticated = "https://ossindex.sonatype.org/api/v3/component-report"
41+
api_authenticated = "https://ossindex.sonatype.org/api/v3/authorized/component-report"
42+
43+
def fetch_json_response(self, coordinates):
44+
username = os.environ.get("OSS_USERNAME", None)
45+
token = os.environ.get("OSS_TOKEN", None)
46+
auth = None
47+
url = self.api_unauthenticated
48+
if username and token:
49+
auth = (username, token)
50+
url = self.api_authenticated
51+
response = requests.post(url, auth=auth, json={"coordinates": coordinates})
52+
53+
if response.status_code == 200:
54+
return response.json()
55+
elif response.status_code == 401:
56+
logger.error("Invalid credentials")
57+
elif response.status_code == 429:
58+
msg = (
59+
"Too many requests"
60+
if auth
61+
else "Too many requests: add OSS_USERNAME and OSS_TOKEN in .env file"
62+
)
63+
logger.error(msg)
64+
else:
65+
logger.error(f"unknown status code: {response.status_code} while fetching: {url}")
66+
67+
def datasource_advisory(self, purl) -> Iterable[VendorData]:
68+
if purl.type not in self.supported_ecosystem():
69+
logger.error("Unsupported PURL")
70+
return
71+
72+
response = self.fetch_json_response([str(purl)])
73+
if response:
74+
self._raw_dump.append(response)
75+
return parse_advisory(response)
76+
77+
@classmethod
78+
def supported_ecosystem(cls):
79+
return {
80+
"cargo": "cargo",
81+
"cocoapods": "cocoapods",
82+
"composer": "composer",
83+
"conan": "conan",
84+
"conda": "conda",
85+
"cran": "cran",
86+
"golang": "golang",
87+
"maven": "maven",
88+
"npm": "npm",
89+
"nuget": "nuget",
90+
"pypi": "pypi",
91+
"rpm": "rpm",
92+
"gem": "gem",
93+
"swift": "swift",
94+
}
95+
96+
97+
def parse_advisory(component) -> Iterable[VendorData]:
98+
response = component[0]
99+
if response["vulnerabilities"]:
100+
for vuln in response["vulnerabilities"]:
101+
aliases = [vuln["id"]]
102+
affected_versions = []
103+
fixed_versions = []
104+
if "versionRanges" in vuln:
105+
affected_versions.extend(vuln["versionRanges"])
106+
yield VendorData(
107+
aliases=aliases,
108+
affected_versions=affected_versions,
109+
fixed_versions=fixed_versions,
110+
)
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
[
2+
{
3+
"coordinates":"pkg:golang/github.com/cloudflare/[email protected]",
4+
"reference":"https://ossindex.sonatype.org/component/pkg:golang/github.com/cloudflare/[email protected]?utm_source=python-requests&utm_medium=integration&utm_content=2.27.1",
5+
"vulnerabilities":[
6+
{
7+
"id":"CVE-2021-3907",
8+
"displayName":"CVE-2021-3907",
9+
"title":"[CVE-2021-3907] CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')",
10+
"description":"OctoRPKI does not escape a URI with a filename containing \"..\", this allows a repository to create a file, (ex. rsync://example.org/repo/../../etc/cron.daily/evil.roa), which would then be written to disk outside the base cache folder. This could allow for remote code execution on the host machine OctoRPKI is running on.",
11+
"cvssScore":9.8,
12+
"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
13+
"cwe":"CWE-22",
14+
"cve":"CVE-2021-3907",
15+
"reference":"https://ossindex.sonatype.org/vulnerability/CVE-2021-3907?component-type=golang&component-name=github.com%2Fcloudflare%2Fcfrpki&utm_source=python-requests&utm_medium=integration&utm_content=2.27.1",
16+
"externalReferences":[
17+
"http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2021-3907",
18+
"https://github.com/cloudflare/cfrpki/security/advisories/GHSA-cqh2-vc2f-q4fh"
19+
]
20+
},
21+
{
22+
"id":"CVE-2021-3761",
23+
"displayName":"CVE-2021-3761",
24+
"title":"[CVE-2021-3761] CWE-787: Out-of-bounds Write",
25+
"description":"Any CA issuer in the RPKI can trick OctoRPKI prior to 1.3.0 into emitting an invalid VRP \"MaxLength\" value, causing RTR sessions to terminate. An attacker can use this to disable RPKI Origin Validation in a victim network (for example AS 13335 - Cloudflare) prior to launching a BGP hijack which during normal operations would be rejected as \"RPKI invalid\". Additionally, in certain deployments RTR session flapping in and of itself also could cause BGP routing churn, causing availability issues.",
26+
"cvssScore":7.5,
27+
"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
28+
"cwe":"CWE-787",
29+
"cve":"CVE-2021-3761",
30+
"reference":"https://ossindex.sonatype.org/vulnerability/CVE-2021-3761?component-type=golang&component-name=github.com%2Fcloudflare%2Fcfrpki&utm_source=python-requests&utm_medium=integration&utm_content=2.27.1",
31+
"externalReferences":[
32+
"http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2021-3761",
33+
"https://github.com/cloudflare/cfrpki/pull/90",
34+
"https://github.com/cloudflare/cfrpki/security/advisories/GHSA-c8xp-8mf3-62h9",
35+
"https://github.com/CVEProject/cvelist/commit/8f3edcdf139aa823e1f17aa15b337ab92436ebf7"
36+
]
37+
},
38+
{
39+
"id":"CVE-2021-3908",
40+
"displayName":"CVE-2021-3908",
41+
"title":"[CVE-2021-3908] CWE-400: Uncontrolled Resource Consumption ('Resource Exhaustion')",
42+
"description":"OctoRPKI does not limit the depth of a certificate chain, allowing for a CA to create children in an ad-hoc fashion, thereby making tree traversal never end.",
43+
"cvssScore":7.5,
44+
"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
45+
"cwe":"CWE-400",
46+
"cve":"CVE-2021-3908",
47+
"reference":"https://ossindex.sonatype.org/vulnerability/CVE-2021-3908?component-type=golang&component-name=github.com%2Fcloudflare%2Fcfrpki&utm_source=python-requests&utm_medium=integration&utm_content=2.27.1",
48+
"externalReferences":[
49+
"http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2021-3908",
50+
"https://github.com/cloudflare/cfrpki/security/advisories/GHSA-g5gj-9ggf-9vmq"
51+
]
52+
},
53+
{
54+
"id":"CVE-2021-3909",
55+
"displayName":"CVE-2021-3909",
56+
"title":"[CVE-2021-3909] CWE-400: Uncontrolled Resource Consumption ('Resource Exhaustion')",
57+
"description":"OctoRPKI does not limit the length of a connection, allowing for a slowloris DOS attack to take place which makes OctoRPKI wait forever. Specifically, the repository that OctoRPKI sends HTTP requests to will keep the connection open for a day before a response is returned, but does keep drip feeding new bytes to keep the connection alive.",
58+
"cvssScore":7.5,
59+
"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
60+
"cwe":"CWE-400",
61+
"cve":"CVE-2021-3909",
62+
"reference":"https://ossindex.sonatype.org/vulnerability/CVE-2021-3909?component-type=golang&component-name=github.com%2Fcloudflare%2Fcfrpki&utm_source=python-requests&utm_medium=integration&utm_content=2.27.1",
63+
"externalReferences":[
64+
"http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2021-3909",
65+
"https://github.com/cloudflare/cfrpki/security/advisories/GHSA-8cvr-4rrf-f244"
66+
]
67+
},
68+
{
69+
"id":"CVE-2021-3910",
70+
"displayName":"CVE-2021-3910",
71+
"title":"[CVE-2021-3910] CWE-20: Improper Input Validation",
72+
"description":"OctoRPKI crashes when encountering a repository that returns an invalid ROA (just an encoded NUL (\\0) character).",
73+
"cvssScore":7.5,
74+
"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
75+
"cwe":"CWE-20",
76+
"cve":"CVE-2021-3910",
77+
"reference":"https://ossindex.sonatype.org/vulnerability/CVE-2021-3910?component-type=golang&component-name=github.com%2Fcloudflare%2Fcfrpki&utm_source=python-requests&utm_medium=integration&utm_content=2.27.1",
78+
"externalReferences":[
79+
"http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2021-3910",
80+
"https://github.com/cloudflare/cfrpki/security/advisories/GHSA-5mxh-2qfv-4g7j"
81+
]
82+
},
83+
{
84+
"id":"CVE-2021-3978",
85+
"displayName":"CVE-2021-3978",
86+
"title":"[CVE-2021-3978] CWE-281: Improper Preservation of Permissions",
87+
"description":"github.com/cloudflare/cfrpki - Improper Preservation of Permissions",
88+
"cvssScore":7.4,
89+
"cvssVector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N",
90+
"cwe":"CWE-281",
91+
"cve":"CVE-2021-3978",
92+
"reference":"https://ossindex.sonatype.org/vulnerability/CVE-2021-3978?component-type=golang&component-name=github.com%2Fcloudflare%2Fcfrpki&utm_source=python-requests&utm_medium=integration&utm_content=2.27.1",
93+
"externalReferences":[
94+
"http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2021-3978",
95+
"https://github.com/cloudflare/cfrpki/security/advisories/GHSA-3pqh-p72c-fj85"
96+
]
97+
},
98+
{
99+
"id":"CVE-2021-3911",
100+
"displayName":"CVE-2021-3911",
101+
"title":"[CVE-2021-3911] CWE-252: Unchecked Return Value",
102+
"description":"If the ROA that a repository returns contains too many bits for the IP address then OctoRPKI will crash.",
103+
"cvssScore":6.5,
104+
"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H",
105+
"cwe":"CWE-252",
106+
"cve":"CVE-2021-3911",
107+
"reference":"https://ossindex.sonatype.org/vulnerability/CVE-2021-3911?component-type=golang&component-name=github.com%2Fcloudflare%2Fcfrpki&utm_source=python-requests&utm_medium=integration&utm_content=2.27.1",
108+
"externalReferences":[
109+
"http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2021-3911",
110+
"https://github.com/cloudflare/cfrpki/security/advisories/GHSA-w6ww-fmfx-2x22"
111+
]
112+
},
113+
{
114+
"id":"CVE-2021-3912",
115+
"displayName":"CVE-2021-3912",
116+
"title":"[CVE-2021-3912] CWE-400: Uncontrolled Resource Consumption ('Resource Exhaustion')",
117+
"description":"OctoRPKI tries to load the entire contents of a repository in memory, and in the case of a GZIP bomb, unzip it in memory, making it possible to create a repository that makes OctoRPKI run out of memory (and thus crash).",
118+
"cvssScore":6.5,
119+
"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H",
120+
"cwe":"CWE-400",
121+
"cve":"CVE-2021-3912",
122+
"reference":"https://ossindex.sonatype.org/vulnerability/CVE-2021-3912?component-type=golang&component-name=github.com%2Fcloudflare%2Fcfrpki&utm_source=python-requests&utm_medium=integration&utm_content=2.27.1",
123+
"externalReferences":[
124+
"http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2021-3912",
125+
"https://github.com/cloudflare/cfrpki/security/advisories/GHSA-g9wh-3vrx-r7hg"
126+
]
127+
},
128+
{
129+
"id":"sonatype-2022-0972",
130+
"displayName":"sonatype-2022-0972",
131+
"title":"1 vulnerability found",
132+
"description":"1 non-CVE vulnerability found. To see more details, please create a free account at https://ossindex.sonatype.org/ and request for this information using your registered account",
133+
"cvssScore":6.5,
134+
"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N",
135+
"cwe":"CWE-699",
136+
"reference":"https://ossindex.sonatype.org/vulnerability/sonatype-2022-0972",
137+
"externalReferences":[
138+
139+
]
140+
}
141+
]
142+
}
143+
]
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
[
2+
{
3+
"affected_versions": [],
4+
"fixed_versions": [],
5+
"aliases": [
6+
"CVE-2021-3907"
7+
]
8+
},
9+
{
10+
"affected_versions": [],
11+
"fixed_versions": [],
12+
"aliases": [
13+
"CVE-2021-3761"
14+
]
15+
},
16+
{
17+
"affected_versions": [],
18+
"fixed_versions": [],
19+
"aliases": [
20+
"CVE-2021-3908"
21+
]
22+
},
23+
{
24+
"affected_versions": [],
25+
"fixed_versions": [],
26+
"aliases": [
27+
"CVE-2021-3909"
28+
]
29+
},
30+
{
31+
"affected_versions": [],
32+
"fixed_versions": [],
33+
"aliases": [
34+
"CVE-2021-3910"
35+
]
36+
},
37+
{
38+
"affected_versions": [],
39+
"fixed_versions": [],
40+
"aliases": [
41+
"CVE-2021-3978"
42+
]
43+
},
44+
{
45+
"affected_versions": [],
46+
"fixed_versions": [],
47+
"aliases": [
48+
"CVE-2021-3911"
49+
]
50+
},
51+
{
52+
"affected_versions": [],
53+
"fixed_versions": [],
54+
"aliases": [
55+
"CVE-2021-3912"
56+
]
57+
},
58+
{
59+
"affected_versions": [],
60+
"fixed_versions": [],
61+
"aliases": [
62+
"sonatype-2022-0972"
63+
]
64+
}
65+
]

vulntotal/tests/test_oss_index.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#
2+
# Copyright (c) nexB Inc. and others. All rights reserved.
3+
# http://nexb.com and https://github.com/nexB/vulnerablecode/
4+
# The VulnTotal software is licensed under the Apache License version 2.0.
5+
# Data generated with VulnTotal require an acknowledgment.
6+
#
7+
# You may not use this software except in compliance with the License.
8+
# You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0
9+
# Unless required by applicable law or agreed to in writing, software distributed
10+
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
11+
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
12+
# specific language governing permissions and limitations under the License.
13+
#
14+
# When you publish or redistribute any data created with VulnTotal or any VulnTotal
15+
# derivative work, you must accompany this data with the following acknowledgment:
16+
#
17+
# Generated with VulnTotal and provided on an "AS IS" BASIS, WITHOUT WARRANTIES
18+
# OR CONDITIONS OF ANY KIND, either express or implied. No content created from
19+
# VulnTotal should be considered or used as legal advice. Consult an Attorney
20+
# for any legal advice.
21+
# VulnTotal is a free software tool from nexB Inc. and others.
22+
# Visit https://github.com/nexB/vulnerablecode/ for support and download.
23+
24+
import json
25+
from pathlib import Path
26+
27+
from commoncode import testcase
28+
from packageurl import PackageURL
29+
30+
from vulnerabilities.tests import util_tests
31+
from vulntotal.datasources import oss_index
32+
33+
34+
class TestDeps(testcase.FileBasedTesting):
35+
test_data_dir = str(Path(__file__).resolve().parent / "test_data" / "oss_index")
36+
37+
def test_parse_advisory(self):
38+
advisory_file = self.get_test_loc("advisory.json")
39+
with open(advisory_file) as f:
40+
advisory = json.load(f)
41+
results = [adv.to_dict() for adv in oss_index.parse_advisory(advisory)]
42+
expected_file = self.get_test_loc("parse_advisory-expected.json", must_exist=False)
43+
util_tests.check_results_against_json(results, expected_file)

0 commit comments

Comments
 (0)