Skip to content

Commit 38ec05f

Browse files
committed
add elixir security importer and test
Signed-off-by: Tushar912 <tushar.912u@gmail.com> add elixir security to init.py Signed-off-by: Tushar912 <tushar.912u@gmail.com> add test for elixir security Signed-off-by: Tushar912 <tushar.912u@gmail.com> fixed code style Signed-off-by: Tushar912 <tushar.912u@gmail.com>
1 parent 7f8ae63 commit 38ec05f

5 files changed

Lines changed: 235 additions & 0 deletions

File tree

vulnerabilities/importer_yielder.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,15 @@
226226
'data_source': 'PostgreSQLDataSource',
227227
'data_source_cfg': {},
228228
},
229+
{
230+
'name': 'elixir_security',
231+
'license': '',
232+
'last_run': None,
233+
'data_source': 'ElixirSecurityDataSource',
234+
'data_source_cfg': {
235+
'repository_url': 'https://github.com/dependabot/elixir-security-advisories'
236+
},
237+
},
229238

230239
]
231240

vulnerabilities/importers/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,4 @@
4343
from vulnerabilities.importers.kaybee import KaybeeDataSource
4444
from vulnerabilities.importers.nginx import NginxDataSource
4545
from vulnerabilities.importers.postgresql import PostgreSQLDataSource
46+
from vulnerabilities.importers.elixir_security import ElixirSecurityDataSource
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# Copyright (c) 2017 nexB Inc. and others. All rights reserved.
2+
# http://nexb.com and https://github.com/nexB/vulnerablecode/
3+
# The VulnerableCode software is licensed under the Apache License version 2.0.
4+
# Data generated with VulnerableCode require an acknowledgment.
5+
#
6+
# You may not use this software except in compliance with the License.
7+
# You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0
8+
# Unless required by applicable law or agreed to in writing, software distributed
9+
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
10+
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
11+
# specific language governing permissions and limitations under the License.
12+
#
13+
# When you publish or redistribute any data created with VulnerableCode or any VulnerableCode
14+
# derivative work, you must accompany this data with the following acknowledgment:
15+
#
16+
# Generated with VulnerableCode and provided on an "AS IS" BASIS, WITHOUT WARRANTIES
17+
# OR CONDITIONS OF ANY KIND, either express or implied. No content created from
18+
# VulnerableCode should be considered or used as legal advice. Consult an Attorney
19+
# for any legal advice.
20+
# VulnerableCode is a free software code scanning tool from nexB Inc. and others.
21+
# Visit https://github.com/nexB/vulnerablecode/ for support and download.
22+
23+
import yaml
24+
import re
25+
import json
26+
import requests
27+
from typing import Set
28+
from typing import List
29+
30+
from packageurl import PackageURL
31+
32+
from vulnerabilities.data_source import GitDataSource
33+
from vulnerabilities.data_source import GitDataSourceConfiguration
34+
from vulnerabilities.data_source import Advisory
35+
from vulnerabilities.data_source import Reference
36+
37+
38+
class ElixirSecurityDataSource(GitDataSource):
39+
def __enter__(self):
40+
super(ElixirSecurityDataSource, self).__enter__()
41+
42+
if not getattr(self, "_added_files", None):
43+
self._added_files, self._updated_files = self.file_changes(
44+
recursive=True, file_ext="yml", subdir="./packages"
45+
)
46+
47+
def updated_advisories(self) -> Set[Advisory]:
48+
files = self._updated_files
49+
advisories = []
50+
for f in files:
51+
processed_data = self.process_file(f)
52+
if processed_data:
53+
advisories.append(processed_data)
54+
return self.batch_advisories(advisories)
55+
56+
def added_advisories(self) -> Set[Advisory]:
57+
files = self._added_files
58+
advisories = []
59+
for f in files:
60+
processed_data = self.process_file(f)
61+
if processed_data:
62+
advisories.append(processed_data)
63+
return self.batch_advisories(advisories)
64+
65+
@staticmethod
66+
def generate_all_versions_list(pkg_name):
67+
resp = requests.get(f"https://hex.pm/api/packages/{pkg_name}")
68+
resp = resp.content
69+
json_resp = json.loads(resp)
70+
versions_list = []
71+
for release in json_resp["releases"]:
72+
versions_list.append(release["version"])
73+
return versions_list
74+
75+
def get_pkg_from_range(self, versions_list, pkg_name):
76+
pkg_versions = []
77+
all_versions_list = self.generate_all_versions_list(pkg_name)
78+
if versions_list is None:
79+
return
80+
for version in versions_list:
81+
if re.match("^>=", version):
82+
index = all_versions_list.index(version[3:])
83+
pkg_versions = pkg_versions + all_versions_list[0: index + 1]
84+
elif re.match("^>", version):
85+
index = all_versions_list.index(version[2:])
86+
pkg_versions = pkg_versions + all_versions_list[0:index]
87+
elif re.match("^<", version):
88+
index = all_versions_list.index(version[2:])
89+
pkg_versions = pkg_versions + all_versions_list[index + 1: -1]
90+
else:
91+
pkg_versions.append(version[3:])
92+
return pkg_versions
93+
94+
def process_file(self, path):
95+
with open(path) as f:
96+
yaml_file = yaml.safe_load(f)
97+
pkg_name = yaml_file["package"]
98+
safe_pkg_versions = []
99+
if yaml_file.get("unaffected_versions"):
100+
safe_pkg_versions = self.get_pkg_from_range(
101+
yaml_file["patched_versions"] + yaml_file["unaffected_versions"],
102+
pkg_name,
103+
)
104+
else:
105+
safe_pkg_versions = self.get_pkg_from_range(
106+
yaml_file["patched_versions"], pkg_name
107+
)
108+
cve_id = yaml_file["cve"]
109+
safe_purls = []
110+
if safe_pkg_versions is not None:
111+
safe_purls = {
112+
PackageURL(name=pkg_name, type="hex", version=version)
113+
for version in safe_pkg_versions
114+
}
115+
116+
vuln_reference = [
117+
Reference(
118+
url=yaml_file["link"],
119+
)
120+
]
121+
122+
return Advisory(
123+
summary=yaml_file["description"],
124+
impacted_package_urls=[],
125+
resolved_package_urls=safe_purls,
126+
cve_id=cve_id,
127+
vuln_references=vuln_reference,
128+
)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
id: 2aae6e3a-24a3-4d5f-86ff-b964eaf7c6d1
3+
package: coherence
4+
disclosure_date: 2017-08-02
5+
cve: 2018-20301
6+
link: https://github.com/smpallen99/coherence/issues/270
7+
title: |
8+
Permissive parameters and privilege escalation
9+
description: |
10+
The Coherence library has "Mass Assignment"-like vulnerabilities.
11+
patched_versions:
12+
- ">= 0.5.2"
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Copyright (c) 2017 nexB Inc. and others. All rights reserved.
2+
# http://nexb.com and https://github.com/nexB/vulnerablecode/
3+
# The VulnerableCode software is licensed under the Apache License version 2.0.
4+
# Data generated with VulnerableCode require an acknowledgment.
5+
#
6+
# You may not use this software except in compliance with the License.
7+
# You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0
8+
# Unless required by applicable law or agreed to in writing, software distributed
9+
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
10+
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
11+
# specific language governing permissions and limitations under the License.
12+
#
13+
# When you publish or redistribute any data created with VulnerableCode or any VulnerableCode
14+
# derivative work, you must accompany this data with the following acknowledgment:
15+
#
16+
# Generated with VulnerableCode and provided on an "AS IS" BASIS, WITHOUT WARRANTIES
17+
# OR CONDITIONS OF ANY KIND, either express or implied. No content created from
18+
# VulnerableCode should be considered or used as legal advice. Consult an Attorney
19+
# for any legal advice.
20+
# VulnerableCode is a free software code scanning tool from nexB Inc. and others.
21+
# Visit https://github.com/nexB/vulnerablecode/ for support and download.
22+
23+
import os
24+
from unittest import TestCase
25+
from collections import OrderedDict
26+
27+
from vulnerabilities.data_source import Reference
28+
from packageurl import PackageURL
29+
30+
from vulnerabilities.importers.elixir_security import ElixirSecurityDataSource
31+
from vulnerabilities.data_source import Advisory
32+
33+
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
34+
35+
36+
class TestElixirSecurityDataSource(TestCase):
37+
@classmethod
38+
def setUpClass(cls):
39+
data_source_cfg = {
40+
"repository_url": "https://test.net",
41+
}
42+
cls.data_src = ElixirSecurityDataSource(1, config=data_source_cfg)
43+
44+
def test_generate_all_versions_list(self):
45+
package = "coherence"
46+
actual_list = self.data_src.generate_all_versions_list(package)
47+
expected_list = [
48+
"0.5.2",
49+
"0.5.1",
50+
"0.5.0",
51+
"0.4.0",
52+
"0.3.1",
53+
"0.3.0",
54+
"0.2.0",
55+
"0.1.3",
56+
"0.1.2",
57+
"0.1.1",
58+
"0.1.0",
59+
]
60+
assert actual_list == expected_list
61+
62+
def test_process_file(self):
63+
64+
path = os.path.join(BASE_DIR, "test_data/elixir_security/test_file.yml")
65+
expected_data = Advisory(
66+
summary=(
67+
'The Coherence library has "Mass Assignment"-like vulnerabilities.\n'
68+
),
69+
impacted_package_urls=[],
70+
resolved_package_urls={
71+
PackageURL(
72+
type="hex",
73+
name="coherence",
74+
version="0.5.2",
75+
),
76+
},
77+
vuln_references=[
78+
Reference(url="https://github.com/smpallen99/coherence/issues/270")
79+
],
80+
cve_id="2018-20301",
81+
)
82+
83+
found_data = self.data_src.process_file(path)
84+
85+
assert expected_data == found_data

0 commit comments

Comments
 (0)