def _query_ossindex(self, arguments): """Query OSS Index REST API.""" entries = {} solver = get_ecosystem_solver(self.storage.get_ecosystem( arguments['ecosystem']), with_parser=OSSIndexDependencyParser()) for package in self._query_ossindex_package(arguments['ecosystem'], arguments['name']): for vulnerability in package.get('vulnerabilities', []): for version_string in vulnerability.get('versions', []): try: affected_versions = solver.solve([ "{} {}".format(arguments['name'], version_string) ], all_versions=True) except Exception: self.log.exception("Failed to resolve %r for %s:%s", version_string, arguments['ecosystem'], arguments['name']) continue if arguments['version'] in affected_versions.get( arguments['name'], []): entry = self._filter_ossindex_fields(vulnerability) if entry.get('id'): entries[entry['id']] = entry return { 'summary': list(entries.keys()), 'status': 'success', 'details': list(entries.values()) }
def components_to_scan(self, previous_sync_timestamp, only_already_scanned): """Get EPV that were recently updated in OSS Index, so they can contain new vulnerabilities. Get components (e:p:v) that were recently (since previous_sync_timestamp) updated in OSS Index, which means that they can contain new vulnerabilities. :param previous_sync_timestamp: timestamp of previous check :param only_already_scanned: include already scanned components only :return: generator of e:p:v """ # TODO: reduce cyclomatic complexity to_scan = [] for ecosystem in ['nuget']: ecosystem_solver = get_ecosystem_solver(self.storage.get_ecosystem(ecosystem), with_parser=OSSIndexDependencyParser()) self.log.debug("Retrieving new %s vulnerabilities from OSS Index", ecosystem) ossindex_updated_packages = CVEcheckerTask.\ query_ossindex_vulnerability_fromtill(ecosystem=ecosystem, from_time=previous_sync_timestamp) for ossindex_updated_package in ossindex_updated_packages: if ecosystem == 'maven': package_name = "{g}:{n}".format(g=ossindex_updated_package['group'], n=ossindex_updated_package['name']) else: package_name = ossindex_updated_package['name'] package_affected_versions = set() for vulnerability in ossindex_updated_package.get('vulnerabilities', []): for version_string in vulnerability.get('versions', []): try: resolved_versions = ecosystem_solver.\ solve(["{} {}".format(package_name, version_string)], all_versions=True) except Exception: self.log.exception("Failed to resolve %r for %s:%s", version_string, ecosystem, package_name) continue resolved_versions = resolved_versions.get(package_name, []) if only_already_scanned: already_scanned_versions =\ [ver for ver in resolved_versions if self.storage.get_analysis_count(ecosystem, package_name, ver) > 0] package_affected_versions.update(already_scanned_versions) else: package_affected_versions.update(resolved_versions) for version in package_affected_versions: to_scan.append({ 'ecosystem': ecosystem, 'name': package_name, 'version': version }) msg = "Components to be {prefix}scanned for vulnerabilities: {components}".\ format(prefix="re-" if only_already_scanned else "", components=to_scan) self.log.info(msg) return to_scan
def test_oss_index_dependency_parser_parse(self, args, expected): """Test OSSIndexDependencyParser.parse().""" dep_parser = OSSIndexDependencyParser() assert dep_parser.parse(args) == expected