-
-
Notifications
You must be signed in to change notification settings - Fork 264
Elixir Security Importer #294
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
38ec05f
add elixir security importer and test
tushar912 70ac4cd
use dephell_specifier for version ranges and sort imports
tushar912 f809a89
added HexVersionAPI and mock test it
tushar912 922e34f
fixed code style
tushar912 ee6dd62
initialize hexapi with cache and sort imports
tushar912 58a253f
Merge new changes and use load_yaml from helpers
tushar912 6e62cdf
add license and categorize left versions as vuln
tushar912 fd25df3
change name of function get_version_from range and add comments in it
tushar912 0fa1bf4
remove unused import and add name to authors and add importer to sources
tushar912 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,144 @@ | ||
| # Copyright (c) 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 tool from nexB Inc. and others. | ||
| # Visit https://github.com/nexB/vulnerablecode/ for support and download. | ||
|
|
||
| import asyncio | ||
| from typing import List, Set | ||
|
|
||
| import yaml | ||
| from dephell_specifier import RangeSpecifier | ||
| from packageurl import PackageURL | ||
|
|
||
| from vulnerabilities.data_source import GitDataSource | ||
| from vulnerabilities.data_source import Advisory | ||
| from vulnerabilities.data_source import Reference | ||
| from vulnerabilities.package_managers import HexVersionAPI | ||
| from vulnerabilities.helpers import load_yaml | ||
|
|
||
|
|
||
| class ElixirSecurityDataSource(GitDataSource): | ||
| def __enter__(self): | ||
| super(ElixirSecurityDataSource, self).__enter__() | ||
|
|
||
| if not getattr(self, "_added_files", None): | ||
| self._added_files, self._updated_files = self.file_changes( | ||
| recursive=True, file_ext="yml", subdir="./packages" | ||
| ) | ||
| self.pkg_manager_api = HexVersionAPI() | ||
| self.set_api(self.collect_packages()) | ||
|
|
||
| def set_api(self, packages): | ||
| asyncio.run(self.pkg_manager_api.load_api(packages)) | ||
|
|
||
| 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) | ||
|
|
||
| def collect_packages(self): | ||
| packages = set() | ||
| files = self._updated_files.union(self._added_files) | ||
| for f in files: | ||
| data = load_yaml(f) | ||
| if data.get("package"): | ||
| packages.add(data["package"]) | ||
|
|
||
| return packages | ||
|
|
||
| def get_versions_for_pkg_from_range_list(self, version_range_list, pkg_name): | ||
| # Takes a list of version ranges(pathced and unaffected) of a package | ||
| # as parameter and returns a tuple of safe package versions and | ||
| # vulnerable package versions | ||
|
|
||
| safe_pkg_versions = [] | ||
| vuln_pkg_versions = [] | ||
| all_version_list = self.pkg_manager_api.get(pkg_name) | ||
| if not version_range_list: | ||
| return [], all_version_list | ||
| version_ranges = {RangeSpecifier(r) for r in version_range_list} | ||
| for version in all_version_list: | ||
| if any([version in v for v in version_ranges]): | ||
| safe_pkg_versions.append(version) | ||
|
|
||
| vuln_pkg_versions = set(all_version_list) - set(safe_pkg_versions) | ||
| return safe_pkg_versions, vuln_pkg_versions | ||
|
|
||
| def process_file(self, path): | ||
| yaml_file = load_yaml(path) | ||
| pkg_name = yaml_file["package"] | ||
| safe_pkg_versions = [] | ||
| vuln_pkg_versions = [] | ||
| if not yaml_file.get("patched_versions"): | ||
| yaml_file["patched_versions"] = [] | ||
sbs2001 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| if not yaml_file.get("unaffected_versions"): | ||
| yaml_file["unaffected_versions"] = [] | ||
sbs2001 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| safe_pkg_versions, vuln_pkg_versions = self.get_versions_for_pkg_from_range_list( | ||
| yaml_file["patched_versions"] + yaml_file["unaffected_versions"], | ||
| pkg_name, | ||
| ) | ||
|
|
||
| if yaml_file.get("cve"): | ||
| cve_id = "CVE-" + yaml_file["cve"] | ||
| else: | ||
| cve_id = "" | ||
|
|
||
| safe_purls = [] | ||
| vuln_purls = [] | ||
|
|
||
| safe_purls = { | ||
| PackageURL(name=pkg_name, type="hex", version=version) for version in safe_pkg_versions | ||
| } | ||
|
|
||
| vuln_purls = { | ||
| PackageURL(name=pkg_name, type="hex", version=version) for version in vuln_pkg_versions | ||
| } | ||
|
|
||
| vuln_references = [ | ||
| Reference( | ||
| reference_id=yaml_file["id"], | ||
| ), | ||
| Reference( | ||
| url=yaml_file["link"], | ||
| ), | ||
| ] | ||
|
|
||
| return Advisory( | ||
| summary=yaml_file["description"], | ||
| impacted_package_urls=vuln_purls, | ||
| resolved_package_urls=safe_purls, | ||
| cve_id=cve_id, | ||
| vuln_references=vuln_references, | ||
| ) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -351,3 +351,24 @@ async def fetch(self, owner_repo: str, session) -> None: | |
| resp = await session.request(method="GET", url=endpoint) | ||
| resp = await resp.json() | ||
| self.cache[owner_repo] = [release["ref"].split("/")[-1] for release in resp] | ||
|
|
||
|
|
||
| class HexVersionAPI(VersionAPI): | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❤️ |
||
| async def load_api(self, pkg_set): | ||
| async with ClientSession(raise_for_status=True) as session: | ||
| await asyncio.gather( | ||
| *[self.fetch(pkg, session) for pkg in pkg_set if pkg not in self.cache] | ||
| ) | ||
|
|
||
| async def fetch(self, pkg, session): | ||
| url = f"https://hex.pm/api/packages/{pkg}" | ||
| versions = set() | ||
| try: | ||
| response = await session.request(method="GET", url=url) | ||
| response = await response.json() | ||
| for release in response["releases"]: | ||
| versions.add(release["version"]) | ||
| except (ClientResponseError, JSONDecodeError): | ||
sbs2001 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| pass | ||
|
|
||
| self.cache[pkg] = versions | ||
12 changes: 12 additions & 0 deletions
12
vulnerabilities/tests/test_data/elixir_security/test_file.yml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| --- | ||
| id: 2aae6e3a-24a3-4d5f-86ff-b964eaf7c6d1 | ||
| package: coherence | ||
| disclosure_date: 2017-08-02 | ||
| cve: 2018-20301 | ||
| link: https://github.com/smpallen99/coherence/issues/270 | ||
| title: | | ||
| Permissive parameters and privilege escalation | ||
| description: | | ||
| The Coherence library has "Mass Assignment"-like vulnerabilities. | ||
| patched_versions: | ||
| - ">= 0.5.2" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,137 @@ | ||
| # Copyright (c) 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 tool from nexB Inc. and others. | ||
| # Visit https://github.com/nexB/vulnerablecode/ for support and download. | ||
|
|
||
| import os | ||
| from collections import OrderedDict | ||
| from unittest import TestCase | ||
|
|
||
| from packageurl import PackageURL | ||
|
|
||
| from vulnerabilities.data_source import Advisory | ||
| from vulnerabilities.data_source import Reference | ||
| from vulnerabilities.importers.elixir_security import ElixirSecurityDataSource | ||
| from vulnerabilities.package_managers import HexVersionAPI | ||
|
|
||
| BASE_DIR = os.path.dirname(os.path.abspath(__file__)) | ||
|
|
||
|
|
||
| class TestElixirSecurityDataSource(TestCase): | ||
| @classmethod | ||
| def setUpClass(cls): | ||
| data_source_cfg = { | ||
| "repository_url": "https://github.com/dependabot/elixir-security-advisories", | ||
| } | ||
| cls.data_src = ElixirSecurityDataSource(1, config=data_source_cfg) | ||
| cls.data_src.pkg_manager_api = HexVersionAPI( | ||
| { | ||
| "coherence": [ | ||
| "0.5.2", | ||
| "0.5.1", | ||
| "0.5.0", | ||
| "0.4.0", | ||
| "0.3.1", | ||
| "0.3.0", | ||
| "0.2.0", | ||
| "0.1.3", | ||
| "0.1.2", | ||
| "0.1.1", | ||
| "0.1.0", | ||
| ] | ||
| } | ||
| ) | ||
|
|
||
| def test_process_file(self): | ||
|
|
||
| path = os.path.join(BASE_DIR, "test_data/elixir_security/test_file.yml") | ||
| expected_data = Advisory( | ||
| summary=('The Coherence library has "Mass Assignment"-like vulnerabilities.\n'), | ||
| impacted_package_urls={ | ||
| PackageURL( | ||
| type="hex", | ||
| name="coherence", | ||
| version="0.5.1", | ||
| ), | ||
| PackageURL( | ||
| type="hex", | ||
| name="coherence", | ||
| version="0.5.0", | ||
| ), | ||
| PackageURL( | ||
| type="hex", | ||
| name="coherence", | ||
| version="0.4.0", | ||
| ), | ||
| PackageURL( | ||
| type="hex", | ||
| name="coherence", | ||
| version="0.3.1", | ||
| ), | ||
| PackageURL( | ||
| type="hex", | ||
| name="coherence", | ||
| version="0.3.0", | ||
| ), | ||
| PackageURL( | ||
| type="hex", | ||
| name="coherence", | ||
| version="0.2.0", | ||
| ), | ||
| PackageURL( | ||
| type="hex", | ||
| name="coherence", | ||
| version="0.1.3", | ||
| ), | ||
| PackageURL( | ||
| type="hex", | ||
| name="coherence", | ||
| version="0.1.2", | ||
| ), | ||
| PackageURL( | ||
| type="hex", | ||
| name="coherence", | ||
| version="0.1.1", | ||
| ), | ||
| PackageURL( | ||
| type="hex", | ||
| name="coherence", | ||
| version="0.1.0", | ||
| ), | ||
| }, | ||
| resolved_package_urls={ | ||
| PackageURL( | ||
| type="hex", | ||
| name="coherence", | ||
| version="0.5.2", | ||
| ), | ||
| }, | ||
| vuln_references=[ | ||
| Reference( | ||
| reference_id="2aae6e3a-24a3-4d5f-86ff-b964eaf7c6d1", | ||
| ), | ||
| Reference(url="https://github.com/smpallen99/coherence/issues/270"), | ||
| ], | ||
| cve_id="CVE-2018-20301", | ||
| ) | ||
|
|
||
| found_data = self.data_src.process_file(path) | ||
|
|
||
| assert expected_data == found_data |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.