From 4eb29ea8886fb0782ae2c515004b2e5226f5b9a4 Mon Sep 17 00:00:00 2001 From: Shivam Sandbhor Date: Sun, 7 Jun 2020 10:50:06 +0530 Subject: [PATCH] Add RetireDotnetDataSource, and its tests Signed-off-by: Shivam Sandbhor --- vulnerabilities/importers/__init__.py | 1 + vulnerabilities/importers/retiredotnet.py | 98 ++++++++++++++ .../migrations/0010_retiredotnet_importer.py | 55 ++++++++ .../test_data/retiredotnet/test_file.json | 37 ++++++ vulnerabilities/tests/test_retiredotnet.py | 123 ++++++++++++++++++ 5 files changed, 314 insertions(+) create mode 100644 vulnerabilities/importers/retiredotnet.py create mode 100644 vulnerabilities/migrations/0010_retiredotnet_importer.py create mode 100644 vulnerabilities/tests/test_data/retiredotnet/test_file.json create mode 100644 vulnerabilities/tests/test_retiredotnet.py diff --git a/vulnerabilities/importers/__init__.py b/vulnerabilities/importers/__init__.py index a6a6cce08..8c1b45a8e 100644 --- a/vulnerabilities/importers/__init__.py +++ b/vulnerabilities/importers/__init__.py @@ -29,3 +29,4 @@ from vulnerabilities.importers.safety_db import SafetyDbDataSource from vulnerabilities.importers.ruby import RubyDataSource from vulnerabilities.importers.ubuntu import UbuntuDataSource +from vulnerabilities.importers.retiredotnet import RetireDotnetDataSource diff --git a/vulnerabilities/importers/retiredotnet.py b/vulnerabilities/importers/retiredotnet.py new file mode 100644 index 000000000..a01e1a0a5 --- /dev/null +++ b/vulnerabilities/importers/retiredotnet.py @@ -0,0 +1,98 @@ +# Copyright (c) 2017 nexB Inc. and others. All rights reserved. +# http://nexb.com and https://github.com/nexB/vulnerablecode/ +# The VulnerableCode software is licensed under the Apache License version 2.0. +# Data generated with VulnerableCode require an acknowledgment. +# +# You may not use this software except in compliance with the License. +# You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# +# When you publish or redistribute any data created with VulnerableCode or any VulnerableCode +# derivative work, you must accompany this data with the following acknowledgment: +# +# Generated with VulnerableCode and provided on an "AS IS" BASIS, WITHOUT WARRANTIES +# OR CONDITIONS OF ANY KIND, either express or implied. No content created from +# VulnerableCode should be considered or used as legal advice. Consult an Attorney +# for any legal advice. +# VulnerableCode is a free software code scanning tool from nexB Inc. and others. +# Visit https://github.com/nexB/vulnerablecode/ for support and download. + +import json +import re +from typing import Set +from typing import List + +from packageurl import PackageURL + +from vulnerabilities.data_source import GitDataSource +from vulnerabilities.data_source import GitDataSourceConfiguration +from vulnerabilities.data_source import Advisory + + +class RetireDotnetDataSource(GitDataSource): + + def __enter__(self): + super(RetireDotnetDataSource, self).__enter__() + + if not getattr(self, '_added_files', None): + self._added_files, self._updated_files = self.file_changes( + recursive=True, file_ext='json', subdir='./Content') + + def updated_advisories(self) -> Set[Advisory]: + files = self._updated_files + advisories = [] + for f in files: + processed_data = self.process_file(f) + if processed_data: + advisories.append(processed_data) + return self.batch_advisories(advisories) + + def added_advisories(self) -> Set[Advisory]: + files = self._added_files + advisories = [] + for f in files: + processed_data = self.process_file(f) + if processed_data: + advisories.append(processed_data) + return self.batch_advisories(advisories) + + @staticmethod + def vuln_id_from_desc(desc): + cve_regex = re.compile(r"CVE-\d+-\d+") + res = cve_regex.search(desc) + if res: + return desc[res.start():res.end()] + else: + return None + + def process_file(self, path) -> List[Advisory]: + with open(path) as f: + json_doc = json.load(f) + if self.vuln_id_from_desc(json_doc["description"]): + vuln_id = self.vuln_id_from_desc(json_doc["description"]) + else: + return + + affected_purls = set() + fixed_purls = set() + + for pkg in json_doc['packages']: + affected_purls.add(PackageURL( + name=pkg['id'], + version=pkg['affected'], + type='nuget')) + + fixed_purls.add(PackageURL( + name=pkg['id'], + version=pkg['fix'], + type='nuget')) + + return Advisory( + summary=json_doc['description'], + impacted_package_urls=affected_purls, + resolved_package_urls=fixed_purls, + reference_urls=[json_doc['link']], + cve_id=vuln_id) diff --git a/vulnerabilities/migrations/0010_retiredotnet_importer.py b/vulnerabilities/migrations/0010_retiredotnet_importer.py new file mode 100644 index 000000000..5c7b7ecb2 --- /dev/null +++ b/vulnerabilities/migrations/0010_retiredotnet_importer.py @@ -0,0 +1,55 @@ +# Copyright (c) 2017 nexB Inc. and others. All rights reserved. +# http://nexb.com and https://github.com/nexB/vulnerablecode/ +# The VulnerableCode software is licensed under the Apache License version 2.0. +# Data generated with VulnerableCode require an acknowledgment. +# +# You may not use this software except in compliance with the License. +# You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# +# When you publish or redistribute any data created with VulnerableCode or any VulnerableCode +# derivative work, you must accompany this data with the following acknowledgment: +# +# Generated with VulnerableCode and provided on an "AS IS" BASIS, WITHOUT WARRANTIES +# OR CONDITIONS OF ANY KIND, either express or implied. No content created from +# VulnerableCode should be considered or used as legal advice. Consult an Attorney +# for any legal advice. +# VulnerableCode is a free software code scanning tool from nexB Inc. and others. +# Visit https://github.com/nexB/vulnerablecode/ for support and download. + +from django.db import migrations + + +def add_retiredotnet_importer(apps, _): + Importer = apps.get_model('vulnerabilities', 'Importer') + + Importer.objects.create( + name='retiredotnet', + license='MIT', + last_run=None, + data_source='RetireDotnetDataSource', + data_source_cfg={ + 'repository_url': 'https://github.com/RetireNet/Packages.git', + }, + ) + + +def remove_retiredotnet_importer(apps, _): + Importer = apps.get_model('vulnerabilities', 'Importer') + qs = Importer.objects.filter(name='RetireDotnet') + if qs: + qs[0].delete() + + +class Migration(migrations.Migration): + + dependencies = [ + ('vulnerabilities', '0009_ubuntu_importer'), + ] + + operations = [ + migrations.RunPython(add_retiredotnet_importer, remove_retiredotnet_importer), + ] diff --git a/vulnerabilities/tests/test_data/retiredotnet/test_file.json b/vulnerabilities/tests/test_data/retiredotnet/test_file.json new file mode 100644 index 000000000..7bdab96ea --- /dev/null +++ b/vulnerabilities/tests/test_data/retiredotnet/test_file.json @@ -0,0 +1,37 @@ +{ + "link": "https://github.com/aspnet/Announcements/issues/359", + "description": "Microsoft Security Advisory CVE-2019-0982: ASP.NET Core Denial of Service Vulnerability", + "packages": [ + { + "id": "Microsoft.AspNetCore.SignalR.Protocols.MessagePack", + "affected": "1.0.0", + "fix": "1.0.11" + }, + { + "id": "Microsoft.AspNetCore.SignalR.Protocols.MessagePack", + "affected": "1.0.1", + "fix": "1.0.11" + }, + { + "id": "Microsoft.AspNetCore.SignalR.Protocols.MessagePack", + "affected": "1.0.2", + "fix": "1.0.11" + }, + { + "id": "Microsoft.AspNetCore.SignalR.Protocols.MessagePack", + "affected": "1.0.3", + "fix": "1.0.11" + }, + { + "id": "Microsoft.AspNetCore.SignalR.Protocols.MessagePack", + "affected": "1.0.4", + "fix": "1.0.11" + }, + + { + "id": "Microsoft.AspNetCore.SignalR.Protocols.MessagePack", + "affected": "1.1.0", + "fix": "1.1.5" + } + ] +} \ No newline at end of file diff --git a/vulnerabilities/tests/test_retiredotnet.py b/vulnerabilities/tests/test_retiredotnet.py new file mode 100644 index 000000000..9ea38e297 --- /dev/null +++ b/vulnerabilities/tests/test_retiredotnet.py @@ -0,0 +1,123 @@ +# Copyright (c) 2017 nexB Inc. and others. All rights reserved. +# http://nexb.com and https://github.com/nexB/vulnerablecode/ +# The VulnerableCode software is licensed under the Apache License version 2.0. +# Data generated with VulnerableCode require an acknowledgment. +# +# You may not use this software except in compliance with the License. +# You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# +# When you publish or redistribute any data created with VulnerableCode or any VulnerableCode +# derivative work, you must accompany this data with the following acknowledgment: +# +# Generated with VulnerableCode and provided on an "AS IS" BASIS, WITHOUT WARRANTIES +# OR CONDITIONS OF ANY KIND, either express or implied. No content created from +# VulnerableCode should be considered or used as legal advice. Consult an Attorney +# for any legal advice. +# VulnerableCode is a free software code scanning tool from nexB Inc. and others. +# Visit https://github.com/nexB/vulnerablecode/ for support and download. + +import os +from unittest import TestCase +from collections import OrderedDict + +from packageurl import PackageURL + +from vulnerabilities.importers.retiredotnet import RetireDotnetDataSource +from vulnerabilities.data_source import Advisory + +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) + + +class TestRetireDotnetDataSource(TestCase): + + @classmethod + def setUpClass(cls): + data_source_cfg = { + 'repository_url': 'https://test.net', } + cls.data_src = RetireDotnetDataSource(1, config=data_source_cfg) + + def test_vuln_id_from_desc(self): + + gibberish = "xyzabcpqr123" * 50 + "\n" * 100 + res = self.data_src.vuln_id_from_desc(gibberish) + assert res is None + + desc = "abcdef CVE-2002-1968 pqrstuvwxyz:_|-|" + res = self.data_src.vuln_id_from_desc(desc) + assert res == "CVE-2002-1968" + + def test_process_file(self): + + path = os.path.join(BASE_DIR, "test_data/retiredotnet/test_file.json") + expected_data = Advisory( + summary=('Microsoft Security Advisory CVE-2019-0982: ' + 'ASP.NET Core Denial of Service Vulnerability'), + impacted_package_urls={ + PackageURL( + type='nuget', + namespace=None, + name='Microsoft.AspNetCore.SignalR.Protocols.MessagePack', + version='1.0.4', + qualifiers=OrderedDict(), + subpath=None), + PackageURL( + type='nuget', + namespace=None, + name='Microsoft.AspNetCore.SignalR.Protocols.MessagePack', + version='1.0.0', + qualifiers=OrderedDict(), + subpath=None), + PackageURL( + type='nuget', + namespace=None, + name='Microsoft.AspNetCore.SignalR.Protocols.MessagePack', + version='1.0.2', + qualifiers=OrderedDict(), + subpath=None), + PackageURL( + type='nuget', + namespace=None, + name='Microsoft.AspNetCore.SignalR.Protocols.MessagePack', + version='1.0.3', + qualifiers=OrderedDict(), + subpath=None), + PackageURL( + type='nuget', + namespace=None, + name='Microsoft.AspNetCore.SignalR.Protocols.MessagePack', + version='1.1.0', + qualifiers=OrderedDict(), + subpath=None), + PackageURL( + type='nuget', + namespace=None, + name='Microsoft.AspNetCore.SignalR.Protocols.MessagePack', + version='1.0.1', + qualifiers=OrderedDict(), + subpath=None)}, + resolved_package_urls={ + PackageURL( + type='nuget', + namespace=None, + name='Microsoft.AspNetCore.SignalR.Protocols.MessagePack', + version='1.0.11', + qualifiers=OrderedDict(), + subpath=None), + PackageURL( + type='nuget', + namespace=None, + name='Microsoft.AspNetCore.SignalR.Protocols.MessagePack', + version='1.1.5', + qualifiers=OrderedDict(), + subpath=None)}, + reference_urls=['https://github.com/aspnet/Announcements/issues/359'], + reference_ids=[], + cve_id='CVE-2019-0982') + + found_data = self.data_src.process_file(path) + + assert expected_data == found_data