2020# VulnerableCode is a free software code scanning tool from nexB Inc. and others.
2121# Visit https://github.com/nexB/vulnerablecode/ for support and download.
2222
23+ import asyncio
2324import yaml
24- import re
2525import json
2626import requests
27+ import re
2728from typing import Set
2829from typing import List
30+
2931from dephell_specifier import RangeSpecifier
3032from packageurl import PackageURL
3133
3234from vulnerabilities .data_source import GitDataSource
3335from vulnerabilities .data_source import GitDataSourceConfiguration
3436from vulnerabilities .data_source import Advisory
3537from vulnerabilities .data_source import Reference
36-
38+ from vulnerabilities . package_managers import HexVersionAPI
3739
3840class ElixirSecurityDataSource (GitDataSource ):
3941 def __enter__ (self ):
@@ -43,6 +45,11 @@ def __enter__(self):
4345 self ._added_files , self ._updated_files = self .file_changes (
4446 recursive = True , file_ext = "yml" , subdir = "./packages"
4547 )
48+ self .pkg_manager_api = HexVersionAPI ()
49+ self .set_api (self .collect_packages ())
50+
51+ def set_api (self , packages ):
52+ asyncio .run (self .pkg_manager_api .load_api (packages ))
4653
4754 def updated_advisories (self ) -> Set [Advisory ]:
4855 files = self ._updated_files
@@ -62,17 +69,25 @@ def added_advisories(self) -> Set[Advisory]:
6269 advisories .append (processed_data )
6370 return self .batch_advisories (advisories )
6471
65- @staticmethod
66- def generate_all_version_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- version_list = []
71- for release in json_resp ["releases" ]:
72- version_list .append (release ["version" ])
72+ def collect_packages (self ):
73+ packages = set ()
74+ files = self ._updated_files .union (self ._added_files )
75+ for f in files :
76+ with open (f ) as file :
77+ data = yaml .safe_load (file )
78+ if data .get ("package" ):
79+ packages .add (data ["package" ])
80+
81+ return packages
82+
83+ def generate_all_version_list (self ,pkg_name ):
84+ if not getattr (self , 'pkg_manager_api' , None ):
85+ self .pkg_manager_api = HexVersionAPI ()
86+ version_list = self .pkg_manager_api .get (
87+ pkg_name )
7388 return version_list
7489
75- def get_pkg_from_range (self , version_list , pkg_name ):
90+ def get_versions_from_range (self , version_list , pkg_name ):
7691 pkg_versions = []
7792 all_version_list = self .generate_all_version_list (pkg_name )
7893 if version_list is None :
@@ -89,15 +104,16 @@ def process_file(self, path):
89104 pkg_name = yaml_file ["package" ]
90105 safe_pkg_versions = []
91106 if yaml_file .get ("unaffected_versions" ):
92- safe_pkg_versions = self .get_pkg_from_range (
107+ safe_pkg_versions = self .get_versions_from_range (
93108 yaml_file ["patched_versions" ] + yaml_file ["unaffected_versions" ],
94109 pkg_name ,
95110 )
96111 else :
97- safe_pkg_versions = self .get_pkg_from_range (
112+ safe_pkg_versions = self .get_versions_from_range (
98113 yaml_file ["patched_versions" ], pkg_name
99114 )
100- cve_id = yaml_file ["cve" ]
115+
116+ cve_id = "CVE-" + str (yaml_file ["cve" ])
101117 safe_purls = []
102118 if safe_pkg_versions is not None :
103119 safe_purls = {
@@ -107,6 +123,7 @@ def process_file(self, path):
107123
108124 vuln_reference = [
109125 Reference (
126+ reference_id = yaml_file ["id" ],
110127 url = yaml_file ["link" ],
111128 )
112129 ]
0 commit comments