Ejemplo n.º 1
0
    def execute(self):
        """
        Execute a load.
        Fetch from the catalog and send to loader.
        :return: the ImageLoad result object including the image object and its vulnerabilities or None if image already found
        """

        self.start_time = datetime.datetime.utcnow()
        try:
            db = get_session()
            img = db.query(Image).get((self.image_id, self.user_id))
            if img is not None:
                if not self.force_reload:
                    log.info(
                        'Image {}/{} already found in the system. Will not re-load.'
                        .format(self.user_id, self.image_id))
                    db.close()
                    return None
                else:
                    log.info(
                        'Deleting image {}/{} and all associated resources for reload'
                        .format(self.user_id, self.image_id))
                    for pkg_vuln in img.vulnerabilities():
                        db.delete(pkg_vuln)
                    db.delete(img)

            # Close the session during the data fetch.
            #db.close()

            image_obj = self._load_image_analysis()
            if not image_obj:
                log.error('Could not load image analysis')
                raise ImageLoadError(
                    'Failed to load image: user_id = {}, image_id = {}, fetch_url = {}'
                    .format(self.user_id, self.image_id, self.fetch_url))

            db = get_session()
            try:
                log.info("Adding image to db")
                db.add(image_obj)

                log.info("Adding image package vulnerabilities to db")
                vulns = vulnerabilities_for_image(image_obj)
                for vuln in vulns:
                    db.add(vuln)

                db.commit()
            except:
                log.exception('Error adding image to db')
                db.rollback()
                raise

            return ImageLoadResult(image_obj, vulns)
        except Exception as e:
            log.exception('Error loading and scanning image: {}'.format(
                self.image_id))
            raise
        finally:
            self.stop_time = datetime.datetime.utcnow()
def check_all_imgs_vuln():
    db = get_thread_scoped_session()
    try:
        for img in db.query(Image).all():
            logger.info('Checking vulnerabilities for image: {}'.format(img.id))
            if not img:
                logger.info('No image found with id: {}'.format(img.id))
                raise Exception('Should have image')
            vulns = vulnerabilities.vulnerabilities_for_image(img)

            for v in vulns:
                db.merge(v)
            db.commit()

            logger.info('Found: {}'.format(vulns))
    except Exception as e:
        logger.info('Error! {}'.format(e))
        end_session()
Ejemplo n.º 3
0
def get_image_vulnerabilities(user_id, image_id, force_refresh=False):
    """
    Return the vulnerability listing for the specified image and load from catalog if not found and specifically asked
    to do so.


    Example json output:
    {
       "multi" : {
          "url_column_index" : 7,
          "result" : {
             "rows" : [],
             "rowcount" : 0,
             "colcount" : 8,
             "header" : [
                "CVE_ID",
                "Severity",
                "*Total_Affected",
                "Vulnerable_Package",
                "Fix_Available",
                "Fix_Images",
                "Rebuild_Images",
                "URL"
             ]
          },
          "querycommand" : "/usr/lib/python2.7/site-packages/anchore/anchore-modules/multi-queries/cve-scan.py /ebs_data/anchore/querytmp/queryimages.7026386 /ebs_data/anchore/data /ebs_data/anchore/querytmp/query.59057288 all",
          "queryparams" : "all",
          "warns" : [
             "0005b136f0fb (prom/prometheus:master) cannot perform CVE scan: no CVE data is currently available for the detected base distro type (busybox:unknown_version,busybox:v1.26.2)"
          ]
       }
    }

    :param user_id: user id of image to evaluate
    :param image_id: image id to evaluate
    :param force_refresh: if true, flush and recompute vulnerabilities rather than returning current values
    :return:
    """

    # Has image?
    db = get_session()
    try:
        img = db.query(Image).get((image_id, user_id))
        vulns = []
        if not img:
            abort(404)
        else:
            if force_refresh:
                log.info('Forcing refresh of vulnerabiltiies for {}/{}'.format(user_id, image_id))
                try:
                    current_vulns = img.vulnerabilities()
                    log.info('Removing {} current vulnerabilities for {}/{} to rescan'.format(len(current_vulns), user_id, image_id))
                    for v in current_vulns:
                        db.delete(v)

                    db.flush()
                    vulns = vulnerabilities_for_image(img)
                    log.info('Adding {} vulnerabilities from rescan to {}/{}'.format(len(vulns), user_id, image_id))
                    for v in vulns:
                        db.add(v)
                    db.commit()
                except Exception as e:
                    log.exception('Error refreshing cve matches for image {}/{}'.format(user_id, image_id))
                    db.rollback()
                    abort(Response('Error refreshing vulnerability listing for image.', 500))

                db = get_session()
                db.refresh(img)
            else:
                vulns = img.vulnerabilities()

        # Has vulnerabilities?
        warns = []
        if not vulns:
            vulns = []
            ns = DistroNamespace.for_obj(img)
            if not have_vulnerabilities_for(ns):
                warns = ['No vulnerability data available for image distro: {}'.format(ns.namespace_name)]


        rows = []
        for vuln in vulns:
            # if vuln.vulnerability.fixed_in:
            #     fixes_in = filter(lambda x: x.name == vuln.pkg_name or x.name == vuln.package.normalized_src_pkg,
            #            vuln.vulnerability.fixed_in)
            #     fix_available_in = fixes_in[0].version if fixes_in else 'None'
            # else:
            #     fix_available_in = 'None'

            rows.append([
                vuln.vulnerability_id,
                vuln.vulnerability.severity,
                1,
                vuln.pkg_name + '-' + vuln.package.fullversion,
                str(vuln.fixed_in()),
                vuln.pkg_image_id,
                'None', # Always empty this for now
                vuln.vulnerability.link
                ]
            )

        vuln_listing = {
            'multi': {
                'url_column_index': 7,
                'result': {
                    'header': TABLE_STYLE_HEADER_LIST,
                    'rowcount': len(rows),
                    'colcount': len(TABLE_STYLE_HEADER_LIST),
                    'rows': rows
                },
                'warns': warns
            }
        }

        report = LegacyVulnerabilityReport.from_dict(vuln_listing)
        resp = ImageVulnerabilityListing(user_id=user_id, image_id=image_id, legacy_report=report)
        return resp.to_dict()
    except HTTPException:
        db.rollback()
        raise
    except Exception as e:
        log.exception('Error checking image {}, {} for vulnerabiltiies. Rolling back'.format(user_id, image_id))
        db.rollback()
        abort(500)
    finally:
        db.close()
Ejemplo n.º 4
0
    def compute_vulnerabilities(self, image_obj):
        """
        Wrapper for vulnerabilities_for_image function
        """

        vulnerabilities.vulnerabilities_for_image(image_obj)