def test_bundle_failure(self): b = build_bundle(test_bundle) image_obj = Image(id='fakeid1') r = b.execute(image_object=image_obj, tag='dockerhub/library/alpine:latest', context=object()) logger.info((json.dumps((r.json()), indent=2)))
def msg_to_db(self, msg): db_obj = Image() db_obj.id = msg.id db_obj.digest = msg.digest db_obj.user_id = msg.user_id db_obj.created_at = msg.created_at db_obj.last_modified = msg.last_modified return db_obj
def test_multi_policy_missing_errors(test_data_env_with_images_loaded): """ Test entries in policy_ids that are not found in bundle :return: """ ruby_tag = "dockerhub/library/ruby:latest" with pytest.raises(InitializationError) as f: built = build_bundle({ "id": "someid", "version": "1_0", "name": "testbundle", "whitelists": [{ "id": "whitelist1", "version": "1_0", "name": "ok whitelist", "items": [], }], "policies": [ { "id": "okpolicy", "version": "1_0", "name": "ok policy", "rules": [], }, { "id": "okpolicy", "version": "1_0", "name": "ok policy", "rules": [], }, ], "mappings": [{ "id": "invalid_mapping", "policy_ids": ["okpolicy", "okpolicy2", "notrealpolicy"], "whitelist_ids": ["whitelist1"], "registry": "*", "repository": "*", "image": { "type": "tag", "value": "*" }, }], }) built.execute(image_object=Image(), context=None, tag=ruby_tag)
def test_multi_policy_missing_errors(self): """ Test entries in policy_ids that are not found in bundle :return: """ ruby_tag = 'dockerhub/library/ruby:latest' with self.assertRaises(InitializationError) as f: built = build_bundle({ 'id': 'someid', 'version': '1_0', 'name': 'testbundle', 'whitelists': [ {'id': 'whitelist1', 'version': '1_0', 'name': 'ok whitelist', 'items': [] } ], 'policies': [ { 'id': 'okpolicy', 'version': '1_0', 'name': 'ok policy', 'rules': [] }, { 'id': 'okpolicy', 'version': '1_0', 'name': 'ok policy', 'rules': [] } ], 'mappings': [ { 'id': 'invalid_mapping', 'policy_ids': ['okpolicy', 'okpolicy2', 'notrealpolicy'], 'whitelist_ids': ['whitelist1'], 'registry': '*', 'repository': '*', 'image': { 'type': 'tag', 'value': '*' } } ] }) built.execute(image_object=Image(), context=None, tag=ruby_tag)
def _match_distro_packages_by_cpe(self, image: Image) -> List[CpeMatch]: """ Returns list of tuples of (imagecpe, vulncpe) that are matches :param image: :return: list of tuples """ logger.spew( "scanning os packages for cpe matches id=%s digest=%s", image.id, image.digest, ) os_pkg_cpe_mappings = self._get_cpes_for_os_packages(image.packages) logger.spew("distro cpes: %s", os_pkg_cpe_mappings) os_cpes = [cpe for pkg, cpe in os_pkg_cpe_mappings] # Get the matches matches = self._query_cpe_matches(os_cpes) logger.spew( "pre-filter cpe distro findings: %s", [(match.image_cpe, match.vuln_cpe.vulnerability_id) for match in matches], ) # Filter the matches if configured to do so if matches and self.exclude_distro_records: # Remove any matches that are for a CVE ID that is represented in the vendor vuln db, regardless of match status. matched_cve_ids = self.get_cve_ids(matches) filtered_matched_cve_ids = set( filter_secdb_entries( image.distro_namespace_obj(), matched_cve_ids, self.db_manager ) ) matches = [ match for match in matches if match.vuln_cpe.vulnerability_id in filtered_matched_cve_ids ] logger.debug( "post-filter cpe distro findings: %s", [ (match.image_cpe.name, match.vuln_cpe.vulnerability_id) for match in matches ], ) return matches
def test_multi_policy_invalid_errors(test_data_env_with_images_loaded): """ Test validation of policies in multi-policy mapping :return: """ ruby_tag = 'dockerhub/library/ruby:latest' with pytest.raises(InitializationError) as f: built = build_bundle({ 'id': 'someid', 'version': '1_0', 'name': 'invalid_version', 'whitelists': [{ 'id': 'whitelist1', 'version': '1_0', 'name': 'ok whitelist', 'items': [] }], 'policies': [{ 'id': 'okpolicy', 'version': '1_0', 'name': 'ok policy', 'rules': [] }, { 'id': 'okpolicy', 'version': '2_0', 'name': 'ok policy', 'rules': [] }], 'mappings': [{ 'id': 'ok_mapping', 'policy_ids': ['okpolicy', 'okpolicy2'], 'whitelist_ids': ['whitelist1'], 'registry': '*', 'repository': '*', 'image': { 'type': 'tag', 'value': '*' } }] }) built.execute(image_object=Image(), context=None, tag=ruby_tag)
""" Gate Unit tests """ import pytest from anchore_engine.db import Image from anchore_engine.subsys import logger from anchore_engine.services.policy_engine.engine.policy.gates.image_metadata import ( ImageMetadataGate, ImageMetadataAttributeCheckTrigger, ) from tests.integration.services.policy_engine.engine.policy.gates import GateUnitTest logger.enable_test_logging() test_image = Image() test_image.distro_name = "debian" test_image.distro_version = "9" test_image.like_distro = "debian" test_image.user_id = "0" test_image.layers_json = ["sha256:a", "sha256:b", "sha256:c"] test_image.layer_info_json = ["layer1", "layer2"] test_image.dockerfile_contents = "FROM SCRATCH\nHEALTHcheck blah\n" test_image.dockerfile_mode = "Guessed" test_image.size = 100 * 1024 * 1024 test_image.docker_data_json = { "Comment": "", "Container": "4e69ef98747345110dc23069be98ff0ae562cc83a187ff1bdd1d2e0048889679", "DockerVersion":
""" Gate Unit tests """ from legacy_test.services.policy_engine.engine.policy.gates import GateUnitTest from anchore_engine.services.policy_engine.engine.policy.gate import ExecutionContext from anchore_engine.db import Image from anchore_engine.services.policy_engine.engine.policy.gates.dockerfile import DockerfileGate, \ ExposedPortsTrigger, \ InstructionCheckTrigger, \ EffectiveUserTrigger, \ NoDockerfile test_image = Image() test_image.distro_name = 'debian' test_image.distro_version = '9' test_image.user_id = '0' test_image.layer_info_json = ['layer1', 'layer2'] test_image.dockerfile_contents = 'FROM SCRATCH\nHEALTHCHECK blah\n' test_image.dockerfile_mode = 'Guessed' dockerfile_from = 'FROM library/centos:latest\nRUN apt-get install\nCMD echo helloworld\n' dockerfile_scratch = 'FROM SCRATCH\nRUN apt-get install\nCMD echo helloworld\n' dockerfile_healthcheck = 'FROM library/centos:latest\nRUN apt-get install\nCMD echo helloworld\nHEALTHcheck echo hello\n' dockerfile_no_healthcheck = 'FROM library/centos:latest\nRUN apt-get install\nCMD echo helloworld\n' dockerfile_no_tag = 'FROM library/centos\nRUN apt-get install\nCMD echo helloworld\n' dockerfile_no_from = 'ADD ./files/* /\nRUN apt-get install\nCMD echo helloworld\n' dockerfile_sudo = 'FROM library/centos\nRUN sudo apt-get install\nCMD echo helloworld\n' dockerfile_volume = 'FROM library/centos\nRUN sudo apt-get install\nVOLUME /var/log\nCMD echo helloworld\n' dockerfile_expose = 'FROM library/centos\nRUN sudo apt-get install\nEXPOSE 8000\nVOLUME /var/log\nCMD echo helloworld\n'
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_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()
from anchore_engine.db import get_thread_scoped_session as get_session, end_session, Image, ImagePackageVulnerability, ImagePackage, Vulnerability, VulnerableArtifact, FixedArtifact, FeedMetadata, FeedGroupMetadata from anchore_engine.services.policy_engine.engine.tasks import FeedsUpdateTask from legacy_test.services.policy_engine.utils import init_db, LocalTestDataEnvironment logging.basicConfig(level='INFO') log = logging.getLogger() init_db() test_env = LocalTestDataEnvironment(os.environ['ANCHORE_ENGINE_TEST_HOME']) 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,
def get_image(): img = Image() img.user_id = "unit_test" img.id = "da28a15dbf563fbc5a486f622b44970ee1bf10f48013bab640f403b06b278543" return img
class TestVulnerabilitiesGate: @pytest.mark.parametrize( "image_obj, mock_vuln_report, feed_group_metadata, expected_trigger_fired", [ ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", FeedGroupMetadata( last_sync=datetime.datetime.utcnow() - datetime.timedelta(days=2), name="test-feed-out-of-date", ), True, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", FeedGroupMetadata( last_sync=datetime.datetime.utcnow(), name="test-feed-not-out-of-date", ), False, ), ], ) def test_feed_out_of_date_trigger( self, image_obj, mock_vuln_report, feed_group_metadata, expected_trigger_fired, setup_mocks_vulnerabilities_gate, setup_mocks_feed_out_of_date_trigger, ): setup_mocks_vulnerabilities_gate(mock_vuln_report) setup_mocks_feed_out_of_date_trigger(feed_group_metadata) vulns_gate = VulnerabilitiesGate() trigger = FeedOutOfDateTrigger(parent_gate_cls=VulnerabilitiesGate, max_days_since_sync="1") exec_context = ExecutionContext(db_session=None, configuration={}) vulns_gate.prepare_context(image_obj, exec_context) trigger.evaluate(image_obj, exec_context) assert trigger.did_fire == expected_trigger_fired if expected_trigger_fired: assert ( trigger.fired[0].msg == f"The vulnerability feed for this image distro is older than MAXAGE ({trigger.max_age.value()}) days" ) @pytest.mark.parametrize( "image_obj, mock_vuln_report, feed_metadata, expected_trigger_fired", [ ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", FeedMetadata(name="vulnerabilities", groups=[FeedGroupMetadata(name="debian:10")]), False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", FeedMetadata(name="vulnerabilities", groups=[FeedGroupMetadata(name="debian:9")]), True, ), ], ) def test_unsupported_distro_trigger( self, image_obj, mock_vuln_report, feed_metadata, expected_trigger_fired, setup_mocks_vulnerabilities_gate, setup_mocks_unsupported_distro_trigger, ): setup_mocks_vulnerabilities_gate(mock_vuln_report) setup_mocks_unsupported_distro_trigger(feed_metadata) vulns_gate = VulnerabilitiesGate() trigger = UnsupportedDistroTrigger(parent_gate_cls=VulnerabilitiesGate) exec_context = ExecutionContext(db_session=None, configuration={}) vulns_gate.prepare_context(image_obj, exec_context) trigger.evaluate(image_obj, exec_context) assert trigger.did_fire == expected_trigger_fired if expected_trigger_fired: assert ( trigger.fired[0].msg == f"Distro-specific feed data not found for distro namespace: {image_obj.distro_namespace}. Cannot perform CVE scan OS/distro packages" ) @pytest.mark.parametrize( "image_obj, mock_vuln_report, vulnerability_ids, vendor_only, expected_trigger_fired", [ ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "CVE-2020-13529", # One matching vuln "false", True, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "CVE-2020-13579", # One fake vuln "false", False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "CVE-2020-13529", # One matching vulns (not a won't fix) "true", # Vendor only True, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_wont-fix.json", "CVE-2020-15719", # One matching vulns (was changed to won't fix for the purposes of this test) "true", # Vendor only False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "CVE-2020-13529, CVE-2020-13579", # One matching vuln and one fake vuln "false", True, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "CVE-2020-13525, CVE-2004-0975", # Two fake vulns "false", False, ), ], ) def test_vulnerabilities_blacklist_trigger( self, image_obj, mock_vuln_report, vulnerability_ids, vendor_only, expected_trigger_fired, setup_mocks_vulnerabilities_gate, ): setup_mocks_vulnerabilities_gate(mock_vuln_report) vulns_gate = VulnerabilitiesGate() trigger = VulnerabilityBlacklistTrigger( parent_gate_cls=VulnerabilitiesGate, vulnerability_ids=vulnerability_ids, vendor_only=vendor_only, ) exec_context = ExecutionContext(db_session=None, configuration={}) vulns_gate.prepare_context(image_obj, exec_context) trigger.evaluate(image_obj, exec_context) assert trigger.did_fire == expected_trigger_fired if expected_trigger_fired: assert re.fullmatch( r"Blacklisted vulnerabilities detected: \[((\'CVE-\d{4}-\d{4,}\')(, )?)+\]", trigger.fired[0].msg, ) @pytest.mark.parametrize( "image_obj, mock_vuln_report, fix_available, expected_trigger_fired, expected_number_triggers", [ ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix_fix-available.json", "true", True, 1, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix_fix-available.json", "false", False, 0, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "true", False, 0, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "false", True, 1, ), ], ) def test_vulnerability_match_trigger_fix_available( self, image_obj, mock_vuln_report, fix_available, expected_trigger_fired, expected_number_triggers, setup_mocks_vulnerabilities_gate, ): setup_mocks_vulnerabilities_gate(mock_vuln_report) vulns_gate = VulnerabilitiesGate() trigger = VulnerabilityMatchTrigger( parent_gate_cls=VulnerabilitiesGate, fix_available=fix_available, package_type="all", ) exec_context = ExecutionContext(db_session=None, configuration={}) vulns_gate.prepare_context(image_obj, exec_context) trigger.evaluate(image_obj, exec_context) assert trigger.did_fire == expected_trigger_fired assert len(trigger.fired) == expected_number_triggers @pytest.mark.parametrize( "image_obj, mock_vuln_report, vendor_only, expected_trigger_fired, expected_number_triggers", [ ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "true", True, 1, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "false", True, 1, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_wont-fix.json", "true", False, 0, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_wont-fix.json", "false", True, 1, ), ], ) def test_vulnerability_match_trigger_vendor_only( self, image_obj, mock_vuln_report, vendor_only, expected_trigger_fired, expected_number_triggers, setup_mocks_vulnerabilities_gate, ): setup_mocks_vulnerabilities_gate(mock_vuln_report) vulns_gate = VulnerabilitiesGate() trigger = VulnerabilityMatchTrigger( parent_gate_cls=VulnerabilitiesGate, vendor_only=vendor_only, package_type="all", ) exec_context = ExecutionContext(db_session=None, configuration={}) vulns_gate.prepare_context(image_obj, exec_context) trigger.evaluate(image_obj, exec_context) assert trigger.did_fire == expected_trigger_fired assert len(trigger.fired) == expected_number_triggers @pytest.mark.parametrize( "image_obj, mock_vuln_report, max_days_since_creation, expected_trigger_fired, expected_number_triggers", [ ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "1000000", False, 0, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "0", True, 1, ), ], ) def test_vulnerability_match_trigger_max_days_since_creation( self, image_obj, mock_vuln_report, max_days_since_creation, expected_trigger_fired, expected_number_triggers, setup_mocks_vulnerabilities_gate, ): setup_mocks_vulnerabilities_gate(mock_vuln_report) vulns_gate = VulnerabilitiesGate() trigger = VulnerabilityMatchTrigger( parent_gate_cls=VulnerabilitiesGate, max_days_since_creation=max_days_since_creation, package_type="all", ) exec_context = ExecutionContext(db_session=None, configuration={}) vulns_gate.prepare_context(image_obj, exec_context) trigger.evaluate(image_obj, exec_context) assert trigger.did_fire == expected_trigger_fired assert len(trigger.fired) == expected_number_triggers @pytest.mark.parametrize( "image_obj, mock_vuln_report, max_days_since_fix, expected_trigger_fired, expected_number_triggers", [ ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix_fix-available.json", "1000000", False, 0, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix_fix-available.json", "0", True, 1, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "1000000", False, 0, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "0", False, 0, ), ], ) def test_vulnerability_match_trigger_max_days_since_fix( self, image_obj, mock_vuln_report, max_days_since_fix, expected_trigger_fired, expected_number_triggers, setup_mocks_vulnerabilities_gate, ): setup_mocks_vulnerabilities_gate(mock_vuln_report) vulns_gate = VulnerabilitiesGate() trigger = VulnerabilityMatchTrigger( parent_gate_cls=VulnerabilitiesGate, max_days_since_creation=max_days_since_fix, fix_available="true", package_type="all", ) exec_context = ExecutionContext(db_session=None, configuration={}) vulns_gate.prepare_context(image_obj, exec_context) trigger.evaluate(image_obj, exec_context) assert trigger.did_fire == expected_trigger_fired assert len(trigger.fired) == expected_number_triggers @pytest.mark.parametrize( "image_obj, mock_vuln_report, package_path_exclude, expected_trigger_fired, expected_number_triggers", [ ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_non-os_will-fix.json", "/usr/.*", True, 1, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_non-os_will-fix.json", "/bin/.*", False, 0, ), ], ) def test_vulnerability_match_trigger_package_path_exclude( self, image_obj, mock_vuln_report, package_path_exclude, expected_trigger_fired, expected_number_triggers, setup_mocks_vulnerabilities_gate, ): setup_mocks_vulnerabilities_gate(mock_vuln_report) vulns_gate = VulnerabilitiesGate() trigger = VulnerabilityMatchTrigger( parent_gate_cls=VulnerabilitiesGate, package_path_exclude=package_path_exclude, package_type="non-os", vendor_only=False, ) exec_context = ExecutionContext(db_session=None, configuration={}) vulns_gate.prepare_context(image_obj, exec_context) trigger.evaluate(image_obj, exec_context) assert trigger.did_fire == expected_trigger_fired assert len(trigger.fired) == expected_number_triggers @pytest.mark.parametrize( "image_obj, mock_vuln_report, package_type, expected_trigger_fired", [ ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "all", True, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "os", True, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_non-os_will-fix.json", "os", False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "non-os", False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_non-os_will-fix.json", "non-os", True, ), ], ) def test_vulnerability_match_trigger_package_type( self, image_obj, mock_vuln_report, package_type, expected_trigger_fired, setup_mocks_vulnerabilities_gate, ): setup_mocks_vulnerabilities_gate(mock_vuln_report) vulns_gate = VulnerabilitiesGate() trigger = VulnerabilityMatchTrigger( parent_gate_cls=VulnerabilitiesGate, package_type=package_type) exec_context = ExecutionContext(db_session=None, configuration={}) vulns_gate.prepare_context(image_obj, exec_context) trigger.evaluate(image_obj, exec_context) assert trigger.did_fire == expected_trigger_fired @pytest.mark.parametrize( "image_obj, mock_vuln_report, severity_comparison, severity, expected_trigger_fired", [ ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "=", "unknown", False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "=", "negligible", False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "=", "low", True, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "=", "medium", False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "=", "high", False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "=", "critical", False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "<", "medium", True, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", ">", "medium", False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "!=", "medium", True, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "<=", "medium", True, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", ">=", "medium", False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "<", "unknown", False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", ">", "critical", False, ), ], ) def test_vulnerability_match_trigger_severity_comparison( self, image_obj, mock_vuln_report, severity_comparison, severity, expected_trigger_fired, setup_mocks_vulnerabilities_gate, ): setup_mocks_vulnerabilities_gate(mock_vuln_report) vulns_gate = VulnerabilitiesGate() trigger = VulnerabilityMatchTrigger( parent_gate_cls=VulnerabilitiesGate, severity_comparison=severity_comparison, severity=severity, package_type="all", ) exec_context = ExecutionContext(db_session=None, configuration={}) vulns_gate.prepare_context(image_obj, exec_context) trigger.evaluate(image_obj, exec_context) assert trigger.did_fire == expected_trigger_fired if expected_trigger_fired: assert len(trigger.fired) == 1 else: assert len(trigger.fired) == 0 @pytest.mark.parametrize( "image_obj, mock_vuln_report, score_comparison, base_score, expected_trigger_fired", [ ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", ">", "6.0", True, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "<", "6.0", False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "=", "6.0", False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", ">=", "6.0", True, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "<=", "6.0", False, ), ], ) def test_vulnerability_match_trigger_cvssv3_base_score_comparison( self, image_obj, mock_vuln_report, score_comparison, base_score, expected_trigger_fired, setup_mocks_vulnerabilities_gate, ): setup_mocks_vulnerabilities_gate(mock_vuln_report) vulns_gate = VulnerabilitiesGate() trigger = VulnerabilityMatchTrigger( parent_gate_cls=VulnerabilitiesGate, cvss_v3_base_score_comparison=score_comparison, cvss_v3_base_score=base_score, package_type="all", ) exec_context = ExecutionContext(db_session=None, configuration={}) vulns_gate.prepare_context(image_obj, exec_context) trigger.evaluate(image_obj, exec_context) assert trigger.did_fire == expected_trigger_fired if expected_trigger_fired: assert len(trigger.fired) == 1 else: assert len(trigger.fired) == 0 @pytest.mark.parametrize( "image_obj, mock_vuln_report, score_comparison, exploitability_score, expected_trigger_fired", [ ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", ">", "3.8", False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "<", "3.8", True, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "=", "3.8", False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", ">=", "3.8", False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "<=", "3.8", True, ), ], ) def test_vulnerability_match_trigger_cvssv3_exploitability_score_comparison( self, image_obj, mock_vuln_report, score_comparison, exploitability_score, expected_trigger_fired, setup_mocks_vulnerabilities_gate, ): setup_mocks_vulnerabilities_gate(mock_vuln_report) vulns_gate = VulnerabilitiesGate() trigger = VulnerabilityMatchTrigger( parent_gate_cls=VulnerabilitiesGate, cvss_v3_exploitability_score_comparison=score_comparison, cvss_v3_exploitability_score=exploitability_score, package_type="all", ) exec_context = ExecutionContext(db_session=None, configuration={}) vulns_gate.prepare_context(image_obj, exec_context) trigger.evaluate(image_obj, exec_context) assert trigger.did_fire == expected_trigger_fired if expected_trigger_fired: assert len(trigger.fired) == 1 else: assert len(trigger.fired) == 0 @pytest.mark.parametrize( "image_obj, mock_vuln_report, score_comparison, impact_score, expected_trigger_fired", [ ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", ">", "3.6", True, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "<", "3.6", False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "=", "3.6", False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", ">=", "3.6", True, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix.json", "<=", "3.6", False, ), ], ) def test_vulnerability_match_trigger_cvssv3_impact_score_comparison( self, image_obj, mock_vuln_report, score_comparison, impact_score, expected_trigger_fired, setup_mocks_vulnerabilities_gate, ): setup_mocks_vulnerabilities_gate(mock_vuln_report) vulns_gate = VulnerabilitiesGate() trigger = VulnerabilityMatchTrigger( parent_gate_cls=VulnerabilitiesGate, cvss_v3_impact_score_comparison=score_comparison, cvss_v3_impact_score=impact_score, package_type="all", ) exec_context = ExecutionContext(db_session=None, configuration={}) vulns_gate.prepare_context(image_obj, exec_context) trigger.evaluate(image_obj, exec_context) assert trigger.did_fire == expected_trigger_fired if expected_trigger_fired: assert len(trigger.fired) == 1 else: assert len(trigger.fired) == 0 @pytest.mark.parametrize( "image_obj, mock_vuln_report, score_comparison, base_score, expected_trigger_fired", [ ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix_vendor_cvssv3.json", ">", "6.0", True, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix_vendor_cvssv3.json", "<", "6.0", False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix_vendor_cvssv3.json", "=", "6.0", False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix_vendor_cvssv3.json", ">=", "6.0", True, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix_vendor_cvssv3.json", "<=", "6.0", False, ), ], ) def test_vulnerability_match_trigger_vendor_cvssv3_base_score_comparison( self, image_obj, mock_vuln_report, score_comparison, base_score, expected_trigger_fired, setup_mocks_vulnerabilities_gate, ): setup_mocks_vulnerabilities_gate(mock_vuln_report) vulns_gate = VulnerabilitiesGate() trigger = VulnerabilityMatchTrigger( parent_gate_cls=VulnerabilitiesGate, vendor_cvss_v3_base_score_comparison=score_comparison, vendor_cvss_v3_base_score=base_score, package_type="all", ) exec_context = ExecutionContext(db_session=None, configuration={}) vulns_gate.prepare_context(image_obj, exec_context) trigger.evaluate(image_obj, exec_context) assert trigger.did_fire == expected_trigger_fired if expected_trigger_fired: assert len(trigger.fired) == 1 else: assert len(trigger.fired) == 0 @pytest.mark.parametrize( "image_obj, mock_vuln_report, score_comparison, exploitability_score, expected_trigger_fired", [ ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix_vendor_cvssv3.json", ">", "3.8", False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix_vendor_cvssv3.json", "<", "3.8", True, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix_vendor_cvssv3.json", "=", "3.8", False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix_vendor_cvssv3.json", ">=", "3.8", False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix_vendor_cvssv3.json", "<=", "3.8", True, ), ], ) def test_vulnerability_match_trigger_vendor_cvssv3_exploitability_score_comparison( self, image_obj, mock_vuln_report, score_comparison, exploitability_score, expected_trigger_fired, setup_mocks_vulnerabilities_gate, ): setup_mocks_vulnerabilities_gate(mock_vuln_report) vulns_gate = VulnerabilitiesGate() trigger = VulnerabilityMatchTrigger( parent_gate_cls=VulnerabilitiesGate, vendor_cvss_v3_exploitability_score_comparison=score_comparison, vendor_cvss_v3_exploitability_score=exploitability_score, package_type="all", ) exec_context = ExecutionContext(db_session=None, configuration={}) vulns_gate.prepare_context(image_obj, exec_context) trigger.evaluate(image_obj, exec_context) assert trigger.did_fire == expected_trigger_fired if expected_trigger_fired: assert len(trigger.fired) == 1 else: assert len(trigger.fired) == 0 @pytest.mark.parametrize( "image_obj, mock_vuln_report, score_comparison, impact_score, expected_trigger_fired", [ ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix_vendor_cvssv3.json", ">", "3.6", True, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix_vendor_cvssv3.json", "<", "3.6", False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix_vendor_cvssv3.json", "=", "3.6", False, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix_vendor_cvssv3.json", ">=", "3.6", True, ), ( Image(id="1", user_id="admin", distro_name="debian", distro_version="10"), "debian_1_os_will-fix_vendor_cvssv3.json", "<=", "3.6", False, ), ], ) def test_vulnerability_match_trigger_vendor_cvssv3_impact_score_comparison( self, image_obj, mock_vuln_report, score_comparison, impact_score, expected_trigger_fired, setup_mocks_vulnerabilities_gate, ): setup_mocks_vulnerabilities_gate(mock_vuln_report) vulns_gate = VulnerabilitiesGate() trigger = VulnerabilityMatchTrigger( parent_gate_cls=VulnerabilitiesGate, vendor_cvss_v3_impact_score_comparison=score_comparison, vendor_cvss_v3_impact_score=impact_score, package_type="all", ) exec_context = ExecutionContext(db_session=None, configuration={}) vulns_gate.prepare_context(image_obj, exec_context) trigger.evaluate(image_obj, exec_context) assert trigger.did_fire == expected_trigger_fired if expected_trigger_fired: assert len(trigger.fired) == 1 else: assert len(trigger.fired) == 0
GateUnitTest, cls_no_feeds_test_env, ) from anchore_engine.db import Image from anchore_engine.services.policy_engine.engine.policy.gates.dockerfile import ( DockerfileGate, ExposedPortsTrigger, InstructionCheckTrigger, EffectiveUserTrigger, NoDockerfile, ) logger.enable_test_logging() test_image = Image() test_image.distro_name = "debian" test_image.distro_version = "9" test_image.user_id = "0" test_image.layer_info_json = ["layer1", "layer2"] test_image.dockerfile_contents = "FROM SCRATCH\nHEALTHCHECK blah\n" test_image.dockerfile_mode = "Guessed" dockerfile_from = ( "FROM library/centos:latest\nRUN apt-get install\nCMD echo helloworld\n") dockerfile_scratch = "FROM SCRATCH\nRUN apt-get install\nCMD echo helloworld\n" dockerfile_healthcheck = "FROM library/centos:latest\nRUN apt-get install\nCMD echo helloworld\nHEALTHcheck echo hello\n" dockerfile_no_healthcheck = ( "FROM library/centos:latest\nRUN apt-get install\nCMD echo helloworld\n") dockerfile_no_tag = "FROM library/centos\nRUN apt-get install\nCMD echo helloworld\n" dockerfile_no_from = "ADD ./files/* /\nRUN apt-get install\nCMD echo helloworld\n"
namespace_name="debian:8", severity="high", fixed_in=[ FixedArtifact(name="testpkg1", version="1.0.1", version_format="deb") ], ) ] mock_images = [ Image( user_id="admin", id="1", digest="sha256:1", distro_name="debian", distro_version="9", like_distro="debian", state="analyzed", ) ] mock_packages = [ ImagePackage( image_user_id="admin", image_id="1", name="testpkg1", version="1.0.0", size=100, arch="amd64", pkg_type="deb",
mock_vulnerabilities = [ Vulnerability(id='cve-1', namespace_name='debian:8', severity='high', fixed_in=[ FixedArtifact(name='testpkg1', version='1.0.1', version_format='deb') ]) ] mock_images = [ Image(user_id='admin', id='1', digest='sha256:1', distro_name='debian', distro_version='9', like_distro='debian', state='analyzed') ] mock_packages = [ ImagePackage( image_user_id='admin', image_id='1', name='testpkg1', version='1.0.0', size=100, arch='amd64', pkg_type='deb', distro_name='debian',
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 load(self): """ Loads the exported image data into this system for usage. :param image_export_json: :return: an initialized Image() record, not persisted to DB yet """ log.info('Loading image json') if type(self.image_export_json) == list and len( self.image_export_json) == 1: image_id = self.image_export_json[0]['image']['imageId'] self.image_export_json = self.image_export_json[0]['image'][ 'imagedata'] log.info( 'Detected a direct export format for image id: {} rather than a catalog analysis export' .format(image_id)) analysis_report = self.image_export_json['analysis_report'] image_report = self.image_export_json['image_report'] image = Image() image.id = image_report['meta']['imageId'] image.size = int(image_report['meta']['sizebytes']) repo_digests = image_report['docker_data'].get('RepoDigests', []) repo_tags = image_report['docker_data'].get('RepoTags', []) if len(repo_digests) > 1: log.warn( 'Found more than one digest for the image {}. Using the first. Digests: {}, Tags: {}' .format(image.id, repo_digests, repo_tags)) image.digest = repo_digests[0].split('@', 1)[1] if repo_digests else None # Tags handled in another phase using the docker_data in the image record. # get initial metadata analyzer_meta = analysis_report['analyzer_meta']['analyzer_meta'][ 'base'] if 'LIKEDISTRO' in analyzer_meta: like_dist = analyzer_meta['LIKEDISTRO'] else: like_dist = analyzer_meta['DISTRO'] image.distro_name = analyzer_meta['DISTRO'] image.distro_version = analyzer_meta['DISTROVERS'] image.like_distro = like_dist image.dockerfile_mode = image_report['dockerfile_mode'] # JSON data image.docker_data_json = image_report['docker_data'] image.docker_history_json = image_report['docker_history'] image.dockerfile_contents = image_report['dockerfile_contents'] image.layers_to_dockerfile_json = analysis_report.get('layer_info') image.layers_json = image_report['layers'] image.familytree_json = image_report['familytree'] image.analyzer_manifest = self.image_export_json['analyzer_manifest'] # Image content # Packages log.info('Loading image packages') image.packages = self.load_and_normalize_packages( analysis_report.get('package_list', {}), image) # Package metadata log.info('Loading image package db entries') self.load_package_verification(analysis_report, image) # FileSystem log.info('Loading image files') image.fs = self.load_fsdump(analysis_report) # Npms log.info('Loading image npms') image.npms = self.load_npms(analysis_report, image) # Gems log.info('Loading image gems') image.gems = self.load_gems(analysis_report, image) # CPEs log.info('Loading image cpes') image.cpes = self.load_cpes(analysis_report, image) analysis_artifact_loaders = [ self.load_retrieved_files, self.load_content_search, self.load_secret_search #self.load_package_verification ] # Content searches image.analysis_artifacts = [] for loader in analysis_artifact_loaders: for r in loader(analysis_report, image): image.analysis_artifacts.append(r) image.state = 'analyzed' return image
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"