Exemple #1
0
def test_basic_selector(maven_vertx_cve):
    """Test VersionSelector().pick_winner()."""
    candidates = [
        PackageNameCandidate('io.vertx:testtools', Decimal('10.0')),
        PackageNameCandidate('io.vertx:vertx-core', Decimal('5.0'))
    ]
    selector = VersionSelector(maven_vertx_cve, candidates, 'java')
    winner = selector.pick_winner()
    assert winner
    assert winner.package == 'io.vertx:vertx-core'
Exemple #2
0
def test_package_name_candidate_bad():
    """Test PackageNameCandidate() with invalid input."""
    with pytest.raises(ValueError):
        PackageNameCandidate(None, Decimal('1.0'))
    with pytest.raises(ValueError):
        PackageNameCandidate('', Decimal('1.0'))
    with pytest.raises(ValueError):
        PackageNameCandidate('package-a', None)

    # extra element ("UI") in the cpe2pkg output line
    candidate = PackageNameCandidate.from_cpe2pkg_output(
        '1.0268737 javascript:JQuery UI', 'javascript')
    assert candidate.package == 'JQuery'
Exemple #3
0
def test_basic_selector_none_versions(unsupported_cve_none_versions):
    """Test VersionSelector().pick_winner() with "None" versions."""
    candidates = [
        PackageNameCandidate('io.vertx:testtools', Decimal('10.0')),
    ]
    selector = VersionSelector(unsupported_cve_none_versions, candidates,
                               'java')
    winner = selector.pick_winner()  # don't throw TypeError here
    assert not winner
Exemple #4
0
def test_package_name_candidate():
    """Test PackageNameCandidate()."""
    c1 = PackageNameCandidate.from_cpe2pkg_output('10.0 python:package-a',
                                                  'python')

    assert c1.package == 'package-a'
    assert c1.score == Decimal('10.0')
    assert str(c1) == 'PackageNameCandidate(package-a, 10.0)'
    assert c1 == c1

    c2 = PackageNameCandidate.from_cpe2pkg_output('9.0 python:package-b',
                                                  'python')
    assert c1 > c2
    assert c2 < c1
    assert c1 != c2

    c3 = PackageNameCandidate.from_cpe2pkg_output('9.0 gid:package-c', 'java')
    assert c3.package == 'gid:package-c'
Exemple #5
0
    def _run_cpe2pkg(self, vendor, product):
        """Run cpe2pkg tool.

        :param vendor: list[str], a list of vendor strings
        :param product: list[str], a list of product strings
        :return: list[PackageNameCandidate], a list of package name candidates
        """
        query_str = build_cpe2pkg_query(vendor, product)
        output = run_cpe2pkg(query_str, self.pkgfile_path, self.cpe2pkg_path)
        return [
            PackageNameCandidate.from_cpe2pkg_output(x, self.ecosystem) for x in output if x
        ]
Exemple #6
0
def run():
    """Run CVEjob."""
    feed_dir = Config.feed_dir
    feed_names = Config.feed_names
    date_range = Config.date_range

    cherrypicked_cve_id = Config.cve_id
    cherrypicked_year = None

    if cherrypicked_cve_id:
        cherrypicked_year = cherrypicked_cve_id.split(sep='-')[1]

        if int(cherrypicked_year) < 2002:
            # all CVEs prior to 2002 are stored in 2002 feed
            cherrypicked_year = 2002

    if date_range:
        date_range = parse_date_range(Config.date_range)

        feed_names = range(date_range[0].year, date_range[1].year + 1)

        if cherrypicked_cve_id:  # optimization check

            if int(cherrypicked_year) not in feed_names:
                logger.info(
                    "[{picked_cve_id}] does not belong to the given feed range:"
                    " {date_range}".format(picked_cve_id=cherrypicked_cve_id,
                                           date_range=date_range))

                return

            # prune the feed names as it is not necessary to iterate over all of them
            feed_names = [cherrypicked_year]

    if not feed_names:

        if cherrypicked_cve_id:
            feed_names = [cherrypicked_year]
        else:
            feed_names = ['modified']

    with FeedManager(n_workers=multiprocessing.cpu_count()) as feed_manager:

        feeds = feed_manager.fetch_feeds(feed_names=feed_names,
                                         data_dir=feed_dir,
                                         update=True)
        collection = feed_manager.collect(feeds)
        collection = _filter_collection(collection, date_range,
                                        cherrypicked_cve_id)

    if not collection:  # collection is empty
        logger.info("Collection is empty.".format(
            picked_cve_id=cherrypicked_cve_id, ))

        return

    logger.debug("Number of CVE Documents in the collection: {}".format(
        collection.count()))

    if Config.package_name and Config.cve_id:
        # user knows the package name, so we don't have to guess ;)
        doc = [x for x in collection][0]  # Collection doesn't support indexing
        affected, safe = NVDVersions(doc, Config.package_name,
                                     Config.ecosystem).run()
        victims_output = VictimsYamlOutput(ecosystem=Config.ecosystem,
                                           cve_doc=doc,
                                           winner=PackageNameCandidate(
                                               Config.package_name,
                                               Decimal('1.0')),
                                           candidates=[],
                                           affected=affected,
                                           fixedin=safe)
        _log_results(victims_output)
        victims_output.write()
        sys.exit(0)

    for doc in collection:

        cve_id = doc.cve.id_

        try:

            if not validate_cve(doc):
                logger.debug(
                    "[{cve_id}] was filtered out by input checks".format(
                        cve_id=cve_id))
                continue

            pkgfile_path = get_pkgfile_path(Config.pkgfile_dir,
                                            Config.ecosystem)
            identifier = get_identifier_cls()(doc, Config.ecosystem,
                                              pkgfile_path)
            candidates = identifier.identify()

            if not candidates:
                logger.info(
                    "[{cve_id}] no package name candidates found".format(
                        cve_id=cve_id))
                continue

            selector = VersionSelector(doc, candidates, Config.ecosystem)
            winner = selector.pick_winner()

            if not winner:
                logger.info(
                    "[{cve_id}] no package name found".format(cve_id=cve_id))

                continue

            affected, safe = NVDVersions(doc, winner.package,
                                         Config.ecosystem).run()

            victims_output = VictimsYamlOutput(ecosystem=Config.ecosystem,
                                               cve_doc=doc,
                                               winner=winner,
                                               candidates=candidates,
                                               affected=affected,
                                               fixedin=safe)

            _log_results(victims_output)

            victims_output.write()

        except Exception as exc:

            logger.warning(
                "[{cve_id}] Unexpected exception occurred: {exc}".format(
                    cve_id=cve_id, exc=exc),
                exc_info=True)