diff --git a/docker/exporter/exporter.py b/docker/exporter/exporter.py index 2b55e74aab8..145d4d71a60 100755 --- a/docker/exporter/exporter.py +++ b/docker/exporter/exporter.py @@ -61,8 +61,7 @@ def _export_ecosystem_to_bucket(self, ecosystem, tmp_dir): file_path = os.path.join(tmp_dir, bug.id() + '.json') osv.write_vulnerability( - bug.to_vulnerability(v0_7=False, v0_8=True, include_source=True), - file_path) + bug.to_vulnerability(include_source=True), file_path) zip_file.write(file_path, os.path.basename(file_path)) def upload_single(source_path, target_path): diff --git a/docker/importer/importer.py b/docker/importer/importer.py index c17e855308a..daf09d222e1 100755 --- a/docker/importer/importer.py +++ b/docker/importer/importer.py @@ -176,8 +176,7 @@ def import_new_oss_fuzz_entries(self, repo, oss_fuzz_source): continue logging.info('Writing %s', bug.key.id()) - osv.write_vulnerability( - bug.to_vulnerability(v0_7=False, v0_8=True), vulnerability_path) + osv.write_vulnerability(bug.to_vulnerability(), vulnerability_path) # The source of truth is now this yaml file. bug.source_of_truth = osv.SourceOfTruth.SOURCE_REPO exported.append(bug) @@ -372,8 +371,7 @@ def export_oss_fuzz(vulnerability, testcase_id, issue_id): continue _, source_id = osv.parse_source_id(bug.source_id) - executor.submit(export_oss_fuzz, - bug.to_vulnerability(v0_7=False, v0_8=True), source_id, + executor.submit(export_oss_fuzz, bug.to_vulnerability(), source_id, bug.issue_id) diff --git a/docker/importer/importer_test.py b/docker/importer/importer_test.py index 6ff212edcde..051fe30be8f 100644 --- a/docker/importer/importer_test.py +++ b/docker/importer/importer_test.py @@ -99,8 +99,22 @@ def test_basic(self, mock_publish): 'ecosystem_specific': { 'severity': 'MEDIUM', }, + 'database_specific': { + 'database_specific': 1337, + }, }], affected_fuzzy=['5-29', '5-30'], + credits=[{ + 'name': 'Foo bar', + 'contact': [], + }, { + 'name': 'Bar foo', + 'contact': ['mailto:bar@foo.com'], + }], + severities=[{ + 'type': 'CVSS_V3', + 'score': '7.5', + }], details=( 'OSS-Fuzz report: ' 'https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1064\n\n' @@ -121,7 +135,11 @@ def test_basic(self, mock_publish): source_of_truth=osv.SourceOfTruth.INTERNAL, status=1, summary='Heap-buffer-overflow in cdf_file_property_info', - timestamp=datetime.datetime(2021, 1, 15, 0, 0, 24, 559102)).put() + timestamp=datetime.datetime(2021, 1, 15, 0, 0, 24, 559102), + database_specific={ + 'database_specific': 1337 + }, + ).put() self.mock_repo.add_file('2021-111.yaml', _EMPTY_VULNERABILITY) self.mock_repo.commit('User', 'user@email') @@ -158,12 +176,15 @@ def test_basic(self, mock_publish): self.mock_storage_client().get_bucket.assert_called_with('bucket') bucket = self.mock_storage_client().get_bucket('bucket') - expected_upload_contents = self._load_test_data('expected.json') + + expected_json = bucket.blob().upload_from_string.call_args[0][0] + self.expect_equal('expected.json', expected_json) + bucket.blob.assert_has_calls([ mock.call('testcase/5417710252982272.json'), - mock.call().upload_from_string(expected_upload_contents), + mock.call().upload_from_string(expected_json), mock.call('issue/1064.json'), - mock.call().upload_from_string(expected_upload_contents), + mock.call().upload_from_string(expected_json), ]) @mock.patch('google.cloud.pubsub_v1.PublisherClient.publish') diff --git a/docker/importer/testdata/ImporterTest_diff_basic.txt b/docker/importer/testdata/ImporterTest_diff_basic.txt index d7ba36a658e..b2101acca98 100644 --- a/docker/importer/testdata/ImporterTest_diff_basic.txt +++ b/docker/importer/testdata/ImporterTest_diff_basic.txt @@ -1,9 +1,9 @@ ('diff --git a/file/OSV-2017-134.yaml b/file/OSV-2017-134.yaml\n' 'new file mode 100644\n' - 'index 0000000..49f0c47\n' + 'index 0000000..f76d8c2\n' '--- /dev/null\n' '+++ b/file/OSV-2017-134.yaml\n' - '@@ -0,0 +1,31 @@\n' + '@@ -0,0 +1,44 @@\n' '+id: OSV-2017-134\n' '+summary: Heap-buffer-overflow in cdf_file_property_info\n' '+details: |\n' @@ -17,6 +17,8 @@ '+ cdf_check_summary_info\n' "+modified: '2021-01-01T00:00:00Z'\n" "+published: '2021-01-15T00:00:24.559102Z'\n" + '+database_specific:\n' + '+ database_specific: 1337.0\n' '+references:\n' '+- type: REPORT\n' '+ url: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1064\n' @@ -35,4 +37,15 @@ '+ - FILE5_29\n' '+ - FILE5_30\n' '+ ecosystem_specific:\n' - '+ severity: MEDIUM\n') \ No newline at end of file + '+ severity: MEDIUM\n' + '+ database_specific:\n' + '+ database_specific: 1337.0\n' + '+schema_version: 1.2.0\n' + '+severity:\n' + '+- type: CVSS_V3\n' + "+ score: '7.5'\n" + '+credits:\n' + '+- name: Foo bar\n' + '+- name: Bar foo\n' + '+ contact:\n' + '+ - mailto:bar@foo.com\n') \ No newline at end of file diff --git a/docker/importer/testdata/ImporterTest_expected.json.txt b/docker/importer/testdata/ImporterTest_expected.json.txt new file mode 100644 index 00000000000..329d511ec0c --- /dev/null +++ b/docker/importer/testdata/ImporterTest_expected.json.txt @@ -0,0 +1,19 @@ +('{"id": "OSV-2017-134", "summary": "Heap-buffer-overflow in ' + 'cdf_file_property_info", "details": "OSS-Fuzz report: ' + 'https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1064\\n\\nCrash type: ' + 'Heap-buffer-overflow READ 1\\nCrash ' + 'state:\\ncdf_file_property_info\\ncdf_file_summary_info\\ncdf_check_summary_info\\n", ' + '"modified": "2021-01-01T00:00:00Z", "published": ' + '"2021-01-15T00:00:24.559102Z", "database_specific": {"database_specific": ' + '1337.0}, "references": [{"type": "REPORT", "url": ' + '"https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1064"}], "affected": ' + '[{"package": {"name": "file", "ecosystem": "OSS-Fuzz", "purl": ' + '"pkg:generic/file"}, "ranges": [{"type": "GIT", "repo": ' + '"https://github.com/file/file.git", "events": [{"introduced": ' + '"17ee4cf670c363de8d2ea4a4897d7a699837873f"}, {"fixed": ' + '"19ccebafb7663c422c714e0c67fa4775abf91c43"}]}], "versions": ["FILE5_29", ' + '"FILE5_30"], "ecosystem_specific": {"severity": "MEDIUM"}, ' + '"database_specific": {"database_specific": 1337.0}}], "schema_version": ' + '"1.2.0", "severity": [{"type": "CVSS_V3", "score": "7.5"}], "credits": ' + '[{"name": "Foo bar"}, {"name": "Bar foo", "contact": ' + '["mailto:bar@foo.com"]}]}') \ No newline at end of file diff --git a/docker/worker/testdata/BLAH-123.old.yaml b/docker/worker/testdata/BLAH-123.old.yaml index 940e48832e4..f14c318e1ba 100644 --- a/docker/worker/testdata/BLAH-123.old.yaml +++ b/docker/worker/testdata/BLAH-123.old.yaml @@ -6,7 +6,9 @@ summary: A vulnerability details: | Blah blah blah Blah -severity: HIGH +severity: +- type: CVSS_V3 + score: '7.5' affects: ranges: - type: GIT diff --git a/docker/worker/testdata/BLAH-123.yaml b/docker/worker/testdata/BLAH-123.yaml index b679ff2752a..7e8f4ad07ab 100644 --- a/docker/worker/testdata/BLAH-123.yaml +++ b/docker/worker/testdata/BLAH-123.yaml @@ -3,7 +3,13 @@ summary: A vulnerability details: | Blah blah blah Blah -severity: HIGH +severity: +- type: CVSS_V3 + score: '7.5' +credits: +- name: Foo bar + contact: + - mailto:foo@bar.com references: - type: WEB url: https://ref.com/ref @@ -19,3 +25,5 @@ affected: - fixed: 8d8242f545e9cec3e6d0d2e3f5bde8be1c659735 versions: - branch-v0.1.1 +database_specific: + specific: 1337 diff --git a/docker/worker/testdata/BLAH-124.old.yaml b/docker/worker/testdata/BLAH-124.old.yaml index 04be47834dd..93ef15a88d7 100644 --- a/docker/worker/testdata/BLAH-124.old.yaml +++ b/docker/worker/testdata/BLAH-124.old.yaml @@ -6,7 +6,6 @@ summary: A vulnerability details: | Blah blah blah Blah -severity: HIGH affects: ranges: - type: GIT diff --git a/docker/worker/testdata/BLAH-125.yaml b/docker/worker/testdata/BLAH-125.yaml index b1a0ded4800..870f6547a98 100644 --- a/docker/worker/testdata/BLAH-125.yaml +++ b/docker/worker/testdata/BLAH-125.yaml @@ -6,7 +6,9 @@ summary: A vulnerability details: | Blah blah blah Blah -severity: HIGH +severity: +- type: CVSS_V3 + score: '7.5' affects: ranges: - type: GIT diff --git a/docker/worker/testdata/BLAH-126.yaml b/docker/worker/testdata/BLAH-126.yaml index 21edbb77cab..3768b6ec31d 100644 --- a/docker/worker/testdata/BLAH-126.yaml +++ b/docker/worker/testdata/BLAH-126.yaml @@ -1,18 +1,18 @@ id: BLAH-126 -package: - name: blah.com/package - ecosystem: golang summary: A vulnerability details: | Blah blah blah Blah -severity: HIGH -affects: +affected: +- package: + name: blah.com/package + ecosystem: golang ranges: - type: GIT repo: https://osv-test/repo/url - introduced: eefe8ec3f1f90d0e684890e810f3f21e8500a4cd - fixed: 8d8242f545e9cec3e6d0d2e3f5bde8be1c659735 + events: + - introduced: eefe8ec3f1f90d0e684890e810f3f21e8500a4cd + - fixed: 8d8242f545e9cec3e6d0d2e3f5bde8be1c659735 versions: - branch-v0.1.1 references: diff --git a/docker/worker/testdata/BLAH-127.old.yaml b/docker/worker/testdata/BLAH-127.old.yaml index 4db09782188..a9e0ffcdbcb 100644 --- a/docker/worker/testdata/BLAH-127.old.yaml +++ b/docker/worker/testdata/BLAH-127.old.yaml @@ -6,7 +6,6 @@ summary: A vulnerability details: | Blah blah blah Blah -severity: HIGH affects: ranges: - type: GIT diff --git a/docker/worker/testdata/BLAH-128.yaml b/docker/worker/testdata/BLAH-128.yaml index 82677cb9239..0a1d5af0064 100644 --- a/docker/worker/testdata/BLAH-128.yaml +++ b/docker/worker/testdata/BLAH-128.yaml @@ -3,7 +3,6 @@ summary: A vulnerability details: | Blah blah blah Blah -severity: HIGH references: - type: WEB url: https://ref.com/ref diff --git a/docker/worker/testdata/ImpactTest_basic.txt b/docker/worker/testdata/ImpactTest_basic.txt index 2dcd2cacee9..9036593e961 100644 --- a/docker/worker/testdata/ImpactTest_basic.txt +++ b/docker/worker/testdata/ImpactTest_basic.txt @@ -20,11 +20,11 @@ 'v0.1.1']}], 'affected_ranges': [], 'aliases': [], + 'credits': [], 'database_specific': None, 'db_id': 'OSV-2020-1337', 'details': 'DETAILS', 'ecosystem': ['ecosystem'], - 'ecosystem_specific': None, 'fixed': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', 'has_affected': True, 'is_fixed': True, @@ -43,7 +43,7 @@ 'osv-2020-1337', 'project'], 'semver_fixed_indexes': [], - 'severity': 'MEDIUM', + 'severities': [], 'source': 'oss-fuzz', 'source_id': 'oss-fuzz:123', 'source_of_truth': 1, diff --git a/docker/worker/testdata/ImpactTest_fixed_range_too_long.txt b/docker/worker/testdata/ImpactTest_fixed_range_too_long.txt index 932f9f87427..534583e03f3 100644 --- a/docker/worker/testdata/ImpactTest_fixed_range_too_long.txt +++ b/docker/worker/testdata/ImpactTest_fixed_range_too_long.txt @@ -18,11 +18,11 @@ 'v0.2']}], 'affected_ranges': [], 'aliases': [], + 'credits': [], 'database_specific': None, 'db_id': 'OSV-2020-1337', 'details': 'DETAILS', 'ecosystem': ['ecosystem'], - 'ecosystem_specific': None, 'fixed': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd:b587c21c36a84e16cfc6b39eb68578d43b5281ad', 'has_affected': True, 'is_fixed': True, @@ -41,7 +41,7 @@ 'osv-2020-1337', 'project'], 'semver_fixed_indexes': [], - 'severity': 'MEDIUM', + 'severities': [], 'source': 'oss-fuzz', 'source_id': 'oss-fuzz:123', 'source_of_truth': 1, diff --git a/docker/worker/testdata/ImpactTest_not_fixed.txt b/docker/worker/testdata/ImpactTest_not_fixed.txt index 9b6fc248caf..60a1c16f6de 100644 --- a/docker/worker/testdata/ImpactTest_not_fixed.txt +++ b/docker/worker/testdata/ImpactTest_not_fixed.txt @@ -18,11 +18,11 @@ 'v0.2']}], 'affected_ranges': [], 'aliases': [], + 'credits': [], 'database_specific': None, 'db_id': 'OSV-2020-1337', 'details': 'DETAILS', 'ecosystem': ['ecosystem'], - 'ecosystem_specific': None, 'fixed': '', 'has_affected': True, 'is_fixed': False, @@ -41,7 +41,7 @@ 'osv-2020-1337', 'project'], 'semver_fixed_indexes': [], - 'severity': 'MEDIUM', + 'severities': [], 'source': 'oss-fuzz', 'source_id': 'oss-fuzz:123', 'source_of_truth': 1, diff --git a/docker/worker/testdata/ImpactTest_range.txt b/docker/worker/testdata/ImpactTest_range.txt index 5ee8d3c7a22..9c4f9318c10 100644 --- a/docker/worker/testdata/ImpactTest_range.txt +++ b/docker/worker/testdata/ImpactTest_range.txt @@ -18,11 +18,11 @@ 'v0.2']}], 'affected_ranges': [], 'aliases': [], + 'credits': [], 'database_specific': None, 'db_id': 'OSV-2020-1337', 'details': 'DETAILS', 'ecosystem': ['ecosystem'], - 'ecosystem_specific': None, 'fixed': 'b1c95a196f22d06fcf80df8c6691cd113d8fefff:36f0bd9549298b44f9ff2496c9dd1326b3a9d0e2', 'has_affected': True, 'is_fixed': True, @@ -41,7 +41,7 @@ 'osv-2020-1337', 'project'], 'semver_fixed_indexes': [], - 'severity': 'MEDIUM', + 'severities': [], 'source': 'oss-fuzz', 'source_id': 'oss-fuzz:123', 'source_of_truth': 1, diff --git a/docker/worker/testdata/ImpactTest_simplify_range.txt b/docker/worker/testdata/ImpactTest_simplify_range.txt index 2dcd2cacee9..9036593e961 100644 --- a/docker/worker/testdata/ImpactTest_simplify_range.txt +++ b/docker/worker/testdata/ImpactTest_simplify_range.txt @@ -20,11 +20,11 @@ 'v0.1.1']}], 'affected_ranges': [], 'aliases': [], + 'credits': [], 'database_specific': None, 'db_id': 'OSV-2020-1337', 'details': 'DETAILS', 'ecosystem': ['ecosystem'], - 'ecosystem_specific': None, 'fixed': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', 'has_affected': True, 'is_fixed': True, @@ -43,7 +43,7 @@ 'osv-2020-1337', 'project'], 'semver_fixed_indexes': [], - 'severity': 'MEDIUM', + 'severities': [], 'source': 'oss-fuzz', 'source_id': 'oss-fuzz:123', 'source_of_truth': 1, diff --git a/docker/worker/testdata/ImpactTest_zero_regression_range.txt b/docker/worker/testdata/ImpactTest_zero_regression_range.txt index c2d1c02cdb6..70994fc1700 100644 --- a/docker/worker/testdata/ImpactTest_zero_regression_range.txt +++ b/docker/worker/testdata/ImpactTest_zero_regression_range.txt @@ -16,11 +16,11 @@ 'v0.1.1']}], 'affected_ranges': [], 'aliases': [], + 'credits': [], 'database_specific': None, 'db_id': 'OSV-2020-1337', 'details': 'DETAILS', 'ecosystem': ['ecosystem'], - 'ecosystem_specific': None, 'fixed': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735', 'has_affected': True, 'is_fixed': True, @@ -39,7 +39,7 @@ 'osv-2020-1337', 'project'], 'semver_fixed_indexes': [], - 'severity': 'MEDIUM', + 'severities': [], 'source': 'oss-fuzz', 'source_id': 'oss-fuzz:123', 'source_of_truth': 1, diff --git a/docker/worker/testdata/UpdateTest_diff_update.txt b/docker/worker/testdata/UpdateTest_diff_update.txt index 4ab44a23a24..b0c51a46233 100644 --- a/docker/worker/testdata/UpdateTest_diff_update.txt +++ b/docker/worker/testdata/UpdateTest_diff_update.txt @@ -1,16 +1,25 @@ ('diff --git a/BLAH-123.yaml b/BLAH-123.yaml\n' - 'index b679ff2..ac4d47d 100644\n' + 'index 7e8f4ad..7799017 100644\n' '--- a/BLAH-123.yaml\n' '+++ b/BLAH-123.yaml\n' - '@@ -4,6 +4,7 @@ details: |\n' + '@@ -3,13 +3,9 @@ summary: A vulnerability\n' + ' details: |\n' ' Blah blah blah\n' ' Blah\n' - ' severity: HIGH\n' + '-severity:\n' + '-- type: CVSS_V3\n' + "- score: '7.5'\n" + '-credits:\n' + '-- name: Foo bar\n' + '- contact:\n' + '- - mailto:foo@bar.com\n' "+modified: '2021-01-01T00:00:00Z'\n" + '+database_specific:\n' + '+ specific: 1337.0\n' ' references:\n' ' - type: WEB\n' ' url: https://ref.com/ref\n' - '@@ -17,5 +18,9 @@ affected:\n' + '@@ -23,7 +19,16 @@ affected:\n' ' events:\n' ' - introduced: eefe8ec3f1f90d0e684890e810f3f21e8500a4cd\n' ' - fixed: 8d8242f545e9cec3e6d0d2e3f5bde8be1c659735\n' @@ -18,5 +27,14 @@ '+ - fixed: b9b3fd4732695b83c3068b7b6a14bb372ec31f98\n' ' versions:\n' ' - branch-v0.1.1\n' + '-database_specific:\n' + '- specific: 1337\n' '+ - branch_1_cherrypick_regress\n' - '+ - v0.1.1\n') \ No newline at end of file + '+ - v0.1.1\n' + '+severity:\n' + '+- type: CVSS_V3\n' + "+ score: '7.5'\n" + '+credits:\n' + '+- name: Foo bar\n' + '+ contact:\n' + '+ - mailto:foo@bar.com\n') \ No newline at end of file diff --git a/docker/worker/testdata/UpdateTest_diff_update_limit.txt b/docker/worker/testdata/UpdateTest_diff_update_limit.txt index 680e23084e8..0f0a52461b9 100644 --- a/docker/worker/testdata/UpdateTest_diff_update_limit.txt +++ b/docker/worker/testdata/UpdateTest_diff_update_limit.txt @@ -1,16 +1,16 @@ ('diff --git a/BLAH-128.yaml b/BLAH-128.yaml\n' - 'index 82677cb..73f4965 100644\n' + 'index 0a1d5af..108af13 100644\n' '--- a/BLAH-128.yaml\n' '+++ b/BLAH-128.yaml\n' - '@@ -4,6 +4,7 @@ details: |\n' + '@@ -3,6 +3,7 @@ summary: A vulnerability\n' + ' details: |\n' ' Blah blah blah\n' ' Blah\n' - ' severity: HIGH\n' "+modified: '2021-01-01T00:00:00Z'\n" ' references:\n' ' - type: WEB\n' ' url: https://ref.com/ref\n' - '@@ -21,3 +22,12 @@ affected:\n' + '@@ -20,3 +21,12 @@ affected:\n' ' events:\n' ' - introduced: 1.13.0\n' ' - limit: 1.14.2\n' diff --git a/docker/worker/testdata/UpdateTest_update.txt b/docker/worker/testdata/UpdateTest_update.txt index 83b7966d7a4..11d25c89c2f 100644 --- a/docker/worker/testdata/UpdateTest_update.txt +++ b/docker/worker/testdata/UpdateTest_update.txt @@ -20,11 +20,11 @@ 'v0.1.1']}], 'affected_ranges': [], 'aliases': [], - 'database_specific': None, + 'credits': [{'contact': ['mailto:foo@bar.com'], 'name': 'Foo bar'}], + 'database_specific': {'specific': 1337.0}, 'db_id': 'BLAH-123', 'details': 'Blah blah blah\nBlah\n', 'ecosystem': ['golang'], - 'ecosystem_specific': None, 'fixed': '', 'has_affected': True, 'is_fixed': True, @@ -44,7 +44,7 @@ 'golang', 'package'], 'semver_fixed_indexes': [], - 'severity': None, + 'severities': [{'score': '7.5', 'type': 'CVSS_V3'}], 'source': 'source', 'source_id': 'source:BLAH-123.yaml', 'source_of_truth': 2, diff --git a/docker/worker/testdata/UpdateTest_update_add_fix.txt b/docker/worker/testdata/UpdateTest_update_add_fix.txt index 943ce6b6e6a..86de6c8df74 100644 --- a/docker/worker/testdata/UpdateTest_update_add_fix.txt +++ b/docker/worker/testdata/UpdateTest_update_add_fix.txt @@ -20,11 +20,11 @@ 'v0.1.1']}], 'affected_ranges': [], 'aliases': [], + 'credits': [], 'database_specific': None, 'db_id': 'BLAH-124', 'details': 'Blah blah blah\nBlah\n', 'ecosystem': ['golang'], - 'ecosystem_specific': None, 'fixed': '', 'has_affected': True, 'is_fixed': True, @@ -44,7 +44,7 @@ 'golang', 'package'], 'semver_fixed_indexes': [], - 'severity': None, + 'severities': [], 'source': 'source', 'source_id': 'source:BLAH-124.yaml', 'source_of_truth': 2, diff --git a/docker/worker/testdata/UpdateTest_update_bucket_0.txt b/docker/worker/testdata/UpdateTest_update_bucket_0.txt index cd3611a1c53..75ba0cc57fe 100644 --- a/docker/worker/testdata/UpdateTest_update_bucket_0.txt +++ b/docker/worker/testdata/UpdateTest_update_bucket_0.txt @@ -1,52 +1,32 @@ { 'affected': [], 'affected_fuzzy': [], - 'affected_packages': [ { 'database_specific': None, - 'ecosystem_specific': { 'url': 'https://go.googlesource.com/vulndb/+/refs/heads/main/reports/GO-2021-0085.toml'}, - 'package': { 'ecosystem': 'Go', - 'name': 'github.com/opencontainers/runc/libcontainer', - 'purl': 'pkg:golang/github.com/opencontainers/runc/libcontainer'}, - 'ranges': [ { 'events': [ { 'type': 'introduced', - 'value': '0'}, - { 'type': 'fixed', - 'value': 'v1.0.0-rc8.0.20190930145003-cad42f6e0932'}], - 'repo_url': None, - 'type': 'SEMVER'}], - 'versions': []}], + 'affected_packages': [], 'affected_ranges': [], 'aliases': ['CVE-2019-16884'], + 'credits': [], 'database_specific': None, 'db_id': 'GO-2021-0085', 'details': 'AppArmor restrictions may be bypassed due to improper ' 'validation of mount\n' 'targets, allowing a malicious image to mount volumes over e.g. ' '/proc.\n', - 'ecosystem': ['Go'], - 'ecosystem_specific': None, + 'ecosystem': [], 'fixed': '', - 'has_affected': True, - 'is_fixed': True, + 'has_affected': False, + 'is_fixed': False, 'issue_id': None, 'last_modified': datetime.datetime(2021, 4, 14, 12, 0), - 'project': ['github.com/opencontainers/runc/libcontainer'], + 'project': [], 'public': True, - 'purl': ['pkg:golang/github.com/opencontainers/runc/libcontainer'], + 'purl': [], 'reference_url_types': { 'https://github.com/opencontainers/runc/commit/cad42f6e0932db0ce08c3a3d9e89e6063ec283e4': 'FIX', 'https://github.com/opencontainers/runc/issues/2128': 'WEB', 'https://github.com/opencontainers/runc/pull/2130': 'FIX'}, 'regressed': '', 'related': [], - 'search_indices': [ '0085', - '2021', - 'com', - 'github', - 'github.com/opencontainers/runc/libcontainer', - 'go', - 'go-2021-0085', - 'libcontainer', - 'opencontainers', - 'runc'], - 'semver_fixed_indexes': [ '00000001.00000000.00000000-1rc8.00000000.120190930145003-cad42f6e0932'], - 'severity': None, + 'search_indices': ['0085', '2021', 'go', 'go-2021-0085'], + 'semver_fixed_indexes': [], + 'severities': [], 'source': 'source', 'source_id': 'source:a/b/test.json', 'source_of_truth': 2, diff --git a/docker/worker/testdata/UpdateTest_update_bucket_1.txt b/docker/worker/testdata/UpdateTest_update_bucket_1.txt index d134b6ab873..b8d6877c347 100644 --- a/docker/worker/testdata/UpdateTest_update_bucket_1.txt +++ b/docker/worker/testdata/UpdateTest_update_bucket_1.txt @@ -1,20 +1,9 @@ { 'affected': [], 'affected_fuzzy': [], - 'affected_packages': [ { 'database_specific': None, - 'ecosystem_specific': { 'Symbols': [ 'mountToRootfs'], - 'url': 'https://go.googlesource.com/vulndb/+/refs/heads/main/reports/GO-2021-0087.toml'}, - 'package': { 'ecosystem': 'Go', - 'name': 'github.com/opencontainers/runc/libcontainer', - 'purl': 'pkg:golang/github.com/opencontainers/runc/libcontainer'}, - 'ranges': [ { 'events': [ { 'type': 'introduced', - 'value': '0'}, - { 'type': 'fixed', - 'value': 'v1.0.0-rc9.0.20200122160610-2fc03cc11c77'}], - 'repo_url': None, - 'type': 'SEMVER'}], - 'versions': []}], + 'affected_packages': [], 'affected_ranges': [], 'aliases': ['CVE-2019-19921'], + 'credits': [], 'database_specific': None, 'db_id': 'GO-2021-0087', 'details': 'A race while mounting volumes allows a possible ' @@ -23,33 +12,23 @@ 'with\n' 'custom volume mount configurations to escape the container.\n' '\n', - 'ecosystem': ['Go'], - 'ecosystem_specific': None, + 'ecosystem': [], 'fixed': '', - 'has_affected': True, - 'is_fixed': True, + 'has_affected': False, + 'is_fixed': False, 'issue_id': None, 'last_modified': datetime.datetime(2021, 4, 14, 12, 0), - 'project': ['github.com/opencontainers/runc/libcontainer'], + 'project': [], 'public': True, - 'purl': ['pkg:golang/github.com/opencontainers/runc/libcontainer'], + 'purl': [], 'reference_url_types': { 'https://github.com/opencontainers/runc/commit/2fc03cc11c775b7a8b2e48d7ee447cb9bef32ad0': 'FIX', 'https://github.com/opencontainers/runc/issues/2197': 'WEB', 'https://github.com/opencontainers/runc/pull/2207': 'FIX'}, 'regressed': '', 'related': [], - 'search_indices': [ '0087', - '2021', - 'com', - 'github', - 'github.com/opencontainers/runc/libcontainer', - 'go', - 'go-2021-0087', - 'libcontainer', - 'opencontainers', - 'runc'], - 'semver_fixed_indexes': [ '00000001.00000000.00000000-1rc9.00000000.120200122160610-2fc03cc11c77'], - 'severity': None, + 'search_indices': ['0087', '2021', 'go', 'go-2021-0087'], + 'semver_fixed_indexes': [], + 'severities': [], 'source': 'source', 'source_id': 'source:a/b/test.json', 'source_of_truth': 2, diff --git a/docker/worker/testdata/UpdateTest_update_limit.txt b/docker/worker/testdata/UpdateTest_update_limit.txt index 399f60ff78c..1288d3da17e 100644 --- a/docker/worker/testdata/UpdateTest_update_limit.txt +++ b/docker/worker/testdata/UpdateTest_update_limit.txt @@ -34,11 +34,11 @@ 'v0.1.1']}], 'affected_ranges': [], 'aliases': [], + 'credits': [], 'database_specific': None, 'db_id': 'BLAH-128', 'details': 'Blah blah blah\nBlah\n', 'ecosystem': ['PyPI'], - 'ecosystem_specific': None, 'fixed': '', 'has_affected': True, 'is_fixed': False, @@ -52,7 +52,7 @@ 'related': [], 'search_indices': ['128', 'blah', 'blah-128', 'grpcio', 'pypi'], 'semver_fixed_indexes': [], - 'severity': None, + 'severities': [], 'source': 'source', 'source_id': 'source:BLAH-128.yaml', 'source_of_truth': 2, diff --git a/docker/worker/testdata/UpdateTest_update_maven.txt b/docker/worker/testdata/UpdateTest_update_maven.txt index e560d9fe7df..378eae15bd3 100644 --- a/docker/worker/testdata/UpdateTest_update_maven.txt +++ b/docker/worker/testdata/UpdateTest_update_maven.txt @@ -32,11 +32,11 @@ '2.4']}], 'affected_ranges': [], 'aliases': ['CVE-2021-38555'], + 'credits': [], 'database_specific': None, 'db_id': 'GHSA-838r-hvwh-24h8', 'details': '', 'ecosystem': ['Maven'], - 'ecosystem_specific': None, 'fixed': '', 'has_affected': True, 'is_fixed': True, @@ -60,7 +60,7 @@ 'org', 'org.apache.any23:apache-any23'], 'semver_fixed_indexes': [], - 'severity': None, + 'severities': [], 'source': 'source', 'source_id': 'source:GHSA-838r-hvwh-24h8.json', 'source_of_truth': 2, diff --git a/docker/worker/testdata/UpdateTest_update_new.txt b/docker/worker/testdata/UpdateTest_update_new.txt index 2b69341a996..bd586beefa2 100644 --- a/docker/worker/testdata/UpdateTest_update_new.txt +++ b/docker/worker/testdata/UpdateTest_update_new.txt @@ -9,10 +9,10 @@ 'value': 'eefe8ec3f1f90d0e684890e810f3f21e8500a4cd'}, { 'type': 'fixed', 'value': '8d8242f545e9cec3e6d0d2e3f5bde8be1c659735'}, - { 'type': 'fixed', - 'value': 'b9b3fd4732695b83c3068b7b6a14bb372ec31f98'}, { 'type': 'introduced', - 'value': 'febfac1940086bc1f6d3dc33fda0a1d1ba336209'}], + 'value': 'febfac1940086bc1f6d3dc33fda0a1d1ba336209'}, + { 'type': 'fixed', + 'value': 'b9b3fd4732695b83c3068b7b6a14bb372ec31f98'}], 'repo_url': 'https://osv-test/repo/url', 'type': 'GIT'}], 'versions': [ 'branch-v0.1.1', @@ -20,11 +20,11 @@ 'v0.1.1']}], 'affected_ranges': [], 'aliases': [], + 'credits': [], 'database_specific': None, 'db_id': 'BLAH-126', 'details': 'Blah blah blah\nBlah\n', 'ecosystem': ['golang'], - 'ecosystem_specific': None, 'fixed': '', 'has_affected': True, 'is_fixed': True, @@ -44,7 +44,7 @@ 'golang', 'package'], 'semver_fixed_indexes': [], - 'severity': None, + 'severities': [], 'source': 'source', 'source_id': 'source:BLAH-126.yaml', 'source_of_truth': 2, diff --git a/docker/worker/testdata/UpdateTest_update_no_introduced.txt b/docker/worker/testdata/UpdateTest_update_no_introduced.txt index a4e42b86ba5..2ab25777f6f 100644 --- a/docker/worker/testdata/UpdateTest_update_no_introduced.txt +++ b/docker/worker/testdata/UpdateTest_update_no_introduced.txt @@ -19,11 +19,11 @@ 'v0.1.1']}], 'affected_ranges': [], 'aliases': [], + 'credits': [], 'database_specific': None, 'db_id': 'BLAH-127', 'details': 'Blah blah blah\nBlah\n', 'ecosystem': ['golang'], - 'ecosystem_specific': None, 'fixed': '', 'has_affected': True, 'is_fixed': True, @@ -43,7 +43,7 @@ 'golang', 'package'], 'semver_fixed_indexes': [], - 'severity': None, + 'severities': [], 'source': 'source', 'source_id': 'source:BLAH-127.yaml', 'source_of_truth': 2, diff --git a/docker/worker/testdata/UpdateTest_update_pypi.txt b/docker/worker/testdata/UpdateTest_update_pypi.txt index 214fcd4884d..4a762e7aa07 100644 --- a/docker/worker/testdata/UpdateTest_update_pypi.txt +++ b/docker/worker/testdata/UpdateTest_update_pypi.txt @@ -120,11 +120,11 @@ '1.31.0rc2']}], 'affected_ranges': [], 'aliases': [], + 'credits': [], 'database_specific': None, 'db_id': 'PYSEC-123', 'details': 'Blah blah blah\nBlah\n', 'ecosystem': ['PyPI'], - 'ecosystem_specific': None, 'fixed': '', 'has_affected': True, 'is_fixed': True, @@ -138,7 +138,7 @@ 'related': [], 'search_indices': ['123', 'grpcio', 'pypi', 'pysec', 'pysec-123'], 'semver_fixed_indexes': [], - 'severity': None, + 'severities': [], 'source': 'source', 'source_id': 'source:PYSEC-123.yaml', 'source_of_truth': 2, diff --git a/docker/worker/worker_test.py b/docker/worker/worker_test.py index 8eb71e6e8e1..a9c90231a4f 100644 --- a/docker/worker/worker_test.py +++ b/docker/worker/worker_test.py @@ -14,6 +14,7 @@ """Worker tests.""" # pylint: disable=line-too-long import datetime +import hashlib import os import shutil import tempfile @@ -37,6 +38,16 @@ # pylint: disable=protected-access,invalid-name +def _sha256(test_name): + """Get sha256 sum.""" + hasher = hashlib.sha256() + + with open(os.path.join(TEST_DATA_DIR, test_name), 'rb') as f: + hasher.update(f.read()) + + return hasher.hexdigest() + + class OssFuzzDetailsTest(unittest.TestCase): """Details generation tests.""" @@ -604,8 +615,7 @@ def test_update(self): message.attributes = { 'source': 'source', 'path': 'BLAH-123.yaml', - 'original_sha256': ('d35b787ba467d6d45c2046c0c5a9c237' - 'ab4b7d9942cc9ad25f2bc27a2ffa7859'), + 'original_sha256': _sha256('BLAH-123.yaml'), 'deleted': 'false', } task_runner._source_update(message) @@ -638,8 +648,7 @@ def test_update_limit(self): message.attributes = { 'source': 'source', 'path': 'BLAH-128.yaml', - 'original_sha256': ('54683c1611241e58bfe7489df6d5431fa' - '476ff15eaf7511e2800246733ff3975'), + 'original_sha256': _sha256('BLAH-128.yaml'), 'deleted': 'false', } task_runner._source_update(message) @@ -676,8 +685,7 @@ def test_update_add_fix(self): message.attributes = { 'source': 'source', 'path': 'BLAH-124.yaml', - 'original_sha256': ('5d6224b81fb100d51bf61c2568b1c75f' - '1df355ace1872af1b7eb0b1b5d93f477'), + 'original_sha256': _sha256('BLAH-124.yaml'), 'deleted': 'false', } task_runner._source_update(message) @@ -712,8 +720,7 @@ def test_update_no_introduced(self): message.attributes = { 'source': 'source', 'path': 'BLAH-127.yaml', - 'original_sha256': ('41ba4799f09d73ab41d60f8fbeaa83a7' - '9f6d8a301330c5c1061cf113ff96a8a3'), + 'original_sha256': _sha256('BLAH-127.yaml'), 'deleted': 'false', } task_runner._source_update(message) @@ -762,8 +769,7 @@ def test_update_new(self): message.attributes = { 'source': 'source', 'path': 'BLAH-126.yaml', - 'original_sha256': ('5e1c2f30f6312cb16f5eedac88f92992' - 'dd015e2891d17e84ee2ab8af78b801b9'), + 'original_sha256': _sha256('BLAH-126.yaml'), 'deleted': 'false', } task_runner._source_update(message) @@ -789,8 +795,7 @@ def test_update_delete(self): message.attributes = { 'source': 'source', 'path': 'BLAH-123.yaml', - 'original_sha256': ('d35b787ba467d6d45c2046c0c5a9c237' - 'ab4b7d9942cc9ad25f2bc27a2ffa7859'), + 'original_sha256': _sha256('BLAH-123.yaml'), 'deleted': 'true', } task_runner._source_update(message) @@ -805,8 +810,7 @@ def test_update_no_changes(self): message.attributes = { 'source': 'source', 'path': 'BLAH-125.yaml', - 'original_sha256': ('f3914d12891a3a441cb19cfe5c11f9b6' - 'b5cd0c87c3c14c40d54559dad4bb813a'), + 'original_sha256': _sha256('BLAH-125.yaml'), 'deleted': 'false', } task_runner._source_update(message) @@ -857,8 +861,7 @@ def mock_push_source_changes(*args, **kwargs): message.attributes = { 'source': 'source', 'path': 'BLAH-123.yaml', - 'original_sha256': ('d35b787ba467d6d45c2046c0c5a9c237' - 'ab4b7d9942cc9ad25f2bc27a2ffa7859'), + 'original_sha256': _sha256('BLAH-123.yaml'), 'deleted': 'false', } task_runner._source_update(message) @@ -887,8 +890,7 @@ def test_update_pypi(self): message.attributes = { 'source': 'source', 'path': 'PYSEC-123.yaml', - 'original_sha256': ('f664bd547299c003e658feb81d4e3b36' - '17c1433e301037a5a825a615581fc6ee'), + 'original_sha256': _sha256('PYSEC-123.yaml'), 'deleted': 'false', } task_runner._source_update(message) @@ -930,8 +932,7 @@ def test_update_maven(self): message.attributes = { 'source': 'source', 'path': 'GHSA-838r-hvwh-24h8.json', - 'original_sha256': ('0e522f0c1785756021839af1fba8a603' - 'a56f8864039c75d69d5d552a1fa44e9d'), + 'original_sha256': _sha256('GHSA-838r-hvwh-24h8.json'), 'deleted': 'false', } task_runner._source_update(message) diff --git a/docs/build.py b/docs/build.py index 6b73c84070c..a755e203a06 100644 --- a/docs/build.py +++ b/docs/build.py @@ -124,12 +124,9 @@ def main(): property_description_workaround(spec['definitions']['v1Query']) property_description_workaround(spec['definitions']['osvVulnerability']) - property_description_workaround(spec['definitions']['osvAffectedRange']) replace_property_name(spec['definitions']['osvVulnerability'], 'databaseSpecific', 'database_specific') - replace_property_name(spec['definitions']['osvVulnerability'], - 'ecosystemSpecific', 'ecosystem_specific') with open('sections.md') as f: spec['info']['description'] = f.read() diff --git a/docs/osv_service_v1.swagger.json b/docs/osv_service_v1.swagger.json index a40f7fb31a4..da1e3d4aa11 100644 --- a/docs/osv_service_v1.swagger.json +++ b/docs/osv_service_v1.swagger.json @@ -186,61 +186,21 @@ }, "description": "Affected versions and commits." }, - "osvAffectedRange": { + "osvCredit": { "type": "object", "properties": { - "type": { - "description": "Required. The type of version information.", - "allOf": [ - { - "$ref": "#/definitions/osvAffectedRangeType" - } - ] - }, - "repo": { - "type": "string", - "description": "Required if type is GIT. The publicly accessible URL of the repo that can\nbe directly passed to clone commands." - }, - "introduced": { + "name": { "type": "string", - "description": "Strongly recommended. The earliest version/commit where this vulnerability\nwas introduced in. If not specified, *all* commits/versions prior to the\n`fixed` commit/version are assumed to be affected." + "description": "The name to give credit to." }, - "fixed": { - "type": "string", - "description": "Optional only if `introduced` is specified. The version/commit that this\nvulnerability was fixed in. This must be reachable from the \"introduced\"\nversion/commit.\n\nIf the vulnerability is not fixed, this will be unset." - } - } - }, - "osvAffectedRangeType": { - "type": "string", - "enum": [ - "UNSPECIFIED", - "GIT", - "SEMVER", - "ECOSYSTEM" - ], - "default": "UNSPECIFIED", - "description": "Type of the version information." - }, - "osvAffects": { - "type": "object", - "properties": { - "ranges": { - "type": "array", - "items": { - "$ref": "#/definitions/osvAffectedRange" - }, - "description": "Required (at least one entry). The commit/version ranges that contain this\nvulnerability.\n\nWhen provided, OSV will attempt to detect and append additional ranges that\nmay be affected as well (e.g. cherry-picks to other branches)." - }, - "versions": { + "contact": { "type": "array", "items": { "type": "string" }, - "description": "Optional. List of affected versions. This should match tag names in the\nupstream repository. OSV will populate or add to this automatically\nbased on the provided commit ranges." + "description": "Contact methods (URLs)." } - }, - "description": "Affected versions and commits. Deprecated." + } }, "osvEvent": { "type": "object", @@ -332,25 +292,40 @@ "ADVISORY", "REPORT", "FIX", - "PACKAGE" + "PACKAGE", + "ARTICLE" ], "default": "NONE" }, "osvSeverity": { + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/osvSeverityType", + "description": "The type of this severity entry." + }, + "score": { + "type": "string", + "description": "The quantitative score." + } + } + }, + "osvSeverityType": { "type": "string", "enum": [ - "NONE", - "LOW", - "MEDIUM", - "HIGH", - "CRITICAL" + "UNSPECIFIED", + "CVSS_V3" ], - "default": "NONE", - "description": "Vulnerability severity information. The exact meaning of these levels are\nspecific to OSS-Fuzz." + "default": "UNSPECIFIED", + "description": "Type of the severity." }, "osvVulnerability": { "type": "object", "properties": { + "schemaVersion": { + "type": "string", + "description": "The OSV schema version." + }, "id": { "type": "string", "description": "The `id` field is a unique identifier for the vulnerability entry. It is a\nstring of the format `-`, where `DB` names the database and\n`ENTRYID` is in the format used by the database. For example:\n\u201cOSV-2020-111\u201d, \u201cCVE-2021-3114\u201d, or \u201cGHSA-vp9c-fpxx-744v\u201d." @@ -400,14 +375,6 @@ "type": "string", "description": "Required. Any additional human readable details for the vulnerability." }, - "affects": { - "description": "Required. Affected commit ranges and versions. Deprecated.", - "allOf": [ - { - "$ref": "#/definitions/osvAffects" - } - ] - }, "affected": { "type": "array", "items": { @@ -423,20 +390,22 @@ "description": "Optional. URLs to more information/advisories (including the\nscheme e.g \"https://\")." }, "severity": { - "description": "Deprecated and will be removed in the future.", - "allOf": [ - { - "$ref": "#/definitions/osvSeverity" - } - ] + "type": "array", + "items": { + "$ref": "#/definitions/osvSeverity" + }, + "description": "Optional. Severity of the vulnerability." + }, + "credits": { + "type": "array", + "items": { + "$ref": "#/definitions/osvCredit" + }, + "description": "Optional. Credits for the vulnerability." }, "database_specific": { "type": "object", "description": "Optional. JSON object holding additional information about the\nvulnerability as defined by the database for which the record applies." - }, - "ecosystem_specific": { - "type": "object", - "description": "Optional. JSON object holding additional information about the\nvulnerability as defined by the ecosystem for which the record applies." } }, "description": "A vulnerability entry.\nThe protobuf representation is *NOT* stable and only used for implementing\nthe JSON based API." diff --git a/gcp/api/integration_tests.py b/gcp/api/integration_tests.py index 4f12249983f..05fc1724e03 100644 --- a/gcp/api/integration_tests.py +++ b/gcp/api/integration_tests.py @@ -41,6 +41,7 @@ class IntegrationTests(unittest.TestCase): _VULN_744 = { 'published': '2020-07-04T00:00:01.948828Z', + 'schema_version': '1.2.0', 'affected': [{ 'database_specific': { 'source': 'https://github.com/google/oss-fuzz-vulns/' @@ -51,7 +52,8 @@ class IntegrationTests(unittest.TestCase): }, 'package': { 'ecosystem': 'OSS-Fuzz', - 'name': 'mruby' + 'name': 'mruby', + 'purl': 'pkg:generic/mruby' }, 'ranges': [{ 'events': [{ @@ -82,6 +84,7 @@ class IntegrationTests(unittest.TestCase): _VULN_2258 = { 'published': '2020-12-11T00:00:45.856Z', + 'schema_version': '1.2.0', 'details': 'INVALID', 'id': 'OSV-2020-2258', 'references': [{ @@ -92,6 +95,8 @@ class IntegrationTests(unittest.TestCase): } _VULN_GO_2020_0004 = { + 'schema_version': + '1.2.0', 'id': 'GO-2020-0004', 'affected': [{ @@ -109,7 +114,8 @@ class IntegrationTests(unittest.TestCase): }, 'package': { 'ecosystem': 'Go', - 'name': 'github.com/nanobox-io/golang-nanoauth' + 'name': 'github.com/nanobox-io/golang-nanoauth', + 'purl': 'pkg:golang/github.com/nanobox-io/golang-nanoauth' }, 'ranges': [{ 'events': [{ @@ -140,6 +146,8 @@ class IntegrationTests(unittest.TestCase): } _VULN_GO_2020_0015 = { + 'schema_version': + '1.2.0', 'affected': [{ 'database_specific': { 'source': 'https://storage.googleapis.com/go-vulndb/byID/' @@ -152,7 +160,8 @@ class IntegrationTests(unittest.TestCase): }, 'package': { 'ecosystem': 'Go', - 'name': 'golang.org/x/text/encoding/unicode' + 'name': 'golang.org/x/text/encoding/unicode', + 'purl': 'pkg:golang/golang.org/x/text/encoding/unicode', }, 'ranges': [{ 'events': [{ @@ -174,7 +183,8 @@ class IntegrationTests(unittest.TestCase): }, 'package': { 'ecosystem': 'Go', - 'name': 'golang.org/x/text/transform' + 'name': 'golang.org/x/text/transform', + 'purl': 'pkg:golang/golang.org/x/text/transform' }, 'ranges': [{ 'events': [{ @@ -217,6 +227,8 @@ class IntegrationTests(unittest.TestCase): } _VULN_RUSTSEC_2020_0105 = { + 'schema_version': + '1.2.0', 'id': 'RUSTSEC-2020-0105', 'summary': diff --git a/gcp/api/server.py b/gcp/api/server.py index 614996a830b..d50139b44af 100644 --- a/gcp/api/server.py +++ b/gcp/api/server.py @@ -110,7 +110,7 @@ def QueryAffectedNew(self, request, context): def bug_to_response(bug): """Convert a Bug entity to a response object.""" - return bug.to_vulnerability(v0_7=False, v0_8=True, include_source=True) + return bug.to_vulnerability(include_source=True) def _get_bugs(bug_ids, to_response=bug_to_response): diff --git a/gcp/api/v1/api_descriptor.pb b/gcp/api/v1/api_descriptor.pb index 4c9291c0d37..71eef148721 100644 Binary files a/gcp/api/v1/api_descriptor.pb and b/gcp/api/v1/api_descriptor.pb differ diff --git a/gcp/appengine/frontend_handlers.py b/gcp/appengine/frontend_handlers.py index 2e24fccc82e..08e8eaf7cd6 100644 --- a/gcp/appengine/frontend_handlers.py +++ b/gcp/appengine/frontend_handlers.py @@ -79,8 +79,7 @@ def index(): def bug_to_response(bug, detailed=True): """Convert a Bug entity to a response object.""" - response = osv.vulnerability_to_dict( - bug.to_vulnerability(v0_7=False, v0_8=True)) + response = osv.vulnerability_to_dict(bug.to_vulnerability()) response.update({ 'isFixed': bug.is_fixed, 'invalid': bug.status == osv.BugStatus.INVALID diff --git a/lib/osv/impact.py b/lib/osv/impact.py index 2f3b65830f9..6d580f0be9c 100644 --- a/lib/osv/impact.py +++ b/lib/osv/impact.py @@ -360,26 +360,6 @@ def update_affected_commits(bug_id, commits, public): _throttled_delete(to_delete) -def enumerate_versions_pre_0_8(package, ecosystem, affected_ranges): - """Enumerate versions from SEMVER and ECOSYSTEM input ranges.""" - versions = set() - for affected_range in affected_ranges: - if affected_range.type in (vulnerability_pb2.AffectedRange.ECOSYSTEM, - vulnerability_pb2.AffectedRange.SEMVER): - if not affected_range.introduced and not affected_range.fixed: - continue - - current_versions = ecosystem.enumerate_versions(package, - affected_range.introduced, - affected_range.fixed) - if current_versions: - versions.update(current_versions) - - versions = list(versions) - ecosystem.sort_versions(versions) - return versions - - def enumerate_versions(package, ecosystem, affected_range): """Enumerate versions from SEMVER and ECOSYSTEM input ranges.""" versions = set() @@ -487,138 +467,12 @@ def _analyze_git_ranges(repo_analyzer, checkout_path, affected_range, return new_versions, commits -def _analyze_git_ranges_pre_0_8(repo_analyzer, checkout_path, vulnerability, - range_collectors, new_versions, commits): - """Analyze git ranges (pre 0.8).""" - package_repo_dir = tempfile.TemporaryDirectory() - package_repo = None - - try: - grouped_git_ranges = {} - for affected_range in vulnerability.affects.ranges: - if affected_range.type != vulnerability_pb2.AffectedRange.GIT: - continue - - # Convert empty values ('') to None. - introduced = affected_range.introduced or None - fixed = affected_range.fixed or None - range_collectors[affected_range.repo].add(introduced, fixed) - - grouped_git_ranges.setdefault(affected_range.repo, []).append( - (introduced, fixed)) - - for repo_url, affected_ranges in grouped_git_ranges.items(): - if checkout_path: - repo_name = os.path.basename(repo_url.rstrip('/')).rstrip('.git') - package_repo = repos.ensure_updated_checkout( - repo_url, os.path.join(checkout_path, repo_name)) - else: - package_repo_dir.cleanup() - package_repo_dir = tempfile.TemporaryDirectory() - package_repo = repos.clone_with_retries(repo_url, package_repo_dir.name) - - all_introduced = [] - all_fixed = [] - for (introduced, fixed) in affected_ranges: - if introduced: - all_introduced.append(introduced) - - if fixed: - all_fixed.append(fixed) - - try: - result = repo_analyzer.get_affected(package_repo, all_introduced, - all_fixed) - except ImpactError: - logging.warning('Got error while analyzing git range: %s', - traceback.format_exc()) - continue - - for introduced, fixed in result.affected_ranges: - range_collectors[repo_url].add(introduced, fixed) - - new_versions.update(result.tags) - commits.update(result.commits) - finally: - package_repo_dir.cleanup() - - return range_collectors, new_versions, commits - - -def _analyze_pre_0_8(vulnerability, - analyze_git=True, - checkout_path=None, - detect_cherrypicks=True, - versions_from_repo=True): - """Update and analyze a vulnerability based on its input ranges (pre 0.8).""" - # Repo -> Git range collectors - range_collectors = collections.defaultdict(RangeCollector) - new_versions = set() - commits = set() - - # Analyze git ranges. - if analyze_git: - repo_analyzer = RepoAnalyzer(detect_cherrypicks=detect_cherrypicks) - _analyze_git_ranges_pre_0_8(repo_analyzer, checkout_path, vulnerability, - range_collectors, new_versions, commits) - - # Enumerate ECOSYSTEM and SEMVER ranges. - ecosystem_helpers = ecosystems.get(vulnerability.package.ecosystem) - if ecosystem_helpers: - versions = enumerate_versions_pre_0_8(vulnerability.package.name, - ecosystem_helpers, - vulnerability.affects.ranges) - else: - logging.warning('No ecosystem helpers implemented for %s', - vulnerability.package.ecosystem) - versions = [] - - # Add additional versions derived from commits and tags. - if versions_from_repo: - versions.extend(new_versions) - - # Apply changes. - has_changes = False - for repo_url, range_collector in range_collectors.items(): - for introduced, fixed in range_collector.ranges(): - if any( - # Range collectors use None, while the proto uses '' for empty - # values. - (affected_range.introduced or None) == introduced and - (affected_range.fixed or None) == fixed - for affected_range in vulnerability.affects.ranges): - # Range already exists. - continue - - has_changes = True - vulnerability.affects.ranges.add( - type=vulnerability_pb2.AffectedRange.Type.GIT, - repo=repo_url, - introduced=introduced, - fixed=fixed) - - for version in sorted(versions): - if version not in vulnerability.affects.versions: - has_changes = True - vulnerability.affects.versions.append(version) - - if not has_changes: - return AnalyzeResult(False, commits) - - vulnerability.modified.FromDatetime(models.utcnow()) - return AnalyzeResult(True, commits) - - def analyze(vulnerability, analyze_git=True, checkout_path=None, detect_cherrypicks=True, versions_from_repo=True): """Update and analyze a vulnerability based on its input ranges.""" - if not vulnerability.affected: - return _analyze_pre_0_8(vulnerability, analyze_git, checkout_path, - detect_cherrypicks, versions_from_repo) - commits = set() has_changes = False for affected_package in vulnerability.affected: diff --git a/lib/osv/models.py b/lib/osv/models.py index 41e5798a3ed..ab05dfc9a70 100644 --- a/lib/osv/models.py +++ b/lib/osv/models.py @@ -30,6 +30,8 @@ from . import sources from . import vulnerability_pb2 +SCHEMA_VERSION = '1.2.0' + def _check_valid_severity(prop, value): """Check valid severity.""" @@ -190,6 +192,18 @@ class AffectedPackage(ndb.Model): ecosystem_specific = ndb.JsonProperty() +class Credit(ndb.Model): + """Credits.""" + name = ndb.StringProperty() + contact = ndb.StringProperty(repeated=True) + + +class Severity(ndb.Model): + """Severity.""" + type = ndb.StringProperty() + score = ndb.StringProperty() + + class Bug(ndb.Model): """Bug entity.""" OSV_ID_PREFIX = 'OSV-' @@ -238,7 +252,9 @@ class Bug(ndb.Model): # Vulnerability details. details = ndb.TextProperty() # Severity of the bug. - severity = ndb.StringProperty(validator=_check_valid_severity) + severities = ndb.LocalStructuredProperty(Severity, repeated=True) + # Credits for the bug. + credits = ndb.LocalStructuredProperty(Credit, repeated=True) # Whether or not the bug is public (OSS-Fuzz only). public = ndb.BooleanProperty() # Reference URL types (dict of url -> type). @@ -253,8 +269,6 @@ class Bug(ndb.Model): is_fixed = ndb.BooleanProperty() # Database specific. database_specific = ndb.JsonProperty() - # Ecosystem specific. - ecosystem_specific = ndb.JsonProperty() # Normalized SEMVER fixed indexes for querying. semver_fixed_indexes = ndb.StringProperty(repeated=True) # Affected packages and versions. @@ -392,54 +406,6 @@ def _pre_put_hook(self): self.key = ndb.Key(Bug, key_id) - def _update_from_pre_0_8(self, vulnerability): - """Update from pre 0.8 import.""" - if self.affected_packages: - affected_package = self.affected_packages[0] - else: - affected_package = AffectedPackage() - self.affected_packages.append(affected_package) - - affected_package.package = Package( - name=vulnerability.package.name, - ecosystem=vulnerability.package.ecosystem, - purl=vulnerability.package.purl) - - vuln_dict = sources.vulnerability_to_dict(vulnerability) - if vulnerability.database_specific: - affected_package.database_specific = vuln_dict['database_specific'] - - if vulnerability.ecosystem_specific: - affected_package.ecosystem_specific = vuln_dict['ecosystem_specific'] - - affected_package.versions = list(vulnerability.affects.versions) - affected_package.ranges = [] - events_by_type = {} - - for affected_range in vulnerability.affects.ranges: - events = events_by_type.setdefault( - (vulnerability_pb2.AffectedRange.Type.Name( - affected_range.type), affected_range.repo), []) - - # An empty introduced in 0.7 now needs to be represented as '0' in 0.8. - introduced = AffectedEvent( - type='introduced', value=affected_range.introduced or '0') - if introduced not in events: - events.append(introduced) - - if affected_range.fixed: - fixed = AffectedEvent(type='fixed', value=affected_range.fixed) - if fixed not in events: - events.append(fixed) - - for (range_type, repo_url), events in events_by_type.items(): - affected_range = AffectedRange2(type=range_type, events=events) - - if range_type == 'GIT' and repo_url: - affected_range.repo_url = repo_url - - affected_package.ranges.append(affected_range) - def update_from_vulnerability(self, vulnerability): """Set fields from vulnerability. Does not set the ID.""" self.summary = vulnerability.summary @@ -459,10 +425,6 @@ def update_from_vulnerability(self, vulnerability): self.aliases = list(vulnerability.aliases) self.related = list(vulnerability.related) - if not vulnerability.affected: - self._update_from_pre_0_8(vulnerability) - return - self.affected_packages = [] for affected_package in vulnerability.affected: current = AffectedPackage() @@ -509,60 +471,26 @@ def update_from_vulnerability(self, vulnerability): self.affected_packages.append(current) - def _get_pre_0_8_affects(self): - """Get pre 0.8 schema affects field.""" - affected_package = self.affected_packages[0] - affects = vulnerability_pb2.Affects(versions=affected_package.versions) - for affected_range in affected_package.ranges: - # Convert flattened events to range pairs (pre-0.8 schema). - # TODO(ochang): Remove this once all consumers are migrated. - # pylint: disable=cell-var-from-loop - new_range = lambda x, y: vulnerability_pb2.AffectedRange( - type=vulnerability_pb2.AffectedRange.Type.Value(affected_range.type), - repo=affected_range.repo_url, - introduced=x, - fixed=y) - last_introduced = None - - # Sort the flattened events, then find corresponding [introduced, - # fixed) pairs. - for event in sorted_events(affected_package.package.ecosystem, - affected_range.type, affected_range.events): - if event.type == 'introduced': - if last_introduced is not None and affected_range.type == 'GIT': - # If this is GIT, then we need to store all "introduced", even if - # they overlap. - affects.ranges.append(new_range(last_introduced, '')) - last_introduced = None - - if last_introduced is None: - # If not GIT, ignore overlapping introduced versions since they're - # redundant. - last_introduced = event.value - if last_introduced == '0': - last_introduced = '' - - if event.type == 'fixed': - if affected_range.type != 'GIT' and last_introduced is None: - # No prior introduced, so ignore this invalid entry. - continue + self.severities = [] + for severity in vulnerability.severity: + self.severities.append( + Severity( + type=vulnerability_pb2.Severity.Type.Name(severity.type), + score=severity.score)) - # Found a complete pair. - affects.ranges.append(new_range(last_introduced, event.value)) - last_introduced = None + self.credits = [] + for credit in vulnerability.credits: + self.credits.append( + Credit(name=credit.name, contact=list(credit.contact))) - if last_introduced is not None: - affects.ranges.append(new_range(last_introduced, '')) - - return affects + if vulnerability.database_specific: + self.database_specific = json_format.MessageToDict( + vulnerability.database_specific, preserving_proto_field_name=True) - def to_vulnerability(self, include_source=False, v0_7=False, v0_8=True): + def to_vulnerability(self, include_source=False): """Convert to Vulnerability proto.""" package = None - ecosystem_specific = None - database_specific = None affected = [] - affects = None source_link = None if self.source and include_source: @@ -571,67 +499,42 @@ def to_vulnerability(self, include_source=False, v0_7=False, v0_8=True): source_link = source_repo.link + sources.source_path(source_repo, self) if self.affected_packages: - if v0_7: - # The pre-0.8 schema only supports a single package, so we take the - # first. - affected_package = self.affected_packages[0] - - package = vulnerability_pb2.Package( - name=affected_package.package.name, - ecosystem=affected_package.package.ecosystem, - purl=affected_package.package.purl) - - try: - affects = self._get_pre_0_8_affects() - except Exception: - # Unsupported conversion. Just skip for now since this code will be - # deleted very soon. - pass + for affected_package in self.affected_packages: + ranges = [] + for affected_range in affected_package.ranges: + events = [] + for event in affected_range.events: + kwargs = {event.type: event.value} + events.append(vulnerability_pb2.Event(**kwargs)) + + current_range = vulnerability_pb2.Range( + type=vulnerability_pb2.Range.Type.Value(affected_range.type), + repo=affected_range.repo_url, + events=events) + + ranges.append(current_range) + + current = vulnerability_pb2.Affected( + package=vulnerability_pb2.Package( + name=affected_package.package.name, + ecosystem=affected_package.package.ecosystem, + purl=affected_package.package.purl), + ranges=ranges, + versions=affected_package.versions) - if affected_package.ecosystem_specific: - ecosystem_specific = affected_package.ecosystem_specific if affected_package.database_specific: - database_specific = affected_package.database_specific - - if v0_8: - for affected_package in self.affected_packages: - ranges = [] - for affected_range in affected_package.ranges: - events = [] - for event in affected_range.events: - kwargs = {event.type: event.value} - events.append(vulnerability_pb2.Event(**kwargs)) + current.database_specific.update(affected_package.database_specific) - current_range = vulnerability_pb2.Range( - type=vulnerability_pb2.Range.Type.Value(affected_range.type), - repo=affected_range.repo_url, - events=events) + if source_link: + current.database_specific.update({'source': source_link}) - ranges.append(current_range) - - current = vulnerability_pb2.Affected( - package=vulnerability_pb2.Package( - name=affected_package.package.name, - ecosystem=affected_package.package.ecosystem, - purl=affected_package.package.purl), - ranges=ranges, - versions=affected_package.versions) - - if affected_package.database_specific: - current.database_specific.update(affected_package.database_specific) - - if source_link: - current.database_specific.update({'source': source_link}) - - if affected_package.ecosystem_specific: - current.ecosystem_specific.update( - affected_package.ecosystem_specific) + if affected_package.ecosystem_specific: + current.ecosystem_specific.update(affected_package.ecosystem_specific) - affected.append(current) + affected.append(current) details = self.details if self.status == bug.BugStatus.INVALID: - affects = None affected = None details = 'INVALID' @@ -657,7 +560,20 @@ def to_vulnerability(self, include_source=False, v0_7=False, v0_8=True): vulnerability_pb2.Reference( url=url, type=vulnerability_pb2.Reference.Type.Value(url_type))) + severity = [] + for entry in self.severities: + severity.append( + vulnerability_pb2.Severity( + type=vulnerability_pb2.Severity.Type.Value(entry.type), + score=entry.score)) + + credits_ = [] + for credit in self.credits: + credits_.append( + vulnerability_pb2.Credit(name=credit.name, contact=credit.contact)) + result = vulnerability_pb2.Vulnerability( + schema_version=SCHEMA_VERSION, id=self.id(), published=published, modified=modified, @@ -667,18 +583,13 @@ def to_vulnerability(self, include_source=False, v0_7=False, v0_8=True): summary=self.summary, details=details, package=package, - affects=affects, affected=affected, + severity=severity, + credits=credits_, references=references) - if ecosystem_specific: - result.ecosystem_specific.update(ecosystem_specific) - - if database_specific: - result.database_specific.update(database_specific) - - if source_link and v0_7: - result.database_specific.update({'source': source_link}) + if self.database_specific: + result.database_specific.update(self.database_specific) return result diff --git a/lib/osv/vulnerability.proto b/lib/osv/vulnerability.proto index 2cd6f00de3f..8e38183a15a 100644 --- a/lib/osv/vulnerability.proto +++ b/lib/osv/vulnerability.proto @@ -88,20 +88,6 @@ message AffectedRange { string fixed = 4; } -// Affected versions and commits. Deprecated. -message Affects { - // Required (at least one entry). The commit/version ranges that contain this - // vulnerability. - // - // When provided, OSV will attempt to detect and append additional ranges that - // may be affected as well (e.g. cherry-picks to other branches). - repeated AffectedRange ranges = 1; - // Optional. List of affected versions. This should match tag names in the - // upstream repository. OSV will populate or add to this automatically - // based on the provided commit ranges. - repeated string versions = 2; -} - // Version events. message Event { // The earliest version/commit where this vulnerability @@ -148,14 +134,23 @@ message Affected { google.protobuf.Struct database_specific = 5; } -// Vulnerability severity information. The exact meaning of these levels are -// specific to OSS-Fuzz. -enum Severity { - NONE = 0; - LOW = 1; - MEDIUM = 2; - HIGH = 3; - CRITICAL = 4; +message Severity { + // Type of the severity. + enum Type { + UNSPECIFIED = 0; + CVSS_V3 = 1; + } + // The type of this severity entry. + Type type = 1; + // The quantitative score. + string score = 2; +} + +message Credit { + // The name to give credit to. + string name = 1; + // Contact methods (URLs). + repeated string contact = 2; } // Reference URL. @@ -180,6 +175,8 @@ message Reference { // The protobuf representation is *NOT* stable and only used for implementing // the JSON based API. message Vulnerability { + // The OSV schema version. + string schema_version = 18; // The `id` field is a unique identifier for the vulnerability entry. It is a // string of the format `-`, where `DB` names the database and // `ENTRYID` is in the format used by the database. For example: @@ -204,19 +201,16 @@ message Vulnerability { string summary = 3; // Required. Any additional human readable details for the vulnerability. string details = 4; - // Required. Affected commit ranges and versions. Deprecated. - Affects affects = 6; // Required. Affected commit ranges and versions. repeated Affected affected = 17; // Optional. URLs to more information/advisories (including the // scheme e.g "https://"). repeated Reference references = 16; // Optional. JSON object holding additional information about the - // vulnerability as defined by the ecosystem for which the record applies. - google.protobuf.Struct ecosystem_specific = 14; - // Optional. JSON object holding additional information about the // vulnerability as defined by the database for which the record applies. google.protobuf.Struct database_specific = 15; - // Deprecated and will be removed in the future. - Severity severity = 5; + // Optional. Severity of the vulnerability. + repeated Severity severity = 19; + // Optional. Credits for the vulnerability. + repeated Credit credits = 20; } diff --git a/lib/osv/vulnerability_pb2.py b/lib/osv/vulnerability_pb2.py index 416d5571e16..a630041517a 100644 --- a/lib/osv/vulnerability_pb2.py +++ b/lib/osv/vulnerability_pb2.py @@ -2,7 +2,6 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: osv/vulnerability.proto -from google.protobuf.internal import enum_type_wrapper from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message from google.protobuf import reflection as _reflection @@ -22,56 +21,10 @@ syntax='proto3', serialized_options=None, create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\x17osv/vulnerability.proto\x12\x03osv\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"y\n\x06\x43ommit\x12\'\n\trepo_type\x18\x01 \x01(\x0e\x32\x14.osv.Commit.RepoType\x12\x10\n\x08repo_url\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\t\"$\n\x08RepoType\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x07\n\x03GIT\x10\x01\"8\n\x07Package\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x11\n\tecosystem\x18\x02 \x01(\t\x12\x0c\n\x04purl\x18\x03 \x01(\t\"\xa4\x01\n\rAffectedRange\x12%\n\x04type\x18\x01 \x01(\x0e\x32\x17.osv.AffectedRange.Type\x12\x0c\n\x04repo\x18\x02 \x01(\t\x12\x12\n\nintroduced\x18\x03 \x01(\t\x12\r\n\x05\x66ixed\x18\x04 \x01(\t\";\n\x04Type\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x07\n\x03GIT\x10\x01\x12\n\n\x06SEMVER\x10\x02\x12\r\n\tECOSYSTEM\x10\x03\"?\n\x07\x41\x66\x66\x65\x63ts\x12\"\n\x06ranges\x18\x01 \x03(\x0b\x32\x12.osv.AffectedRange\x12\x10\n\x08versions\x18\x02 \x03(\t\"9\n\x05\x45vent\x12\x12\n\nintroduced\x18\x01 \x01(\t\x12\r\n\x05\x66ixed\x18\x02 \x01(\t\x12\r\n\x05limit\x18\x03 \x01(\t\"\x8d\x01\n\x05Range\x12\x1d\n\x04type\x18\x01 \x01(\x0e\x32\x0f.osv.Range.Type\x12\x0c\n\x04repo\x18\x02 \x01(\t\x12\x1a\n\x06\x65vents\x18\x03 \x03(\x0b\x32\n.osv.Event\";\n\x04Type\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x07\n\x03GIT\x10\x01\x12\n\n\x06SEMVER\x10\x02\x12\r\n\tECOSYSTEM\x10\x03\"\xc0\x01\n\x08\x41\x66\x66\x65\x63ted\x12\x1d\n\x07package\x18\x01 \x01(\x0b\x32\x0c.osv.Package\x12\x1a\n\x06ranges\x18\x02 \x03(\x0b\x32\n.osv.Range\x12\x10\n\x08versions\x18\x03 \x03(\t\x12\x33\n\x12\x65\x63osystem_specific\x18\x04 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x32\n\x11\x64\x61tabase_specific\x18\x05 \x01(\x0b\x32\x17.google.protobuf.Struct\"\x93\x01\n\tReference\x12!\n\x04type\x18\x01 \x01(\x0e\x32\x13.osv.Reference.Type\x12\x0b\n\x03url\x18\x02 \x01(\t\"V\n\x04Type\x12\x08\n\x04NONE\x10\x00\x12\x07\n\x03WEB\x10\x01\x12\x0c\n\x08\x41\x44VISORY\x10\x02\x12\n\n\x06REPORT\x10\x03\x12\x07\n\x03\x46IX\x10\x04\x12\x0b\n\x07PACKAGE\x10\x05\x12\x0b\n\x07\x41RTICLE\x10\x06\"\xf8\x03\n\rVulnerability\x12\n\n\x02id\x18\x01 \x01(\t\x12-\n\tpublished\x18\x0b \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12,\n\x08modified\x18\n \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12-\n\twithdrawn\x18\x0c \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0f\n\x07\x61liases\x18\x08 \x03(\t\x12\x0f\n\x07related\x18\r \x03(\t\x12\x1d\n\x07package\x18\x02 \x01(\x0b\x32\x0c.osv.Package\x12\x0f\n\x07summary\x18\x03 \x01(\t\x12\x0f\n\x07\x64\x65tails\x18\x04 \x01(\t\x12\x1d\n\x07\x61\x66\x66\x65\x63ts\x18\x06 \x01(\x0b\x32\x0c.osv.Affects\x12\x1f\n\x08\x61\x66\x66\x65\x63ted\x18\x11 \x03(\x0b\x32\r.osv.Affected\x12\"\n\nreferences\x18\x10 \x03(\x0b\x32\x0e.osv.Reference\x12\x33\n\x12\x65\x63osystem_specific\x18\x0e \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x32\n\x11\x64\x61tabase_specific\x18\x0f \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x1f\n\x08severity\x18\x05 \x01(\x0e\x32\r.osv.Severity*A\n\x08Severity\x12\x08\n\x04NONE\x10\x00\x12\x07\n\x03LOW\x10\x01\x12\n\n\x06MEDIUM\x10\x02\x12\x08\n\x04HIGH\x10\x03\x12\x0c\n\x08\x43RITICAL\x10\x04\x62\x06proto3' + serialized_pb=b'\n\x17osv/vulnerability.proto\x12\x03osv\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"y\n\x06\x43ommit\x12\'\n\trepo_type\x18\x01 \x01(\x0e\x32\x14.osv.Commit.RepoType\x12\x10\n\x08repo_url\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\t\"$\n\x08RepoType\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x07\n\x03GIT\x10\x01\"8\n\x07Package\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x11\n\tecosystem\x18\x02 \x01(\t\x12\x0c\n\x04purl\x18\x03 \x01(\t\"\xa4\x01\n\rAffectedRange\x12%\n\x04type\x18\x01 \x01(\x0e\x32\x17.osv.AffectedRange.Type\x12\x0c\n\x04repo\x18\x02 \x01(\t\x12\x12\n\nintroduced\x18\x03 \x01(\t\x12\r\n\x05\x66ixed\x18\x04 \x01(\t\";\n\x04Type\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x07\n\x03GIT\x10\x01\x12\n\n\x06SEMVER\x10\x02\x12\r\n\tECOSYSTEM\x10\x03\"9\n\x05\x45vent\x12\x12\n\nintroduced\x18\x01 \x01(\t\x12\r\n\x05\x66ixed\x18\x02 \x01(\t\x12\r\n\x05limit\x18\x03 \x01(\t\"\x8d\x01\n\x05Range\x12\x1d\n\x04type\x18\x01 \x01(\x0e\x32\x0f.osv.Range.Type\x12\x0c\n\x04repo\x18\x02 \x01(\t\x12\x1a\n\x06\x65vents\x18\x03 \x03(\x0b\x32\n.osv.Event\";\n\x04Type\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x07\n\x03GIT\x10\x01\x12\n\n\x06SEMVER\x10\x02\x12\r\n\tECOSYSTEM\x10\x03\"\xc0\x01\n\x08\x41\x66\x66\x65\x63ted\x12\x1d\n\x07package\x18\x01 \x01(\x0b\x32\x0c.osv.Package\x12\x1a\n\x06ranges\x18\x02 \x03(\x0b\x32\n.osv.Range\x12\x10\n\x08versions\x18\x03 \x03(\t\x12\x33\n\x12\x65\x63osystem_specific\x18\x04 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x32\n\x11\x64\x61tabase_specific\x18\x05 \x01(\x0b\x32\x17.google.protobuf.Struct\"a\n\x08Severity\x12 \n\x04type\x18\x01 \x01(\x0e\x32\x12.osv.Severity.Type\x12\r\n\x05score\x18\x02 \x01(\t\"$\n\x04Type\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x0b\n\x07\x43VSS_V3\x10\x01\"\'\n\x06\x43redit\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07\x63ontact\x18\x02 \x03(\t\"\x93\x01\n\tReference\x12!\n\x04type\x18\x01 \x01(\x0e\x32\x13.osv.Reference.Type\x12\x0b\n\x03url\x18\x02 \x01(\t\"V\n\x04Type\x12\x08\n\x04NONE\x10\x00\x12\x07\n\x03WEB\x10\x01\x12\x0c\n\x08\x41\x44VISORY\x10\x02\x12\n\n\x06REPORT\x10\x03\x12\x07\n\x03\x46IX\x10\x04\x12\x0b\n\x07PACKAGE\x10\x05\x12\x0b\n\x07\x41RTICLE\x10\x06\"\xda\x03\n\rVulnerability\x12\x16\n\x0eschema_version\x18\x12 \x01(\t\x12\n\n\x02id\x18\x01 \x01(\t\x12-\n\tpublished\x18\x0b \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12,\n\x08modified\x18\n \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12-\n\twithdrawn\x18\x0c \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0f\n\x07\x61liases\x18\x08 \x03(\t\x12\x0f\n\x07related\x18\r \x03(\t\x12\x1d\n\x07package\x18\x02 \x01(\x0b\x32\x0c.osv.Package\x12\x0f\n\x07summary\x18\x03 \x01(\t\x12\x0f\n\x07\x64\x65tails\x18\x04 \x01(\t\x12\x1f\n\x08\x61\x66\x66\x65\x63ted\x18\x11 \x03(\x0b\x32\r.osv.Affected\x12\"\n\nreferences\x18\x10 \x03(\x0b\x32\x0e.osv.Reference\x12\x32\n\x11\x64\x61tabase_specific\x18\x0f \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x1f\n\x08severity\x18\x13 \x03(\x0b\x32\r.osv.Severity\x12\x1c\n\x07\x63redits\x18\x14 \x03(\x0b\x32\x0b.osv.Creditb\x06proto3' , dependencies=[google_dot_protobuf_dot_struct__pb2.DESCRIPTOR,google_dot_protobuf_dot_timestamp__pb2.DESCRIPTOR,]) -_SEVERITY = _descriptor.EnumDescriptor( - name='Severity', - full_name='osv.Severity', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='NONE', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='LOW', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='MEDIUM', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='HIGH', index=3, number=3, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='CRITICAL', index=4, number=4, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - serialized_start=1563, - serialized_end=1628, -) -_sym_db.RegisterEnumDescriptor(_SEVERITY) - -Severity = enum_type_wrapper.EnumTypeWrapper(_SEVERITY) -NONE = 0 -LOW = 1 -MEDIUM = 2 -HIGH = 3 -CRITICAL = 4 _COMMIT_REPOTYPE = _descriptor.EnumDescriptor( @@ -169,6 +122,31 @@ ) _sym_db.RegisterEnumDescriptor(_RANGE_TYPE) +_SEVERITY_TYPE = _descriptor.EnumDescriptor( + name='Type', + full_name='osv.Severity.Type', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='UNSPECIFIED', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='CVSS_V3', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + serialized_start=902, + serialized_end=938, +) +_sym_db.RegisterEnumDescriptor(_SEVERITY_TYPE) + _REFERENCE_TYPE = _descriptor.EnumDescriptor( name='Type', full_name='osv.Reference.Type', @@ -214,8 +192,8 @@ ], containing_type=None, serialized_options=None, - serialized_start=968, - serialized_end=1054, + serialized_start=1043, + serialized_end=1129, ) _sym_db.RegisterEnumDescriptor(_REFERENCE_TYPE) @@ -367,45 +345,6 @@ ) -_AFFECTS = _descriptor.Descriptor( - name='Affects', - full_name='osv.Affects', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='ranges', full_name='osv.Affects.ranges', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='versions', full_name='osv.Affects.versions', index=1, - number=2, type=9, cpp_type=9, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=443, - serialized_end=506, -) - - _EVENT = _descriptor.Descriptor( name='Event', full_name='osv.Event', @@ -447,8 +386,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=508, - serialized_end=565, + serialized_start=443, + serialized_end=500, ) @@ -494,8 +433,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=568, - serialized_end=709, + serialized_start=503, + serialized_end=644, ) @@ -554,8 +493,87 @@ extension_ranges=[], oneofs=[ ], - serialized_start=712, - serialized_end=904, + serialized_start=647, + serialized_end=839, +) + + +_SEVERITY = _descriptor.Descriptor( + name='Severity', + full_name='osv.Severity', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='type', full_name='osv.Severity.type', index=0, + number=1, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='score', full_name='osv.Severity.score', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + _SEVERITY_TYPE, + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=841, + serialized_end=938, +) + + +_CREDIT = _descriptor.Descriptor( + name='Credit', + full_name='osv.Credit', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='osv.Credit.name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='contact', full_name='osv.Credit.contact', index=1, + number=2, type=9, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=940, + serialized_end=979, ) @@ -594,8 +612,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=907, - serialized_end=1054, + serialized_start=982, + serialized_end=1129, ) @@ -608,75 +626,75 @@ create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( - name='id', full_name='osv.Vulnerability.id', index=0, + name='schema_version', full_name='osv.Vulnerability.schema_version', index=0, + number=18, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='id', full_name='osv.Vulnerability.id', index=1, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=b"".decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='published', full_name='osv.Vulnerability.published', index=1, + name='published', full_name='osv.Vulnerability.published', index=2, number=11, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='modified', full_name='osv.Vulnerability.modified', index=2, + name='modified', full_name='osv.Vulnerability.modified', index=3, number=10, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='withdrawn', full_name='osv.Vulnerability.withdrawn', index=3, + name='withdrawn', full_name='osv.Vulnerability.withdrawn', index=4, number=12, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='aliases', full_name='osv.Vulnerability.aliases', index=4, + name='aliases', full_name='osv.Vulnerability.aliases', index=5, number=8, type=9, cpp_type=9, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='related', full_name='osv.Vulnerability.related', index=5, + name='related', full_name='osv.Vulnerability.related', index=6, number=13, type=9, cpp_type=9, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='package', full_name='osv.Vulnerability.package', index=6, + name='package', full_name='osv.Vulnerability.package', index=7, number=2, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='summary', full_name='osv.Vulnerability.summary', index=7, + name='summary', full_name='osv.Vulnerability.summary', index=8, number=3, type=9, cpp_type=9, label=1, has_default_value=False, default_value=b"".decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='details', full_name='osv.Vulnerability.details', index=8, + name='details', full_name='osv.Vulnerability.details', index=9, number=4, type=9, cpp_type=9, label=1, has_default_value=False, default_value=b"".decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='affects', full_name='osv.Vulnerability.affects', index=9, - number=6, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='affected', full_name='osv.Vulnerability.affected', index=10, number=17, type=11, cpp_type=10, label=3, @@ -692,23 +710,23 @@ is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='ecosystem_specific', full_name='osv.Vulnerability.ecosystem_specific', index=12, - number=14, type=11, cpp_type=10, label=1, + name='database_specific', full_name='osv.Vulnerability.database_specific', index=12, + number=15, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='database_specific', full_name='osv.Vulnerability.database_specific', index=13, - number=15, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, + name='severity', full_name='osv.Vulnerability.severity', index=13, + number=19, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='severity', full_name='osv.Vulnerability.severity', index=14, - number=5, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, + name='credits', full_name='osv.Vulnerability.credits', index=14, + number=20, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), @@ -724,15 +742,14 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1057, - serialized_end=1561, + serialized_start=1132, + serialized_end=1606, ) _COMMIT.fields_by_name['repo_type'].enum_type = _COMMIT_REPOTYPE _COMMIT_REPOTYPE.containing_type = _COMMIT _AFFECTEDRANGE.fields_by_name['type'].enum_type = _AFFECTEDRANGE_TYPE _AFFECTEDRANGE_TYPE.containing_type = _AFFECTEDRANGE -_AFFECTS.fields_by_name['ranges'].message_type = _AFFECTEDRANGE _RANGE.fields_by_name['type'].enum_type = _RANGE_TYPE _RANGE.fields_by_name['events'].message_type = _EVENT _RANGE_TYPE.containing_type = _RANGE @@ -740,28 +757,29 @@ _AFFECTED.fields_by_name['ranges'].message_type = _RANGE _AFFECTED.fields_by_name['ecosystem_specific'].message_type = google_dot_protobuf_dot_struct__pb2._STRUCT _AFFECTED.fields_by_name['database_specific'].message_type = google_dot_protobuf_dot_struct__pb2._STRUCT +_SEVERITY.fields_by_name['type'].enum_type = _SEVERITY_TYPE +_SEVERITY_TYPE.containing_type = _SEVERITY _REFERENCE.fields_by_name['type'].enum_type = _REFERENCE_TYPE _REFERENCE_TYPE.containing_type = _REFERENCE _VULNERABILITY.fields_by_name['published'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP _VULNERABILITY.fields_by_name['modified'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP _VULNERABILITY.fields_by_name['withdrawn'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP _VULNERABILITY.fields_by_name['package'].message_type = _PACKAGE -_VULNERABILITY.fields_by_name['affects'].message_type = _AFFECTS _VULNERABILITY.fields_by_name['affected'].message_type = _AFFECTED _VULNERABILITY.fields_by_name['references'].message_type = _REFERENCE -_VULNERABILITY.fields_by_name['ecosystem_specific'].message_type = google_dot_protobuf_dot_struct__pb2._STRUCT _VULNERABILITY.fields_by_name['database_specific'].message_type = google_dot_protobuf_dot_struct__pb2._STRUCT -_VULNERABILITY.fields_by_name['severity'].enum_type = _SEVERITY +_VULNERABILITY.fields_by_name['severity'].message_type = _SEVERITY +_VULNERABILITY.fields_by_name['credits'].message_type = _CREDIT DESCRIPTOR.message_types_by_name['Commit'] = _COMMIT DESCRIPTOR.message_types_by_name['Package'] = _PACKAGE DESCRIPTOR.message_types_by_name['AffectedRange'] = _AFFECTEDRANGE -DESCRIPTOR.message_types_by_name['Affects'] = _AFFECTS DESCRIPTOR.message_types_by_name['Event'] = _EVENT DESCRIPTOR.message_types_by_name['Range'] = _RANGE DESCRIPTOR.message_types_by_name['Affected'] = _AFFECTED +DESCRIPTOR.message_types_by_name['Severity'] = _SEVERITY +DESCRIPTOR.message_types_by_name['Credit'] = _CREDIT DESCRIPTOR.message_types_by_name['Reference'] = _REFERENCE DESCRIPTOR.message_types_by_name['Vulnerability'] = _VULNERABILITY -DESCRIPTOR.enum_types_by_name['Severity'] = _SEVERITY _sym_db.RegisterFileDescriptor(DESCRIPTOR) Commit = _reflection.GeneratedProtocolMessageType('Commit', (_message.Message,), { @@ -785,13 +803,6 @@ }) _sym_db.RegisterMessage(AffectedRange) -Affects = _reflection.GeneratedProtocolMessageType('Affects', (_message.Message,), { - 'DESCRIPTOR' : _AFFECTS, - '__module__' : 'osv.vulnerability_pb2' - # @@protoc_insertion_point(class_scope:osv.Affects) - }) -_sym_db.RegisterMessage(Affects) - Event = _reflection.GeneratedProtocolMessageType('Event', (_message.Message,), { 'DESCRIPTOR' : _EVENT, '__module__' : 'osv.vulnerability_pb2' @@ -813,6 +824,20 @@ }) _sym_db.RegisterMessage(Affected) +Severity = _reflection.GeneratedProtocolMessageType('Severity', (_message.Message,), { + 'DESCRIPTOR' : _SEVERITY, + '__module__' : 'osv.vulnerability_pb2' + # @@protoc_insertion_point(class_scope:osv.Severity) + }) +_sym_db.RegisterMessage(Severity) + +Credit = _reflection.GeneratedProtocolMessageType('Credit', (_message.Message,), { + 'DESCRIPTOR' : _CREDIT, + '__module__' : 'osv.vulnerability_pb2' + # @@protoc_insertion_point(class_scope:osv.Credit) + }) +_sym_db.RegisterMessage(Credit) + Reference = _reflection.GeneratedProtocolMessageType('Reference', (_message.Message,), { 'DESCRIPTOR' : _REFERENCE, '__module__' : 'osv.vulnerability_pb2'