软件工程

SBOM (软件物料清单,Software Bill of Materials) — 第二部分,用Syft和Grype报告生成。

本文主要是介绍SBOM (软件物料清单,Software Bill of Materials) — 第二部分,用Syft和Grype报告生成。,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
遇到问题吗?

本文提到的功能,以及更多功能,都可以通过SOCFortress平台实现。让SOCFortress帮助你和你的团队确保基础设施的安全。

网址是:https://www.socfortress.co/

如有任何問題,請聯繫我們: https://www.socfortress.co/contact_form.html

开头

在网络安全领域,SBOM(软件物料清单,Software Bill of Materials 的简称)是一个关键文档,列出了构建软件应用程序所使用的组件,包括库、框架、依赖项等。

这就像软件的“成分列表”,列出了构成该软件的开源闭源组件。利用它,组织可以更好地理解、管理和保护其应用程序的安全。

(请参阅前文这里)

使用Syft创建SBOM报告(软件物料清单):
创建SBOM报告

可以参考:https://github.com/anchore/syft

Syft 是一个由 Anchore 开发的开放源代码工具,旨在为容器镜像和文件系统生成软件物料清单(SBOM),。它通过识别依赖项、库和其他第三方组件来帮助组织了解其软件的构成部分,这对于安全性和合规性来说是至关重要的。

通过为您的容器映像或软件构建生成 SBOM,Syft 帮助团队识别正在使用的第三方组件,并结合使用 Grype 漏洞扫描,帮助识别这些组件中的已知漏洞。

Syft 生成的 SBOMs 帮助组织遵守行业标准和监管要求(例如,美国的网络安全行政命令,该命令要求为政府使用的软件生成 SBOM 信息)。

许多组织对开源软件许可协议感到担心。Syft 的 SBOM 包含识别软件包的许可证信息,这有助于更轻松地管理许可风险并确保符合许可政策,使许可证管理过程更加简化。

随着供应链攻击变得越来越常见,了解软件内部的细节至关重要。Syft 帮助开发人员、安全团队和运营团队清楚地了解所使用的组件及其相关风险,从而提升整体的安全态势。

Syft 可以轻松集成到 CI/CD 流水线中,帮助团队在软件开发的各个阶段生成软件物料清单,从而执行安全检查并确保软件在部署前的完整性。

Syft可以通过APIs和自定义工作流来扩展其功能,使其成为一个灵活的自动安全工具。

Syft的关键特性
  • SBOM 生成:
    Syft 可以生成各种格式的 SBOM,例如:
    — CycloneDX(一种常用的安全上下文格式)
    — SPDX(用于交换软件包数据的格式)
    — Syft 的内置格式

SBOM 提供了关于软件组件的详细元数据,包括软件包清单、版本、许可证以及潜在的安全漏洞(在配合漏洞扫描工具使用时)。

  • 支持不同的生态系统 :
    Syft 支持广泛的软件生态系统和包类型。一些最常见的支持的生态系统包括:
    — Docker 和符合 OCI 标准的容器镜像
    — Java(JAR、WAR、EAR 文件)
    — JavaScript(NPM 包)
    — Python(Pip、Poetry)
    — Ruby(Gem 包)
    — Go 模块
    — Rust(Cargo)
    — .NET(NuGet 包)
    — 文件系统扫描功能
  • 与CI/CD管道集成 :
    Syft 可以集成到持续集成/持续部署(CI/CD)管道中,保证对软件供应链的实时可见性,并使组织能够在其开发过程中早期监控和管理安全风险。
  • 容器镜像支持 :
    Syft 可以检查和分析存储在 Docker 注册表中的容器镜像,并为这些镜像生成 SBOM。这对于开发人员构建容器化应用程序非常有用,同时对于安全团队监视生产中的容器部署也非常有帮助。
  • 命令行接口(CLI) :
    Syft 作为命令行工具构建,使其容易集成到工作流程中。您可以在本地机器上直接运行 Syft 命令,或将它们集成到自动化脚本中。
  • 支持其他工具 :
    Syft 通常与 Grype 一起使用,这是另一个由 Anchore 提供的工具,用于对 SBOM 进行漏洞扫描。当一起使用时,Syft 和 Grype 可以帮助组织发现其 SBOM 中的漏洞包和组件。
使用Grype进行漏洞扫描报告

可以参考: https://github.com/anchore/grype

Grype 是一个开源的 漏洞扫描工具,用于扫描容器图像和文件系统中的漏洞等。它帮助开发人员和安全专家识别软件供应链中的已知漏洞。由 Anchore 开发的 Grype 通过将图像或文件系统中的软件包与美国国家漏洞数据库(NVD)、GitHub 咨询信息等数据库中的已知漏洞进行比对来查找漏洞。

Grype 帮助开发人员和安全团队在开发周期早期识别漏洞,保护容器化应用程序免受已知漏洞攻击。

通过其 CI/CD 集成,Grype 使漏洞扫描成为软件开发过程中的自动化环节,从而使软件开发过程中的安全保持持续。

作为 Anchore 开源项目的一员,Grype 不断 更新最新的漏洞数据和特性。它拥有一个活跃的社区,在云原生领域中,它被信赖为漏洞管理工具。

特点:
  • 全面漏洞扫描 :
    — Grype 使用公共漏洞数据库来扫描容器镜像、文件系统和单个软件包,查找已知漏洞。
    — 它支持众多的包管理器(如 APT、RPM、APK、NPM 和 Python 的 PIP),同时兼容多种操作系统发行版。
  • 多个漏洞数据来源 :
    — Grype 从多个来源拉取漏洞数据,包括 NVD、Alpine SecDB、Red Hat UBI、GitHub 安全公告等。这使它能够有效地识别不同生态系统中的漏洞。
  • 与 Syft 的 SBOM 集成 :
    — Grype 无缝集成到另一个由 Anchore 开发的工具 Syft 中,该工具生成软件物料清单(SBOM)。您可以使用 Syft 生成软件组件列表(如已安装的包),然后 Grype 将扫描该列表以查找漏洞。
    — 这种方法确保了全面扫描,并提供了对镜像中运行软件的可见性。
  • 多种输出格式 :
    — Grype 提供了灵活的扫描结果输出方式,支持多种格式:
    — CycloneDX(XML/JSON):一种用于以机器可读方式共享漏洞数据的标准格式。
    — SPDX(JSON):另一种流行的漏洞报告格式。
    — SARIF:静态分析结果互换格式,适合与静态代码分析工具集成。
    — JSON:以详细的原始报告形式获得,可以与其他工作流集成或进一步分析。
  • 持续集成/持续部署 (CI/CD) 集成 :
    — Grype 可以集成到 CI/CD 流水线中,自动在开发和部署过程中扫描容器镜像中的漏洞。这有助于在镜像推送至生产环境之前捕获漏洞,从而提供额外的安全防护。
  • 可自定义的数据源 :
    — 用户可以配置 Grype 使用他们自己的漏洞数据源或自定义扫描中使用的数据源。
  • 基于 CLI 且易于使用 :
    — Grype 轻量且易于安装,使得它可以轻松地集成到现有系统和自动化工作流中。
Syft 和 Grype 在行动

使用Python Flask,我们可以快速搭建一个web服务器,并创建一个表单来输入我们想要生成相关Docker镜像的SBOM和漏洞报告的名称。

以下是一些步骤:

安装Syft程序。

    curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin  # 此命令用于从GitHub下载并安装Syft工具到指定路径 /usr/local/bin

安装一下 Grype。

    curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin
# 使用curl从GitHub下载安装脚本,然后通过shell执行该脚本来安装grype到/usr/local/bin目录。

安装 Flask:

命令是 pip install Flask,这会安装 Flask 框架。

创建一个 python 文件 "app.py"。

    from flask import Flask, render_template, request, send_file  
    import os  
    import subprocess  

    app = Flask(__name__)  

    # 确保输出文件的目录存在  
    OUTPUT_DIR = "reports"  
    if not os.path.exists(OUTPUT_DIR):  
        os.makedirs(OUTPUT_DIR)  

    # 定义Syft和Grype可用的格式  
    SYFT_FORMATS = [  
        "syft-json",  
        "cyclonedx-xml",  
        "cyclonedx-xml@1.5",  
        "cyclonedx-json",  
        "cyclonedx-json@1.5",  
        "spdx-json",  
        "spdx-json@2.2"  
    ]  

    GRYPE_FORMATS = [  
        "cyclonedx",  
        "cyclonedx-json",  
        "json",  
        "sarif"  
    ]  

    @app.route('/')  
    def index():  
        return render_template('index.html', syft_formats=SYFT_FORMATS, grype_formats=GRYPE_FORMATS)  

    @app.route('/generate', methods=['POST'])  
    def generate_reports():  
        image_id = request.form['image_id']  
        syft_format = request.form['syft_format']  
        grype_format = request.form['grype_format']  

        if not image_id:  
            return "Error: Docker image ID is required.", 400  

        # 生成Syft和Grype输出文件路径  
        syft_output_file = os.path.join(OUTPUT_DIR, f"{image_id.replace(':', '_')}_syft_report.{syft_format.split('-')[-1]}")  
        grype_output_file = os.path.join(OUTPUT_DIR, f"{image_id.replace(':', '_')}_grype_report.{grype_format.split('-')[-1]}")  

        try:  
            # 运行Syft命令  
            syft_command = f"syft {image_id} -o {syft_format} > {syft_output_file}"  
            subprocess.run(syft_command, shell=True, check=True)  

            # 运行Grype命令  
            grype_command = f"grype {image_id} -o {grype_format} > {grype_output_file}"  
            subprocess.run(grype_command, shell=True, check=True)  

        except subprocess.CalledProcessError as e:  
            return f"生成报告时出错:{e}", 500  

        # 提供Syft和Grype报告文件的下载链接  
        return f"""  
            报告生成成功:<br>  
            <a href='/download/{os.path.basename(syft_output_file)}'>下载Syft报告文件</a><br>  
            <a href='/download/{os.path.basename(grype_output_file)}'>下载Grype报告文件</a>  
        """  

    @app.route('/download/<filename>')  
    def download_file(filename):  
        filepath = os.path.join(OUTPUT_DIR, filename)  
        if os.path.exists(filepath):  
            return send_file(filepath, as_attachment=True)  
        else:  
            return "文件未找到,请检查文件名是否正确", 404  

    if __name__ == '__main__':  
        app.run(debug=True)

HTML模板:

    从 flask 导入 Flask, render_template, request, send_file 作为 send_file  
    导入 os  
    导入 subprocess    

    app = Flask(__name__)  

    # 确保用于存储输出文件的目录存在  
    OUTPUT_DIR = "reports"  
    如果 not os.path.exists(OUTPUT_DIR):  
        os.makedirs(OUTPUT_DIR)  

    # 定义 Syft 和 Grype 的可用格式  
    SYFT_FORMATS = [  
        "syft-json",  
        "cyclonedx-xml",  
        "cyclonedx-xml@1.5",  
        "cyclonedx-json",  
        "cyclonedx-json@1.5",  
        "spdx-json",  
        "spdx-json@2.2"  
    ]  

    GRYPE_FORMATS = [  
        "cyclonedx",  
        "cyclonedx-json",  
        "json",  
        "sarif"  
    ]  

    @app.route('/')  
    def index():  
        渲染并返回 render_template('index.html', syft_formats=SYFT_FORMATS, grype_formats=GRYPE_FORMATS)  

    @app.route('/generate', methods=['POST'])  
    def generate_reports():  
        image_id = request.form['image_id']  
        syft_format = request.form['syft_format']  
        grype_format = request.form['grype_format']  

        如果 not image_id:  
            返回 "错误: Docker image ID 是必需的.", 400  

        # 生成 Syft 和 Grype 输出的文件路径  
        syft_output_file = os.path.join(OUTPUT_DIR, f"{image_id.replace(':', '_')}_syft_report.{syft_format.split('-')[-1]}")  
        grype_output_file = os.path.join(OUTPUT_DIR, f"{image_id.replace(':', '_')}_grype_report.{grype_format.split('-')[-1]}")  

        尝试:  
            # 运行 Syft 命令  
            syft_command = f"syft {image_id} -o {syft_format} > {syft_output_file}"  
            subprocess.run(syft_command, shell=True, check=True)  

            # 运行 Grype 命令  
            grype_command = f"grype {image_id} -o {grype_format} > {grype_output_file}"  
            subprocess.run(grype_command, shell=True, check=True)  

        除了 subprocess.CalledProcessError 作为 e:  
            返回 f"生成报告时出错: {e}", 500  

        # 提供两个报告的下载链接  
        返回 f"""  
            报告生成成功!<br>  
            <a href='/download/{os.path.basename(syft_output_file)}'>下载 Syft 报告</a><br>  
            <a href='/download/{os.path.basename(grype_output_file)}'>下载 Grype 报告</a>  
        """  

    @app.route('/download/<filename>')  
    def download_file(filename):  
        filepath = os.path.join(OUTPUT_DIR, filename)  
        如果 os.path.exists(filepath):  
            返回 send_file(filepath, 作为附件=True)  
        否则:  
            返回 "文件未找到!", 404  

    如果 __name__ 等于 '__main__':  
        app.run(debug=True)

打开应用。

我们可以在网页表单中选择输出格式,如上图所示。

Syft 格式规范:

  • syft-json: 用于尽可能多地获取Syft中的信息!
  • clonedx-xml: 按照CycloneDX 1.6规范生成的XML报告。
  • cyclonedx-xml@1.5: 按照CycloneDX 1.5规范生成的XML报告。
  • cyclonedx-json: 按照CycloneDX 1.6规范生成的JSON报告。
  • cyclonedx-json@1.5: 按照CycloneDX 1.5规范生成的JSON报告。
  • spdx-json: 按照SPDX 2.3 JSON Schema生成的JSON报告。
  • spdx-json@2.2: 按照SPDX 2.2 JSON Schema生成的JSON报告。

格赖普格式说明:

  • XML 报告:符合 CycloneDX 1.6 规范的报告。
  • JSON 报告:符合 CycloneDX 1.6 规范的报告。
  • 使用此选项可以尽可能多地获取 Grype 的信息。
  • 使用此选项以获取 SARIF 报告,这是一种静态分析结果交换格式。

提交后即可下载报告:

Grype报告中的漏洞:

需要帮忙吗?

本文中讨论的功能,以及其他众多功能,均可通过SOCFortress平台使用。让SOCFortress帮助您和您的团队保障基础设施的安全。

网址:https://www.socfortress.co./

想联系我们?点击这里:https://www.socfortress.co/contact_form.html

这篇关于SBOM (软件物料清单,Software Bill of Materials) — 第二部分,用Syft和Grype报告生成。的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!