Example #1
0
    def map(self, record_json):
        if not record_json:
            return None

        # Handle a 'Vulnerability' wrapper around the specific record. If not present, assume a direct record
        if len(record_json.keys()) == 1 and record_json.get('Vulnerability'):
            vuln = record_json['Vulnerability']
        else:
            vuln = record_json

        db_rec = Vulnerability()
        db_rec.id = vuln['Name']
        db_rec.namespace_name = self.group
        db_rec.severity = vuln.get('Severity', 'Unknown')
        db_rec.link = vuln.get('Link')
        description = vuln.get("Description", "")
        if description:
            db_rec.description = vuln.get('Description', '') if len(
                vuln.get('Description', '')) < self.MAX_STR_LEN else (
                    vuln.get('Description')[:self.MAX_STR_LEN - 8] + '...')
        else:
            db_rec.description = ""
        db_rec.fixed_in = []
        db_rec.vulnerable_in = []

        db_rec.metadata_json = json.dumps(
            vuln.get('Metadata')) if 'Metadata' in vuln else None
        cvss_data = vuln.get('Metadata', {}).get('NVD', {}).get('CVSSv2')
        if cvss_data:
            db_rec.cvss2_vectors = cvss_data.get('Vectors')
            db_rec.cvss2_score = cvss_data.get('Score')

        # Process Fixes
        if 'FixedIn' in vuln:
            for f in vuln['FixedIn']:
                fix = FixedArtifact()
                fix.name = f['Name']
                fix.version = f['Version']
                fix.version_format = f['VersionFormat']
                fix.epochless_version = re.sub(r'^[0-9]*:', '', f['Version'])
                fix.vulnerability_id = db_rec.id
                fix.namespace_name = self.group

                db_rec.fixed_in.append(fix)

        if 'VulnerableIn' in vuln:
            for v in vuln['VulnerableIn']:
                v_in = VulnerableArtifact()
                v_in.name = v['Name']
                v_in.version = v['Version']
                v_in.version_format = v['VersionFormat']
                v_in.epochless_version = re.sub(r'^[0-9]*:', '', v['Version'])
                v_in.vulnerability_id = db_rec.id
                v_in.namespace_name = self.group

                db_rec.vulnerable_in.append(v_in)

        return db_rec
Example #2
0
    def map(self, record_json):
        advisory = record_json["Advisory"]

        db_rec = Vulnerability()
        db_rec.id = advisory["ghsaId"]
        db_rec.name = advisory["ghsaId"]
        db_rec.namespace_name = advisory["namespace"]
        db_rec.description = advisory["Summary"]
        db_rec.severity = advisory.get("Severity", "Unknown") or "Unknown"
        db_rec.link = advisory["url"]
        db_rec.metadata_json = advisory["Metadata"]
        references = [
            "https://nvd.nist.gov/vuln/detail/{}".format(i)
            for i in advisory["CVE"]
        ]
        db_rec.references = references

        # Set the `FixedArtifact` to an empty list so that a cascade deletion
        # gets rid of the associated fixes. If the advisory has been withdrawn,
        # this field will a string with a date.
        if advisory["withdrawn"] is not None:
            db_rec.fixed_in = []
            return db_rec

        for f in advisory["FixedIn"]:
            fix = FixedArtifact()
            fix.name = f["name"]
            # this is an unfortunate lie, 'version' has to be a range in order
            # to be processed correctly. If there is a real fix version, it
            # will be set in the `fix_metadata`.
            fix.version = f.get("range", "None")
            fix.version_format = "semver"
            fix.vulnerability_id = db_rec.id
            fix.namespace_name = f["namespace"]
            fix.vendor_no_advisory = False
            # the advisory summary is the same as db_rec.description, do we need to do this again?
            fix.fix_metadata = {"first_patched_version": f["identifier"]}

            db_rec.fixed_in.append(fix)

        return db_rec
Example #3
0
    def map(self, record_json):
        advisory = record_json['Advisory']

        db_rec = Vulnerability()
        db_rec.id = advisory['ghsaId']
        db_rec.name = advisory['ghsaId']
        db_rec.namespace_name = advisory['namespace']
        db_rec.description = advisory['Summary']
        db_rec.severity = advisory.get('Severity', 'Unknown') or 'Unknown'
        db_rec.link = advisory['url']
        db_rec.metadata_json = advisory['Metadata']
        references = [
            "https://nvd.nist.gov/vuln/detail/{}".format(i)
            for i in advisory['CVE']
        ]
        db_rec.references = references

        # Set the `FixedArtifact` to an empty list so that a cascade deletion
        # gets rid of the associated fixes. If the advisory has been withdrawn,
        # this field will a string with a date.
        if advisory['withdrawn'] is not None:
            db_rec.fixed_in = []
            return db_rec

        for f in advisory['FixedIn']:
            fix = FixedArtifact()
            fix.name = f['name']
            # this is an unfortunate lie, 'version' has to be a range in order
            # to be processed correctly. If there is a real fix version, it
            # will be set in the `fix_metadata`.
            fix.version = f.get('range', 'None')
            fix.version_format = 'semver'
            fix.vulnerability_id = db_rec.id
            fix.namespace_name = f['namespace']
            fix.vendor_no_advisory = False
            # the advisory summary is the same as db_rec.description, do we need to do this again?
            fix.fix_metadata = {'first_patched_version': f['identifier']}

            db_rec.fixed_in.append(fix)

        return db_rec
test_package.size = 1000
test_package.origin = 'upstream'
test_package.arch = 'x86_64'
test_package.image = test_image

test_cve = Vulnerability(id='CVE123', namespace_name='centos:7')
test_cve.severity = 'High'
test_cve.description = 'some test cve'
test_cve.cvss2_score = '1.0'
test_cve.metadata_json = {}
test_cve.cvss2_vectors = ''
test_cve.link = 'http://mitre.com/cve123'

test_fixedin = FixedArtifact(vulnerability_id=test_cve.id)
test_fixedin.name = 'testpackage'
test_fixedin.version = '1.1'
test_fixedin.version_format = 'rpm'
test_fixedin.epochless_version = '1.1'
test_fixedin.include_later_versions = True
test_fixedin.parent = test_cve
test_cve.fixed_in = [test_fixedin]

test_vulnin = VulnerableArtifact(vulnerability_id=test_cve.id)
test_vulnin.name = 'testpackage'
test_vulnin.version = '0.9'
test_vulnin.epochless_version = '0.9'
test_vulnin.namespace_name = 'centos:7'
test_vulnin.version_format = 'rpm'
test_vulnin.include_previous_versions = False
test_vulnin.parent = test_cve
test_cve.vulnerable_in = [test_vulnin]
Example #5
0
    def map(self, record_json):
        if not record_json:
            return None

        # Handle a 'Vulnerability' wrapper around the specific record. If not present, assume a direct record
        if len(list(
                record_json.keys())) == 1 and record_json.get("Vulnerability"):
            vuln = record_json["Vulnerability"]
        else:
            vuln = record_json

        db_rec = Vulnerability()
        db_rec.id = vuln["Name"]
        db_rec.namespace_name = self.group
        db_rec.severity = vuln.get("Severity", "Unknown")
        db_rec.link = vuln.get("Link")
        description = vuln.get("Description", "")
        if description:
            db_rec.description = (
                vuln.get("Description", "")
                if len(vuln.get("Description", "")) < self.MAX_STR_LEN else
                (vuln.get("Description")[:self.MAX_STR_LEN - 8] + "..."))
        else:
            db_rec.description = ""
        db_rec.fixed_in = []
        # db_rec.vulnerable_in = []

        # db_rec.metadata_json = json.dumps(vuln.get('Metadata')) if 'Metadata' in vuln else None
        db_rec.additional_metadata = vuln.get("Metadata", {})
        cvss_data = vuln.get("Metadata", {}).get("NVD", {}).get("CVSSv2")
        if cvss_data:
            db_rec.cvss2_vectors = cvss_data.get("Vectors")
            db_rec.cvss2_score = cvss_data.get("Score")

        # Process Fixes
        if "FixedIn" in vuln:
            for f in vuln["FixedIn"]:
                fix = FixedArtifact()
                fix.name = f["Name"]
                fix.version = f["Version"]
                fix.version_format = f["VersionFormat"]
                fix.epochless_version = re.sub(r"^[0-9]*:", "", f["Version"])
                fix.vulnerability_id = db_rec.id
                fix.namespace_name = self.group
                fix.vendor_no_advisory = f.get("VendorAdvisory",
                                               {}).get("NoAdvisory", False)
                fix.fix_metadata = ({
                    "VendorAdvisorySummary":
                    f["VendorAdvisory"]["AdvisorySummary"]
                } if f.get("VendorAdvisory", {}).get("AdvisorySummary", [])
                                    else None)

                db_rec.fixed_in.append(fix)

        #        if 'VulnerableIn' in vuln:
        #            for v in vuln['VulnerableIn']:
        #                v_in = VulnerableArtifact()
        #                v_in.name = v['Name']
        #                v_in.version = v['Version']
        #                v_in.version_format = v['VersionFormat']
        #                v_in.epochless_version = re.sub(r'^[0-9]*:', '', v['Version'])
        #                v_in.vulnerability_id = db_rec.id
        #                v_in.namespace_name = self.group
        #
        #                db_rec.vulnerable_in.append(v_in)

        return db_rec
def test_cve_updates(test_data_env):
    test_env = test_data_env
    test_env.init_feeds()

    test_user_id = 'test1'
    test_img_id = 'img1'
    test_image = Image(user_id=test_user_id, id=test_img_id, distro_name='centos', distro_version='7')
    test_image.familytree_json = [test_img_id]
    test_image.layers_json = [test_img_id]
    test_image.layer_info_json = ['somelayer_here']
    test_image.like_distro = 'centos'
    test_image.state = 'analyzed'
    test_image.digest = 'digest1'
    test_image.anchore_type = 'undefined'
    test_image.dockerfile_mode = 'Guessed'
    test_image.docker_history_json = ['line1', 'line2']
    test_image.docker_data_json = {'Config': {}, 'ContainerConfig': {}}
    test_image.dockerfile_contents = 'FROM BLAH'

    test_package = ImagePackage(image_user_id=test_user_id, image_id=test_img_id, name='testpackage', version='1.0', pkg_type='RPM')
    test_package.src_pkg = 'testpackage'
    test_package.distro_name = 'centos'
    test_package.distro_version = '7'
    test_package.like_distro = 'centos'
    test_package.license = 'apache2'
    test_package.fullversion = '1.0'
    test_package.normalized_src_pkg = '1.0'
    test_package.release = ''
    test_package.size = 1000
    test_package.origin = 'upstream'
    test_package.arch = 'x86_64'
    test_package.image = test_image

    test_cve = Vulnerability(id='CVE123', namespace_name='centos:7')
    test_cve.severity = 'High'
    test_cve.description = 'some test cve'
    test_cve.cvss2_score = '1.0'
    test_cve.metadata_json = {}
    test_cve.cvss2_vectors = ''
    test_cve.link = 'http://mitre.com/cve123'

    test_fixedin = FixedArtifact(vulnerability_id=test_cve.id)
    test_fixedin.name = 'testpackage'
    test_fixedin.version = '1.1'
    test_fixedin.version_format = 'rpm'
    test_fixedin.epochless_version = '1.1'
    test_fixedin.include_later_versions = True
    test_fixedin.parent = test_cve
    test_cve.fixed_in = [test_fixedin]

    test_vulnin = VulnerableArtifact(vulnerability_id=test_cve.id)
    test_vulnin.name = 'testpackage'
    test_vulnin.version = '0.9'
    test_vulnin.epochless_version = '0.9'
    test_vulnin.namespace_name = 'centos:7'
    test_vulnin.version_format = 'rpm'
    test_vulnin.include_previous_versions = False
    test_vulnin.parent = test_cve
    test_cve.vulnerable_in = [test_vulnin]

    db = get_session()
    try:
        db.add(test_image)
        db.add(test_package)
        db.commit()
    except sqlalchemy.exc.IntegrityError:
        db.rollback()
    except Exception:
        logger.exception('Unexpected failure')
        raise

    db = get_session()
    try:
        db.add(test_cve)
        feeds.process_updated_vulnerability(db, test_cve)
        db.commit()
    except sqlalchemy.exc.IntegrityError:
        logger.exception('Failed!')
        db.rollback()
    finally:
        db = get_session()
        i = db.query(Image).get((test_img_id, test_user_id))
        print(('Vulns: {}'.format(i.vulnerabilities())))
        db.commit()

    test_cve2 = Vulnerability(id='CVE123', namespace_name='centos:7')
    test_cve2.severity = 'Medium'
    test_cve2.description = 'some test cve'
    test_cve2.cvss2_score = '1.0'
    test_cve2.metadata_json = {}
    test_cve2.cvss2_vectors = ''
    test_cve2.link = 'http://mitre.com/cve123'
    fix2 = FixedArtifact(name='pkg2', version='1.2', epochless_version='1.2')
    fix2.namespace_name = 'centos:7'
    fix2.vulnerability_id = test_cve2.id
    test_cve2.fixed_in = [fix2]

    db = get_session()
    try:
        t2 = db.merge(test_cve2)
        db.add(t2)
        feeds.process_updated_vulnerability(db, t2)
        db.commit()
    except sqlalchemy.exc.IntegrityError:
        logger.exception('Failed!')
        db.rollback()
    finally:
        db = get_session()
        i = db.query(Image).get((test_img_id, test_user_id))
        print(('Vulns: {}'.format(i.vulnerabilities())))
        db.commit()
def test_github_advisory_fixed_in(test_data_env):
    test_env = test_data_env
    test_env.init_feeds()

    test_user_id = 'test1'
    test_img_id = 'img1'
    test_image = Image(
        user_id=test_user_id, id=test_img_id,
        distro_name='centos', distro_version='7'
    )
    test_image.familytree_json = [test_img_id]
    test_image.layers_json = [test_img_id]
    test_image.layer_info_json = ['somelayer_here']
    test_image.like_distro = 'centos'
    test_image.state = 'analyzed'
    test_image.digest = 'digest1'
    test_image.anchore_type = 'undefined'
    test_image.dockerfile_mode = 'Guessed'
    test_image.docker_history_json = ['line1', 'line2']
    test_image.docker_data_json = {'Config': {}, 'ContainerConfig': {}}
    test_image.dockerfile_contents = 'FROM BLAH'

    test_package = ImagePackage(
        image_user_id=test_user_id, image_id=test_img_id,
        name='testpackage', version='1.0', pkg_type='python'
    )
    test_package.src_pkg = 'testpackage'
    test_package.distro_name = 'centos'
    test_package.distro_version = '7'
    test_package.like_distro = 'centos'
    test_package.license = 'apache2'
    test_package.fullversion = '1.0'
    test_package.normalized_src_pkg = '1.0'
    test_package.release = ''
    test_package.size = 1000
    test_package.origin = 'upstream'
    test_package.arch = 'x86_64'
    test_package.image = test_image

    test_cve = Vulnerability(id='GHSA-rpch-cqj9-h65r', namespace_name='github:python')
    test_cve.severity = 'High'
    test_cve.description = 'some advisory ghsa'
    test_cve.link = 'http://mitre.com/cve123'

    test_fixedin = FixedArtifact(vulnerability_id=test_cve.id)
    test_fixedin.name = 'testpackage'
    test_fixedin.version = 'None'
    test_fixedin.fix_metadata = {'first_patched_version': '1.2'}
    test_fixedin.version_format = 'semver'
    test_fixedin.parent = test_cve
    test_cve.fixed_in = [test_fixedin]

    db = get_session()
    try:
        db.add(test_image)
        db.add(test_package)
        db.commit()
    except sqlalchemy.exc.IntegrityError:
        db.rollback()
    except Exception:
        logger.exception('Unexpected failure')
        raise

    db = get_session()
    # XXX This needs to be a fixture
    try:
        db.add(test_cve)
        feeds.process_updated_vulnerability(db, test_cve)
        db.commit()
    except sqlalchemy.exc.IntegrityError:
        logger.exception('Failed!')
        db.rollback()

    db = get_session()
    image_vuln = db.query(Image).get((test_img_id, test_user_id))
    # should be one vulnerability
    vulnerabilities = image_vuln.vulnerabilities()
    assert len(vulnerabilities) == 1
    img_pkg_vuln = vulnerabilities[0]
    assert img_pkg_vuln.fixed_in() == '1.2'
def test_FixedArtifact_fix_observed_at_behavior(anchore_db):
    try:
        with session_scope() as session:
            testV = Vulnerability()
            testV.id = "FA_TEST-1234"
            testV.namespace_name = "fa_testnamespace:1"
            testV.severity = "Unknown"

            # this indicates a fix available
            testFA_wfix = FixedArtifact()
            testFA_wfix.name = "fa_testpkg1"
            testFA_wfix.version = "1.0"

            testV.fixed_in.append(testFA_wfix)

            # this indicates a vulnerable package (no fix available)
            testFA_wofix = FixedArtifact()
            testFA_wofix.name = "fa_testpkg2"
            testFA_wofix.version = "None"

            testV.fixed_in.append(testFA_wofix)

            session.add(testV)

        timestamps = {}
        logger.info("TESTING: state after initial insert")
        with session_scope() as session:
            records = (
                session.query(FixedArtifact)
                .filter(FixedArtifact.vulnerability_id == "FA_TEST-1234")
                .all()
            )
            for record in records:
                p = record.name
                logger.info(
                    "FOUND: record {} - version {} - fix_observed_at - {}".format(
                        record.vulnerability_id, record.version, record.fix_observed_at
                    )
                )
                if record.version == "None" and record.fix_observed_at is not None:
                    logger.info(
                        "FAIL: record shows no fix version, but fix_observed_at set"
                    )
                    assert False
                elif (
                    record.version is not None
                    and record.version != "None"
                    and record.fix_observed_at is None
                ):
                    logger.info(
                        "FAIL: record shows fix version, but fix_observed_at is null"
                    )
                    assert False
                else:
                    logger.info(
                        "SUCCESS: record {} is correct at this phase ({} - {})".format(
                            p, record.version, record.fix_observed_at
                        )
                    )
                timestamps[record.name] = record.fix_observed_at

        logger.info("TESTING: state after update of elements unrelated to fix version")
        with session_scope() as session:
            records = (
                session.query(FixedArtifact)
                .filter(FixedArtifact.vulnerability_id == "FA_TEST-1234")
                .all()
            )
            for record in records:
                record.version_format = "testformat"
                session.add(record)

        with session_scope() as session:
            records = (
                session.query(FixedArtifact)
                .filter(FixedArtifact.vulnerability_id == "FA_TEST-1234")
                .all()
            )
            for record in records:
                p = record.name
                logger.info(
                    "FOUND: record {} - version {} - fix_observed_at - {}".format(
                        record.vulnerability_id, record.version, record.fix_observed_at
                    )
                )
                if record.version == "None" and record.fix_observed_at is not None:
                    logger.info(
                        "FAIL: record shows no fix version, but fix_observed_at set"
                    )
                    assert False
                elif (
                    record.version is not None
                    and record.version != "None"
                    and record.fix_observed_at is None
                ):
                    logger.info(
                        "FAIL: record shows fix version, but fix_observed_at is null"
                    )
                    assert False
                else:
                    logger.info(
                        "SUCCESS: record {} is correct at this phase ({} - {})".format(
                            p, record.version, record.fix_observed_at
                        )
                    )

        logger.info("TESTING: state after update of elements related to fix version")
        with session_scope() as session:
            records = (
                session.query(FixedArtifact)
                .filter(FixedArtifact.vulnerability_id == "FA_TEST-1234")
                .all()
            )
            for record in records:
                record.version = "1.0"
                session.add(record)

            record = (
                session.query(FixedArtifact)
                .filter(
                    FixedArtifact.vulnerability_id == "FA_TEST-1234",
                    FixedArtifact.name == "fa_testpkg2",
                )
                .one()
            )
            timestamps["fa_testpkg2"] = record.fix_observed_at

        with session_scope() as session:
            for p in ["fa_testpkg1", "fa_testpkg2"]:
                record = (
                    session.query(FixedArtifact)
                    .filter(
                        FixedArtifact.vulnerability_id == "FA_TEST-1234",
                        FixedArtifact.name == p,
                    )
                    .one()
                )
                if record.fix_observed_at != timestamps[p]:
                    logger.info(
                        "FAIL: {} timestamp in DB is not equal to original set ({} != {})".format(
                            p, record.fix_observed_at, timestamps[p]
                        )
                    )
                    assert False
                else:
                    logger.info(
                        "SUCCESS: record {} is correct at this phase ({} - {})".format(
                            p, record.version, record.fix_observed_at
                        )
                    )

        logger.info(
            "TESTING: state after further update of elements related to fix version"
        )
        with session_scope() as session:
            records = (
                session.query(FixedArtifact)
                .filter(FixedArtifact.vulnerability_id == "FA_TEST-1234")
                .all()
            )
            for record in records:
                record.version = "2.0"
                session.add(record)

        with session_scope() as session:
            for p in ["fa_testpkg1", "fa_testpkg2"]:
                record = (
                    session.query(FixedArtifact)
                    .filter(
                        FixedArtifact.vulnerability_id == "FA_TEST-1234",
                        FixedArtifact.name == p,
                    )
                    .one()
                )
                if record.fix_observed_at != timestamps[p]:
                    logger.info(
                        "FAIL: {} timestamp in DB is not equal to original set ({} != {})".format(
                            p, record.fix_observed_at, timestamps[p]
                        )
                    )
                    assert False
                else:
                    logger.info(
                        "SUCCESS: record {} is correct at this phase ({} - {})".format(
                            p, record.version, record.fix_observed_at
                        )
                    )

    except Exception as err:
        logger.error("FAIL: exception - {}".format(err))
        raise (err)
    finally:
        tearDown()
def test_cve_updates(test_data_env):
    test_env = test_data_env
    test_env.init_feeds()

    test_user_id = "test1"
    test_img_id = "img1"
    test_image = Image(user_id=test_user_id,
                       id=test_img_id,
                       distro_name="centos",
                       distro_version="7")
    test_image.familytree_json = [test_img_id]
    test_image.layers_json = [test_img_id]
    test_image.layer_info_json = ["somelayer_here"]
    test_image.like_distro = "centos"
    test_image.state = "analyzed"
    test_image.digest = "digest1"
    test_image.anchore_type = "undefined"
    test_image.dockerfile_mode = "Guessed"
    test_image.docker_history_json = ["line1", "line2"]
    test_image.docker_data_json = {"Config": {}, "ContainerConfig": {}}
    test_image.dockerfile_contents = "FROM BLAH"

    test_package = ImagePackage(
        image_user_id=test_user_id,
        image_id=test_img_id,
        name="testpackage",
        version="1.0",
        pkg_type="RPM",
    )
    test_package.src_pkg = "testpackage"
    test_package.distro_name = "centos"
    test_package.distro_version = "7"
    test_package.like_distro = "centos"
    test_package.license = "apache2"
    test_package.fullversion = "1.0"
    test_package.normalized_src_pkg = "1.0"
    test_package.release = ""
    test_package.size = 1000
    test_package.origin = "upstream"
    test_package.arch = "x86_64"
    test_package.image = test_image

    test_cve = Vulnerability(id="CVE123", namespace_name="centos:7")
    test_cve.severity = "High"
    test_cve.description = "some test cve"
    test_cve.cvss2_score = "1.0"
    test_cve.metadata_json = {}
    test_cve.cvss2_vectors = ""
    test_cve.link = "http://mitre.com/cve123"

    test_fixedin = FixedArtifact(vulnerability_id=test_cve.id)
    test_fixedin.name = "testpackage"
    test_fixedin.version = "1.1"
    test_fixedin.version_format = "rpm"
    test_fixedin.epochless_version = "1.1"
    test_fixedin.include_later_versions = True
    test_fixedin.parent = test_cve
    test_cve.fixed_in = [test_fixedin]

    test_vulnin = VulnerableArtifact(vulnerability_id=test_cve.id)
    test_vulnin.name = "testpackage"
    test_vulnin.version = "0.9"
    test_vulnin.epochless_version = "0.9"
    test_vulnin.namespace_name = "centos:7"
    test_vulnin.version_format = "rpm"
    test_vulnin.include_previous_versions = False
    test_vulnin.parent = test_cve
    test_cve.vulnerable_in = [test_vulnin]

    db = get_session()
    try:
        db.add(test_image)
        db.add(test_package)
        db.commit()
    except sqlalchemy.exc.IntegrityError:
        db.rollback()
    except Exception:
        logger.exception("Unexpected failure")
        raise

    db = get_session()
    try:
        db.add(test_cve)
        feeds.process_updated_vulnerability(db, test_cve)
        db.commit()
    except sqlalchemy.exc.IntegrityError:
        logger.exception("Failed!")
        db.rollback()
    finally:
        db = get_session()
        i = db.query(Image).get((test_img_id, test_user_id))
        print(("Vulns: {}".format(i.vulnerabilities())))
        db.commit()

    test_cve2 = Vulnerability(id="CVE123", namespace_name="centos:7")
    test_cve2.severity = "Medium"
    test_cve2.description = "some test cve"
    test_cve2.cvss2_score = "1.0"
    test_cve2.metadata_json = {}
    test_cve2.cvss2_vectors = ""
    test_cve2.link = "http://mitre.com/cve123"
    fix2 = FixedArtifact(name="pkg2", version="1.2", epochless_version="1.2")
    fix2.namespace_name = "centos:7"
    fix2.vulnerability_id = test_cve2.id
    test_cve2.fixed_in = [fix2]

    db = get_session()
    try:
        t2 = db.merge(test_cve2)
        db.add(t2)
        feeds.process_updated_vulnerability(db, t2)
        db.commit()
    except sqlalchemy.exc.IntegrityError:
        logger.exception("Failed!")
        db.rollback()
    finally:
        db = get_session()
        i = db.query(Image).get((test_img_id, test_user_id))
        print(("Vulns: {}".format(i.vulnerabilities())))
        db.commit()
Example #10
0
def test_github_advisory_fixed_in(test_data_env):
    test_env = test_data_env
    test_env.init_feeds()

    test_user_id = "test1"
    test_img_id = "img1"
    test_image = Image(user_id=test_user_id,
                       id=test_img_id,
                       distro_name="centos",
                       distro_version="7")
    test_image.familytree_json = [test_img_id]
    test_image.layers_json = [test_img_id]
    test_image.layer_info_json = ["somelayer_here"]
    test_image.like_distro = "centos"
    test_image.state = "analyzed"
    test_image.digest = "digest1"
    test_image.anchore_type = "undefined"
    test_image.dockerfile_mode = "Guessed"
    test_image.docker_history_json = ["line1", "line2"]
    test_image.docker_data_json = {"Config": {}, "ContainerConfig": {}}
    test_image.dockerfile_contents = "FROM BLAH"

    test_package = ImagePackage(
        image_user_id=test_user_id,
        image_id=test_img_id,
        name="testpackage",
        version="1.0",
        pkg_type="python",
    )
    test_package.src_pkg = "testpackage"
    test_package.distro_name = "centos"
    test_package.distro_version = "7"
    test_package.like_distro = "centos"
    test_package.license = "apache2"
    test_package.fullversion = "1.0"
    test_package.normalized_src_pkg = "1.0"
    test_package.release = ""
    test_package.size = 1000
    test_package.origin = "upstream"
    test_package.arch = "x86_64"
    test_package.image = test_image

    test_cve = Vulnerability(id="GHSA-rpch-cqj9-h65r",
                             namespace_name="github:python")
    test_cve.severity = "High"
    test_cve.description = "some advisory ghsa"
    test_cve.link = "http://mitre.com/cve123"

    test_fixedin = FixedArtifact(vulnerability_id=test_cve.id)
    test_fixedin.name = "testpackage"
    test_fixedin.version = "None"
    test_fixedin.fix_metadata = {"first_patched_version": "1.2"}
    test_fixedin.version_format = "semver"
    test_fixedin.parent = test_cve
    test_cve.fixed_in = [test_fixedin]

    db = get_session()
    try:
        db.add(test_image)
        db.add(test_package)
        db.commit()
    except sqlalchemy.exc.IntegrityError:
        db.rollback()
    except Exception:
        logger.exception("Unexpected failure")
        raise

    db = get_session()
    # XXX This needs to be a fixture
    try:
        db.add(test_cve)
        feeds.process_updated_vulnerability(db, test_cve)
        db.commit()
    except sqlalchemy.exc.IntegrityError:
        logger.exception("Failed!")
        db.rollback()

    db = get_session()
    image_vuln = db.query(Image).get((test_img_id, test_user_id))
    # should be one vulnerability
    vulnerabilities = image_vuln.vulnerabilities()
    assert len(vulnerabilities) == 1
    img_pkg_vuln = vulnerabilities[0]
    assert img_pkg_vuln.fixed_in() == "1.2"