Exemplo n.º 1
0
def report_to_cyclonedx(report: Report) -> Bom:
    bom = Bom()

    for failed_check in report.failed_checks:
        component = Component.for_file(
            absolute_file_path=failed_check.file_abs_path,
            path_for_bom=failed_check.file_path)

        component.add_vulnerability(
            Vulnerability(
                id=failed_check.check_id,
                source_name='checkov',
                description=
                f'Resource: {failed_check.resource}. {failed_check.check_name}',
                advisories=[failed_check.guideline]))
        bom.add_component(component=component)

    return bom
Exemplo n.º 2
0
    def get_cyclonedx_bom(self) -> Bom:
        bom = Bom()

        if sys.version_info >= (3, 8, 0):
            from importlib.metadata import version as meta_version
        else:
            from importlib_metadata import version as meta_version

        try:
            this_tool = Tool(vendor='bridgecrew',
                             name='checkov',
                             version=meta_version('checkov'))
        except Exception:
            # Unable to determine current version of 'checkov'
            this_tool = Tool(vendor='bridgecrew',
                             name='checkov',
                             version='UNKNOWN')
        bom.get_metadata().add_tool(this_tool)

        for check in itertools.chain(self.passed_checks, self.skipped_checks):
            component = Component.for_file(
                absolute_file_path=check.file_abs_path,
                path_for_bom=check.file_path)

            if bom.has_component(component=component):
                component = bom.get_component_by_purl(
                    purl=component.get_purl())

            bom.add_component(component=component)

        for failed_check in self.failed_checks:
            component = Component.for_file(
                absolute_file_path=failed_check.file_abs_path,
                path_for_bom=failed_check.file_path)

            if bom.has_component(component=component):
                component = bom.get_component_by_purl(
                    purl=component.get_purl())

            component.add_vulnerability(
                Vulnerability(
                    id=failed_check.check_id,
                    source_name='checkov',
                    description=
                    f'Resource: {failed_check.resource}. {failed_check.check_name}',
                    recommendations=[failed_check.guideline]))
            bom.add_component(component=component)

        return bom
Exemplo n.º 3
0
 def __init__(self) -> None:
     """Start the report."""
     self._bom = Bom()
     self._bom.metadata.add_tool(self.dfetch_tool)
Exemplo n.º 4
0
class SbomReporter(Reporter):
    """Reporter for generating SBoM's."""

    url_splitter = re.compile(r"([^\/)]+)")
    github_url = re.compile(r"github.com\/(?P<group>.+)\/(?P<repo>[^\s\.]+)[\.]?")
    dfetch_tool = Tool(vendor="dfetch-org", name="dfetch", version=dfetch.__version__)

    name = "SBoM"

    def __init__(self) -> None:
        """Start the report."""
        self._bom = Bom()
        self._bom.metadata.add_tool(self.dfetch_tool)

    def add_project(
        self, project: ProjectEntry, license_name: str, version: str
    ) -> None:
        """Add a project to the report."""
        match = self.github_url.search(project.remote_url)
        if match:
            component = Component(
                name=project.name,
                version=version,
                component_type=ComponentType.LIBRARY,
                purl=PackageURL(
                    type="github",
                    name=match.group("repo"),
                    version=version,
                    namespace=match.group("group"),
                    subpath=project.source or None,
                ),
            )
        else:
            parts = self._split_url(project.remote_url)
            component = Component(
                name=project.name,
                version=version,
                component_type=ComponentType.LIBRARY,
                purl=PackageURL(
                    type="generic",
                    version=version,
                    qualifiers=f"download_url={project.remote_url}",
                    namespace=parts[0],
                    subpath=project.source or None,
                ),
            )
            component.add_external_reference(
                ExternalReference(
                    reference_type=ExternalReferenceType.VCS,
                    url=project.remote_url,
                )
            )

        component.licenses += [LicenseChoice(license_expression=license_name)]
        self._bom.add_component(component)

    @staticmethod
    def _split_url(url: str) -> List[str]:
        """Split the url in elements."""
        return [
            part.group()
            for part in SbomReporter.url_splitter.finditer(url)
            if not part.group().endswith(":")  # Skip protocol specifiers
        ]

    def dump_to_file(self, outfile: str) -> bool:
        """Dump the SBoM to file."""
        output_format = (
            OutputFormat.XML if outfile.endswith(".xml") else OutputFormat.JSON
        )
        outputter = cast(Json, get_instance(bom=self._bom, output_format=output_format))

        parsed = json.loads(outputter.output_as_string())
        outputter._json_output = json.dumps(  # pylint: disable=protected-access
            parsed, indent=4
        )

        outputter.output_to_file(outfile, allow_overwrite=True)

        return True