36
36
from vulnerabilities .data_source import DataSource
37
37
from vulnerabilities .data_source import DataSourceConfiguration
38
38
from vulnerabilities .data_source import Reference
39
+ from vulnerabilities .data_inference import Inference
40
+ from vulnerabilities .data_inference import Improver
39
41
from vulnerabilities .package_managers import GitHubTagsAPI
40
42
from vulnerabilities .package_managers import Version
41
43
from vulnerabilities .helpers import nearest_patched_package
42
-
44
+ from vulnerabilities . models import Advisory
43
45
44
46
@dataclasses .dataclass
45
47
class NginxDataSourceConfiguration (DataSourceConfiguration ):
@@ -51,21 +53,6 @@ class NginxDataSource(DataSource):
51
53
52
54
url = "http://nginx.org/en/security_advisories.html"
53
55
54
- def set_api (self ):
55
- self .version_api = GitHubTagsAPI ()
56
- asyncio .run (self .version_api .load_api (["nginx/nginx" ]))
57
-
58
- # For some reason nginx tags it's releases are in the form of `release-1.2.3`
59
- # Chop off the `release-` part here.
60
- normalized_versions = set ()
61
- while self .version_api .cache ["nginx/nginx" ]:
62
- version = self .version_api .cache ["nginx/nginx" ].pop ()
63
- normalized_version = Version (
64
- version .value .replace ("release-" , "" ), version .release_date
65
- )
66
- normalized_versions .add (normalized_version )
67
- self .version_api .cache ["nginx/nginx" ] = normalized_versions
68
-
69
56
def advisory_data (self ) -> List [AdvisoryData ]:
70
57
adv_data = []
71
58
# self.set_api()
@@ -170,7 +157,9 @@ def extract_vuln_pkgs(self, vuln_info):
170
157
if "-" not in version_info :
171
158
# These are discrete versions
172
159
version_ranges .append (
173
- VersionSpecifier .from_scheme_version_spec_string ("semver" , version_info [0 ])
160
+ VersionSpecifier .from_scheme_version_spec_string (
161
+ "semver" , version_info [0 ]
162
+ )
174
163
)
175
164
continue
176
165
@@ -195,6 +184,67 @@ def extract_vuln_pkgs(self, vuln_info):
195
184
]
196
185
197
186
187
+ class NginxTimeTravel (Improver ):
188
+ def infer (self ):
189
+ self .set_api ()
190
+ advisories = Advisory .objects .filter (
191
+ source = "vulnerabilities.importers.nginx.NginxDataSource"
192
+ )
193
+ inferences = []
194
+ for advisory in advisories :
195
+ advisory_data = AdvisoryData .from_json (advisory .data )
196
+
197
+ affected_package_ranges = [
198
+ pkg .version_specifier for pkg in advisory_data .affected_packages
199
+ ]
200
+ affected_package_versions = find_valid_versions (
201
+ self .version_api .get ("nginx/nginx" ).valid_versions ,
202
+ affected_package_ranges ,
203
+ )
204
+ affected_packages = []
205
+ for pkg in advisory_data .affected_packages :
206
+ for
207
+ affected_packages .extend ([])
208
+ affected_packages = [advisory_data .affected_packages ]
209
+
210
+ fixed_package_ranges = [
211
+ pkg .version_specifier for pkg in advisory_data .affected_packages
212
+ ]
213
+ fixed_packages = find_valid_versions (
214
+ self .version_api .get ("nginx/nginx" ).valid_versions , fixed_package_ranges
215
+ )
216
+
217
+ pkgs = nearest_patched_package (affected_package_versions , fixed_package_ranges )
218
+ for pkg in pkgs :
219
+ print (pkg )
220
+ print (type (pkg ))
221
+ inferences .append (
222
+ Inference (
223
+ confidence = 90 , # TODO: Decide properly
224
+ vulnerability_id = advisory_data .vulnerability_id ,
225
+ affected_packages = pkg [0 ],
226
+ fixed_packages = pkg [1 ],
227
+ )
228
+ )
229
+
230
+ return inferences
231
+
232
+ def set_api (self ):
233
+ self .version_api = GitHubTagsAPI ()
234
+ asyncio .run (self .version_api .load_api (["nginx/nginx" ]))
235
+
236
+ # For some reason nginx tags it's releases are in the form of `release-1.2.3`
237
+ # Chop off the `release-` part here.
238
+ normalized_versions = set ()
239
+ while self .version_api .cache ["nginx/nginx" ]:
240
+ version = self .version_api .cache ["nginx/nginx" ].pop ()
241
+ normalized_version = Version (
242
+ version .value .replace ("release-" , "" ), version .release_date
243
+ )
244
+ normalized_versions .add (normalized_version )
245
+ self .version_api .cache ["nginx/nginx" ] = normalized_versions
246
+
247
+
198
248
def find_valid_versions (versions , version_ranges ):
199
249
valid_versions = set ()
200
250
for version in versions :
0 commit comments