静态应用程序安全测试(SAST)

在 13.3 版本中,所有开源 (OSS) 分析器都从旗舰版迁移到了免费版。

如果您使用极狐GitLab CI/CD,您可以使用静态应用程序安全测试 (SAST) 检查源代码中的已知漏洞。您可以在任何级别的版本中运行 SAST 分析器。分析器将 JSON 格式的报告作为作业产物输出。

使用旗舰版,还可以处理 SAST 结果:

  • 在合并请求中查看它们。
  • 在审核工作流程中使用它们。
  • 在安全仪表盘中查看它们。

有关更多详细信息,请参阅功能摘要

SAST results shown in the MR widget

结果按漏洞的优先级排序:

  1. Critical
  2. High
  3. Medium
  4. Low
  5. Info
  6. Unknown

一个流水线由多个作业组成,包括 SAST 和 DAST 扫描。如果任何作业因任何原因未能完成,安全仪表盘不会显示 SAST 扫描仪输出。例如,SAST 作业完成但 DAST 作业失败,则安全仪表盘不会显示 SAST 结果。失败时,分析器会输出退出代码。

用例

  • 您的代码在类中具有潜在危险属性,或者可能导致意外代码执行的不安全代码。
  • 您的应用程序容易受到跨站点脚本 (XSS) 攻击,这些攻击可用于未经授权访问会话数据。

要求

SAST 在 test 阶段运行,默认情况下可用。如果在 .gitlab-ci.yml 文件中重新定义阶段,则需要 test 阶段。

要运行 SAST 作业,默认情况下,您需要带有 dockerkubernetes 执行器。 如果您在 JihuLab.com 上使用共享 runner,则默认启用此功能。

caution我们的 SAST 作业需要 Linux/amd64 容器类型。尚不支持 Windows 容器。
caution如果您使用自己的 runner,请确保安装的 Docker 版本不是 19.03.0。有关详细信息,请参阅故障排除信息

支持的语言和框架

SAST 支持多种语言、包管理器和框架。我们的 SAST 安全扫描器还具有自动语言检测功能,甚至适用于混合语言项目。如果在项目源代码中检测到任何受支持的语言,我们会自动运行相应的 SAST 分析器。

语言(包管理器)/ 框架 扫描工具 引入版本
.NET Core Security Code Scan 11.0
.NET Framework1 Security Code Scan 13.0
Apex (Salesforce) PMD 12.1
C Semgrep 14.2
C/C++ Flawfinder 10.7
Elixir (Phoenix) Sobelow 11.1
Go Gosec 10.7
Go Semgrep 14.4
Groovy2 SpotBugs,具有 find-sec-bugs 插件 11.3 (Gradle) & 11.9 (Ant, Maven, SBT)
Helm Charts Kubesec 13.1
Java (any build system) Semgrep 14.10
Java2 SpotBugs,具有 find-sec-bugs 插件 10.6 (Maven), 10.8 (Gradle) & 11.9 (Ant, SBT)
Java (Android) MobSF (beta) 13.5
JavaScript ESLint security plugin 11.8
JavaScript Semgrep 13.10
Kotlin (Android) MobSF (beta) 13.5
Kotlin (General)2 SpotBugs,具有 find-sec-bugs 插件 13.11
Kubernetes manifests Kubesec 12.6
Node.js NodeJsScan 11.1
Objective-C (iOS) MobSF (beta) 13.5
PHP phpcs-security-audit 10.8
Python (pip) bandit 10.3
Python Semgrep 13.9
React ESLint react plugin 12.5
React Semgrep 13.10
Ruby brakeman 13.9
Ruby on Rails brakeman 10.3
Scala2 SpotBugs,具有 find-sec-bugs 插件 11.0 (SBT) & 11.9 (Ant, Gradle, Maven)
Swift (iOS) MobSF (beta) 13.5
TypeScript ESLint security plugin 11.9, merged with ESLint in 13.2
TypeScript Semgrep 13.10
  1. .NET 4 支持有限。分析器在 Linux 容器中运行,并且无法访问特定于 Windows 的库或功能。
  2. 基于 SpotBugs 的分析器支持 AntGradleMavenSBT。它还可以与 Gradle wrapperGrailsMaven 包装器

多项目支持

引入于 13.7 版本。

SAST 可以扫描包含多个项目的仓库。

以下分析器具有多项目支持:

  • Bandit
  • ESLint
  • Gosec
  • Kubesec
  • NodeJsScan
  • MobSF
  • PMD
  • Security Code Scan
  • Semgrep
  • SpotBugs
  • Sobelow

为安全代码扫描启用多项目支持

安全代码扫描中的多项目支持需要仓库根目录中的解决方案 (.sln) 文件。有关解决方案格式的详细信息,请参阅 Microsoft 解决方案 (.sln) 文件

支持的发行版

默认扫描器镜像是在基本 Alpine 镜像的基础上构建的,以确保大小和可维护性。

FIPS-enabled 镜像

引入于 14.10 版本。

极狐GitLab 提供了一个基于 Red Hat UBI 基础镜像的镜像版本,它使用 FIPS 140-验证的密码模块。要使用 FIPS-enabled 的镜像,您可以:

  • SAST_IMAGE_SUFFIX 设置为 -fips
  • -fips 扩展添加到默认图像名称。
variables:
  SAST_IMAGE_SUFFIX: '-fips'

include:
  - template: Security/SAST.gitlab-ci.yml

FIPS-compliant 镜像仅适用于基于 Semgrep 的分析器。

要以 FIPS-compliant 的方式使用 SAST,您必须排除其他分析器运行

使 SAST 分析器可用于所有产品级别

自 13.3 版本起,所有开源 (OSS) 分析器都已移至免费版。

每个级别的功能摘要

不同的产品级别提供不同的功能,如下表所示:

功能 免费版和专业版 旗舰版
配置 SAST 扫描器
自定义 SAST 设置
下载 JSON 报告
在合并请求部件中查看新的发现
管理漏洞
访问安全仪表盘
在 UI 中配置 SAST
自定义 SAST 规则集
检测误报
跟踪移动的漏洞

配置

要为项目配置 SAST,您可以:

手动配置 SAST

要启用 SAST,您必须包括 SAST.gitlab-ci.yml 模板,模板作为极狐GitLab 安装实例的一部分提供。

将以下内容添加到您的 .gitlab-ci.yml 文件中:

include:
  - template: Security/SAST.gitlab-ci.yml

包含的模板在您的 CI/CD 流水线中创建 SAST 作业,并扫描您项目的源代码以查找可能的漏洞。

结果保存为 SAST 报告产物,您可以稍后下载和分析。由于实施限制,我们始终采用可用的最新 SAST 产物。

在 UI 中配置 SAST

您可以使用默认设置或自定义在 UI 中启用和配置 SAST。 您可以使用的方法取决于您的极狐GitLab 产品级别。

在 UI 中使用默认设置 SAST

引入于 13.9 版本。

note配置工具在没有现有 .gitlab-ci.yml 文件或最小配置文件的情况下效果最佳。如果您有一个复杂的极狐GitLab 配置文件,它可能无法解析成功,并且可能会出现错误。

使用默认设置启用和配置 SAST:

  1. 在顶部栏上,选择 菜单 > 项目 并找到您的项目。
  2. 在左侧边栏中,选择 安全与合规 > 配置
  3. 在 SAST 部分中,选择 使用合并请求配置
  4. 查看并合并合并请求,来启用 SAST。

流水线现在包括一个 SAST 作业。

在 UI 中使用自定义配置 SAST

  • 引入于 13.3 版本。
  • 优化于 13.4 版本。
  • 优化于 13.5 版本。
note配置工具在没有现有 .gitlab-ci.yml 文件或最小配置文件的情况下效果最佳。如果您有一个复杂的极狐GitLab 配置文件,它可能无法解析成功,并且可能会出现错误。

要使用自定义启用和配置 SAST:

  1. 在顶部栏上,选择 菜单 > 项目 并找到您的项目。
  2. 在左侧边栏中,选择 安全与合规 > 配置
  3. 如果项目没有 .gitlab-ci.yml 文件,在静态应用程序安全测试(SAST)行选择 启用 SAST,否则选择 配置 SAST
  4. 输入自定义 SAST 值。

    自定义值存储在 .gitlab-ci.yml 文件中。对于不在 SAST 配置页面中的 CI/CD 变量,它们的值继承自 SAST 模板。

  5. 或者,展开 SAST 分析器 部分,选择单个 SAST 分析器并输入自定义分析器值。
  6. 选择 创建合并请求
  7. 查看并合并合并请求。

流水线现在包括一个 SAST 作业。

覆盖 SAST 作业

caution从 13.0 版本开始,不再支持使用 onlyexcept。覆盖模板时,您必须改用 rules

要覆盖作业定义(例如,更改 variablesdependencies 等属性),请声明与要覆盖的 SAST 作业同名的作业。将此新作业放在模板包含之后,并在其下指定任何其他键。例如,为 spotbugs 分析器启用 FAIL_NEVER

include:
  - template: Security/SAST.gitlab-ci.yml

spotbugs-sast:
  variables:
    FAIL_NEVER: 1

固定到镜像小版本

虽然我们的模板使用 MAJOR 版本固定来始终确保提取最新的分析器版本,但在某些情况下,将分析器固定到特定版本可能是有益的。为此,请直接覆盖作业模板中的 SAST_ANALYZER_IMAGE_TAG CI/CD 变量。

在下面的示例中,我们固定到 semgrep 分析器的小版本和 brakeman 分析器的特定补丁版本:

include:
  - template: Security/SAST.gitlab-ci.yml

semgrep-sast:
  variables:
    SAST_ANALYZER_IMAGE_TAG: "2.16"

brakeman-sast:
  variables:
    SAST_ANALYZER_IMAGE_TAG: "2.21.1"

自定义规则集

  • 引入于 13.5 版本。
  • 添加了对透传链的支持。在版本 14.6 中,扩展为包括额外的传递类型的 filegiturl
  • 对覆盖规则的支持添加于 14.8 版本。

您可以自定义我们的 SAST 分析器提供的默认扫描规则。 规则集自定义支持可同时使用的以下内容:

要自定义默认扫描规则,请创建一个包含自定义规则的文件。这些规则被传递到分析器的底层扫描工具。

创建自定义规则集:

  1. 在项目的根目录下创建一个 .gitlab 目录,如果该目录尚不存在。
  2. .gitlab 目录下创建一个名为 sast-ruleset.toml 的自定义规则集文件。

禁用预定义的分析器规则

要禁用分析器规则:

  1. ruleset 部分的上下文中将 disabled 标志设置为 true

  2. 在一个或多个 ruleset.identifier 中,列出您要禁用的规则。每个 ruleset.identifier 都有:

  • 一个 type 字段,用于命名目标分析器使用的预定义规则标识符。
  • 一个 value 字段,用于命名要禁用的规则。
示例:禁用 SAST 分析器的预定义规则

在以下示例中,通过匹配标识符的 typevalue 将禁用的规则分配给 eslintsobelow

[eslint]
  [[eslint.ruleset]]
    disable = true
    [eslint.ruleset.identifier]
      type = "eslint_rule_id"
      value = "security/detect-object-injection"

  [[eslint.ruleset]]
    disable = true
    [eslint.ruleset.identifier]
      type = "cwe"
      value = "185"

[sobelow]
  [[sobelow.ruleset]]
    disable = true
    [sobelow.ruleset.identifier]
      type = "sobelow_rule_id"
      value = "sql_injection"

那些包含提供的类型和值的漏洞现在被禁用,这意味着它们不会显示在合并请求或漏洞报告中。

覆盖预定义的分析器规则

要覆盖分析器规则:

  1. 在一个或多个 ruleset.identifier 中,列出您要覆盖的规则。每个 ruleset.identifier 都有:

    • 一个 type 字段,用于命名目标分析器使用的预定义规则标识符。
    • 一个 value 字段,用于命名要覆盖的规则。
  2. ruleset 部分的 ruleset.override 上下文中,提供要覆盖的键。可以覆盖任何键组合。有效的键是:

    • description
    • message
    • name
    • severity(有效选项为:Critical、High、Medium、Low、Unknown、Info)
示例:覆盖 SAST 分析器的预定义规则

在添加规则集之前,我们通过查看 gl-sast-report.json 来验证哪个漏洞将被覆盖:

"identifiers": [
        {
          "type": "gosec_rule_id",
          "name": "Gosec Rule ID G307",
          "value": "G307"
        },
        {
          "type": "CWE",
          "name": "CWE-703",
          "value": "703",
          "url": "https://cwe.mitre.org/data/definitions/703.html"
        }
      ]

在以下示例中,来自 gosec 的规则由标识符的 typevalue 匹配,然后被覆盖:

[gosec]
  [[gosec.ruleset]]
    [gosec.ruleset.identifier]
        type = "CWE"
        value = "703"
    [gosec.ruleset.override]
      severity = "Critical"

如果发现类型为 CWE 且值为 703 的漏洞,则漏洞严重性将被覆盖为 Critical

合成自定义配置

要创建自定义配置,您可以使用透传链。

透传是透传链中的一个步骤。按顺序评估透传,逐步构建配置。然后将配置传递给目标分析器。

分析器的配置部分具有以下参数:

参数 说明
description 关于分析器配置部分的说明。
targetdir targetdir 参数定义了最终配置所在的目录。如果 targetdir 为空,则分析器使用随机目录。targetdir 的最大大小为 100MB。
validate 如果设置为 true,则验证传递的目标文件(rawfileurl)。验证适用于 yamlxmljsontoml 文件。根据目标文件的扩展名识别正确的验证器。默认情况下,validate 设置为 false
interpolate 如果设置为 true,则启用环境变量插值,以便配置使用 secret/令牌。 我们建议谨慎使用此功能,不要泄露任何 secret。默认情况下,interpolate 设置为 false
timeout 评估透传链的 timeout 设置为 60 秒。如果未设置 timeout,则默认超时为 60 秒。超时不能超过 300 秒。

配置部分可以包括一个或多个透传部分。透传部分的最大数量为 20。 有几种类型的透传:

类型 描述
file 使用 Git 仓库中已有的文件。
raw 提供行内配置。
git 从远端 Git 仓库中提取配置。
url 通过 HTTP 获取分析器配置。

如果在透传链中定义了多个透传部分,则它们在链中的位置定义了它们的评估顺序。

  • 链序列中后面列出的透传具有更高的优先级。
  • 具有更高优先级的透传覆盖(默认)并附加先前透传产生的数据,对于需要使用或修改现有配置的情况很有用。

配置透传的以下参数:

参数 说明
type filerawgiturl 之一。
target 包含透传评估写入的数据的目标文件。如果未提供任何值,则会生成一个随机目标文件。
mode overwrite:如果 target 存在,覆盖文件;append:改为追加到文件。默认值为 overwrite
ref 此选项仅适用于 git 直通类型,并包含要使用的分支名称或 SHA。
subdir 此选项仅适用于 git 直通类型,可用于仅考虑源 Git 仓库的某个子目录。
value 对于 file urlgit 类型,value 定义了文件/Git 仓库的源位置;对于 raw 类型,value 携带要传递的原始内容。
validator 可用于在应用透传后,在目标文件上显式调用验证器(xmlyamljsontoml)。默认情况下,没有设置验证器。

单次透传产生的数据量限制为 1MB。

透传配置示例

nodejs-scan 的原始透传

定义自定义分析器配置。在此示例中,为 nodejs-scan 扫描器定义了自定义规则:

[nodejs-scan]
  description = 'custom ruleset for nodejs-scan'

  [[nodejs-scan.passthrough]]
    type  = "raw"
    value = '''
- nodejs-extensions:
  - .js

  template-extensions:
  - .new
  - .hbs
  - ''

  ignore-filenames:
- skip.js

  ignore-paths:
  - __MACOSX
  - skip_dir
  - node_modules

  ignore-extensions:
  - .hbs

  ignore-rules:
  - regex_injection_dos
  - pug_jade_template
  - express_xss

'''
Gosec 的文件透传

提供包含自定义分析器配置的文件的名称。在本例中,gosec 扫描器的自定义规则包含在 gosec-config.json 文件中:

[gosec]
  description = 'custom ruleset for gosec'

  [[gosec.passthrough]]
    type  = "file"
    value = "gosec-config.json"
Semgrep 的透传链

在下面的示例中,我们在 /sgrules 目标目录下生成一个自定义配置,总 timeout 为 60 秒。

几种透传类型为目标分析器生成配置:

  • 两个 git 透传部分从 myrules Git 仓库中提取分支refs/remotes/origin/test 的头部,并从sast-rules Git 仓库中提取 revision 97f7686。在 sast-rules Git 仓库中,仅考虑来自 go 子目录的数据。
    • sast-rules 条目具有更高的优先级,因为它稍后出现在配置中。
    • 如果两个仓库中的文件之间存在文件名冲突,则来自 sast 仓库的文件会覆盖来自 myrules 仓库的文件,因为 sast-rules 具有更高的优先级。
  • raw 条目在 /sgrules 下创建一个名为 insecure.yml 的文件。完整路径是 /sgrules/insecure.yml
  • url 条目获取通过 URL 提供的配置并将其存储在 /sgrules/gosec.yml 文件中。

之后,使用位于 /sgrules 下的最终配置调用 Semgrep。

[semgrep]
  description = 'semgrep custom rules configuration'
  targetdir = "/sgrules"
  timeout = 60

  [[semgrep.passthrough]]
    type  = "git"
    value = "https://gitlab.com/user/myrules.git"
    ref = "refs/remotes/origin/test"

  [[semgrep.passthrough]]
    type  = "git"
    value = "https://gitlab.com/gitlab-org/secure/gsoc-sast-vulnerability-rules/playground/sast-rules.git"
    ref = "97f7686db058e2141c0806a477c1e04835c4f395"
    subdir = "go"

  [[semgrep.passthrough]]
    type  = "raw"
    target = "insecure.yml"
    value = """
rules:
- id: "insecure"
  patterns:
  - pattern: "func insecure() {...}"
  message: |
    Insecure function insecure detected
  metadata:
    cwe: "CWE-200: Exposure of Sensitive Information to an Unauthorized Actor"
  severity: "ERROR"
  languages:
  - "go"
    """

  [[semgrep.passthrough]]
    type  = "url"
    value = "https://semgrep.dev/c/p/gosec"
    target = "gosec.yml"
插值

下面的代码片段显示了一个示例配置,该配置使用环境变量 $GITURL 通过 Git URL 访问私有仓库。该变量在 value 字段中包含用户名和令牌(例如 https://user:token@url)。 它不会在配置文件中明确地存储凭据。为了降低通过创建的路径和文件泄露机密的风险,请谨慎使用此功能。

[semgrep]
  description = 'semgrep custom rules configuration'
  targetdir = "/sgrules"
  interpolate = true

  [[semgrep.passthrough]]
    type  = "git"
    value = "$GITURL"
    ref = "refs/remotes/origin/main"
为透传配置附加模式

要将数据附加到先前的传递,请对传递类型 fileurlraw 使用 append 模式。

override 模式下的透传会覆盖链中前面的透传发现命名冲突时创建的文件。如果 mode 设置为 append,则透传会将数据附加到其前身创建的文件中,而不是覆盖。

在下面的 Semgrep 配置中,/sgrules/insecure.yml 组装了两个透传。规则是:

  • insecure
  • secret

这些规则将搜索模式添加到分析器并扩展 Semgrep 功能。

对于透传链,我们建议您启用验证。要启用验证,您可以:

  • validate 设置为 true

  • 将透传 validator 设置为 xmljsonyamltoml

[semgrep]
  description = 'semgrep custom rules configuration'
  targetdir = "/sgrules"
  validate = true

  [[semgrep.passthrough]]
    type  = "raw"
    target = "insecure.yml"
    value = """
rules:
- id: "insecure"
  patterns:
  - pattern: "func insecure() {...}"
  message: |
    Insecure function insecure detected
  metadata:
    cwe: "...
  severity: "ERROR"
  languages:
  - "go"
"""

  [[semgrep.passthrough]]
    type  = "raw"
    mode  = "append"
    target = "insecure.yml"
    value = """
- id: "secret"
  patterns:
  - pattern-either:
    - pattern: "$MASK = \"...\""
  - metavariable-regex:
      metavariable: "$MASK"
      regex: "(password|pass|passwd|pwd|secret|token)"
  message: |
    Use of Hard-coded Password
    cwe: "..."
  severity: "ERROR"
  languages:
  - "go"
"""

误报检测

引入于 14.2 版本。

已检测到且为误报的漏洞将在安全仪表板中标记为误报。

支持的语言分析器的子集提供了误报检测:

  • Ruby,在基于 Brakeman 的分析器中

高级漏洞跟踪

引入于 14.2 版本。

源代码易变;随着开发人员进行更改,源代码可能会在文件内或文件之间移动。 安全分析器可能已经报告了漏洞报告中正在跟踪的漏洞。 这些漏洞与特定的有问题的代码片段相关联,以便可以找到并修复它们。 如果代码片段在移动时没有被可靠地跟踪,则漏洞管理会更加困难,因为可能会再次报告相同的漏洞。

SAST 使用先进的漏洞跟踪算法来更准确地识别由于重构或无关更改而在文件中移动的相同漏洞。

高级漏洞跟踪可用于支持的语言分析器的子集:

  • C,仅在基于 Semgrep 的分析器中
  • Go,在基于 Gosec 和 Semgrep 的分析器中
  • Java,仅在基于 Semgrep 的分析器中
  • JavaScript,仅在基于 Semgrep 的分析器中
  • Python,仅在基于 Semgrep 的分析器中
  • Ruby,在基于 Brakeman 的分析器中

使用 CI/CD 变量为私有仓库传递凭据

一些分析器需要下载项目的依赖项才能执行分析。反过来,此类依赖项可能存在于私有 Git 仓库中,因此需要用户名和密码等凭据才能下载它们。根据分析器的不同,可以通过自定义 CI/CD 变量向其提供此类凭据。

使用 CI/CD 变量将用户名和密码传递给私有 Go 仓库

如果您的 Go 项目依赖于私有模块,请参阅从私有项目中获取模块,了解如何通过 HTTPS 提供身份验证。

要通过 ~/.netrc 指定凭据,请提供包含以下内容的 before_script

gosec-sast:
  before_script:
    - |
      cat <<EOF > ~/.netrc
      machine gitlab.com
      login $CI_DEPLOY_USER
      password $CI_DEPLOY_PASSWORD
      EOF

使用 CI/CD 变量将用户名和密码传递给私有 Maven 仓库

如果您的私有 Maven 仓库需要登录凭据,您可以使用 MAVEN_CLI_OPTS CI/CD 变量。

启用 Kubesec 分析器

您需要将 SCAN_KUBERNETES_MANIFESTS 设置为 "true",来启用 Kubesec 分析器。在 .gitlab-ci.yml 中,定义:

include:
  - template: Security/SAST.gitlab-ci.yml

variables:
  SCAN_KUBERNETES_MANIFESTS: "true"

预编译

大多数 SAST 分析器直接扫描您的源代码,而无需先编译它。 但是,出于技术原因,一些分析器只能扫描编译后的代码。

默认情况下,这些分析器会自动尝试获取依赖项并编译您的代码,以便对其进行扫描。如果出现以下情况,自动编译可能会失败:

  • 您的项目需要自定义构建配置。
  • 您使用分析器中未内置的语言版本。

要解决这些问题,您可以跳过分析器的编译步骤,而是直接提供流水线早期阶段的产物。这种策略称为预编译

预编译可用于支持 COMPILE CI/CD 变量的分析器。 有关当前列表,请参阅分析器设置

要使用预编译:

  1. 将项目的依赖输出到项目工作目录中的一个目录,然后通过设置 artifacts:paths 配置,将该目录保存为产物。
  2. 向分析器提供 COMPILE: "false" CI/CD 变量,禁用自动编译。
  3. 将您的编译阶段添加为分析器作业的依赖项。

要允许分析器识别编译的产物,您必须明确指定 vendored 目录的路径。 此配置可能因分析仪而异。对于 Maven 项目,您可以使用 MAVEN_REPO_PATH。 有关可用选项的完整列表,请参阅分析器设置

以下示例预编译了一个 Maven 项目并将其提供给 SpotBugs SAST 分析器:

stages:
  - build
  - test

include:
  - template: Security/SAST.gitlab-ci.yml

build:
  image: maven:3.6-jdk-8-slim
  stage: build
  script:
    - mvn package -Dmaven.repo.local=./.m2/repository
  artifacts:
    paths:
      - .m2/
      - target/

spotbugs-sast:
  dependencies:
    - build
  variables:
    MAVEN_REPO_PATH: ./.m2/repository
    COMPILE: "false"
  artifacts:
    reports:
      sast: gl-sast-report.json

可用的 CI/CD 变量

可以使用 .gitlab-ci.yml 中的 variables 参数配置 SAST。

caution在将这些更改合并到默认分支之前,应在合并请求中测试极狐GitLab 安全扫描工具的所有自定义。不这样做会产生意想不到的结果,包括大量误报。

以下示例包含用于将 SAST_GOSEC_LEVEL 变量覆盖为 2 的 SAST 模板。模板是之前评估的流水线配置,因此最后提及的变量优先。

include:
  - template: Security/SAST.gitlab-ci.yml

variables:
  SAST_GOSEC_LEVEL: 2

日志级别

引入于 13.1 版本。

要控制日志的详细程度,请设置 SECURE_LOG_LEVEL 环境变量。输出此日志级别或更高级别的消息。

从最高到最低严重性,日志记录级别是:

  • fatal
  • error
  • warn
  • info(默认)
  • debug

自定义证书颁发机构

要信任自定义证书颁发机构,请将 ADDITIONAL_CA_CERT_BUNDLE 变量设置为您希望在 SAST 环境中信任的 CA 证书包。ADDITIONAL_CA_CERT_BUNDLE 值应包含 X.509 PEM 公钥证书的文本表示形式。例如,要在 .gitlab-ci.yml 文件中配置此值,请使用以下命令:

variables:
  ADDITIONAL_CA_CERT_BUNDLE: |
      -----BEGIN CERTIFICATE-----
      MIIGqTCCBJGgAwIBAgIQI7AVxxVwg2kch4d56XNdDjANBgkqhkiG9w0BAQsFADCB
      ...
      jWgmPqF3vUbZE0EyScetPJquRFRKIesyJuBFMAs=
      -----END CERTIFICATE-----

ADDITIONAL_CA_CERT_BUNDLE 值也可以配置为 UI 中的自定义变量,或者配置为 file,它需要证书的路径;或者作为变量,它需要证书的文本表示。

Docker 镜像

以下是 Docker 镜像相关的 CI/CD 变量。

CI/CD 变量 描述
SECURE_ANALYZERS_PREFIX 覆盖提供默认镜像(代理)的 Docker 镜像库的名称。阅读有关自定义分析器的更多信息。
SAST_EXCLUDED_ANALYZERS 不应运行的默认镜像的名称。阅读有关自定义分析器的更多信息。
SAST_ANALYZER_IMAGE_TAG 覆盖默认版本的分析器镜像。阅读更多关于固定分析器镜像版本
SAST_IMAGE_SUFFIX 添加到镜像名称的后缀。如果设置为 -fips,则使用 FIPS-enabled 镜像进行扫描。有关详细信息,请参阅FIPS-enabled 镜像。引入于 14.10 版本。

漏洞过滤器

一些分析器可以过滤掉特定阈值下的漏洞。

CI/CD 变量 默认值 描述
SAST_EXCLUDED_PATHS spec, test, tests, tmp 根据路径从输出中排除漏洞。这是一个逗号分隔的模式列表。Patterns 可以是 glob、文件或文件夹路径(例如,doc、spec)。父目录也匹配模式。您可能需要排除构建工具使用的临时目录,因为这些可能会产生误报。要排除路径,请复制并粘贴默认排除路径,然后添加您自己的要排除的路径。如果您未指定默认排除路径,您将覆盖默认值,并且只有您指定的路径将从 SAST 扫描中排除。
SEARCH_MAX_DEPTH 4 SAST 搜索仓库,检测使用的编程语言,并选择匹配的分析器。设置 SEARCH_MAX_DEPTH 的值来指定搜索阶段应该跨越多少个目录级别。选择分析器后,将分析整个仓库。
SAST_BANDIT_EXCLUDED_PATHS   要从扫描中排除的路径的逗号分隔列表。使用 Python 的 fnmatch 语法;例如:'*/tests/*, */venv/*'
SAST_BRAKEMAN_LEVEL 1 在给定的置信水平下忽略 Brakeman 漏洞。整数,1=低 3=高。
SAST_FLAWFINDER_LEVEL 1 忽略给定风险级别下的 Flawfinder 漏洞。整数,0=无风险,5=高风险。
SAST_GOSEC_LEVEL 0 在给定的置信水平下忽略 Gosec 漏洞。整数,0=未定义,1=低,2=中,3=高。

分析器设置

一些分析器可以使用 CI/CD 变量进行自定义。

CI/CD 变量 分析器 描述
SCAN_KUBERNETES_MANIFESTS Kubesec 设置为 true,扫描 Kubernetes 清单。
KUBESEC_HELM_CHARTS_PATH Kubesec helm 用于生成 kubesec 扫描的 Kubernetes 清单的 Helm chart 的可选路径。 如果定义了依赖项,则应该在 before_script 中运行 helm dependency build 以获取必要的依赖项。
KUBESEC_HELM_OPTIONS Kubesec helm 可执行文件的附加参数。
COMPILE Gosec, SpotBugs 设置为 false 以禁用项目编译和依赖项获取。SpotBugs 分析器引入于 13.1 版本,Gosec 分析器引入于 14.0 版本。
ANT_HOME SpotBugs ANT_HOME 变量。
ANT_PATH SpotBugs ant 可执行文件的路径。
GRADLE_PATH SpotBugs gradle 可执行文件的路径。
JAVA_OPTS SpotBugs java 可执行文件的附加参数。
JAVA_PATH SpotBugs java 可执行文件的路径。
SAST_JAVA_VERSION SpotBugs 使用哪个 Java 版本。从 15.0 版本开始,支持的版本是 1117(默认)。在 15.0 版本之前,支持的版本是 8(默认)和 11
MAVEN_CLI_OPTS SpotBugs mvnmvnw 可执行文件的附加参数。
MAVEN_PATH SpotBugs mvn 可执行文件的路径。
MAVEN_REPO_PATH SpotBugs Maven 本地仓库的路径(maven.repo.local 属性的快捷方式)。
SBT_PATH SpotBugs sbt 可执行文件的路径。
FAIL_NEVER SpotBugs 设置为 1,可以忽略编译失败。
SAST_GOSEC_CONFIG Gosec caution 删除于 14.0 版本 - 改用自定义规则集。Gosec 的配置路径(可选)。
PHPCS_SECURITY_AUDIT_PHP_EXTENSIONS phpcs-security-audit 逗号分隔的附加 PHP 扩展列表。
SAST_DISABLE_BABEL NodeJsScan caution 删除于 13.5 版本。
SAST_SEMGREP_METRICS Semgrep 设置为 false,禁用向 r2c 发送匿名扫描指标。默认值:true

自定义 CI/CD 变量

除了上述 SAST 配置 CI/CD 变量之外,如果使用 SAST 供应模板,所有自定义变量都会传播到底层 SAST 分析器镜像。

note在 13.3 及更早版本中,名称以以下前缀开头的变量不会传播到分析器容器或 SAST Docker 容器:DOCKER_CIGITLAB_FF_HOMEPWDOLDPWDPATHSHLVLHOSTNAME

报告 JSON 格式

SAST 以 JSON 格式输出报告文件。报告文件包含所有发现的漏洞的详细信息。 要下载报告文件,您可以:

  • 从 CI/CD 流水线页面下载文件。
  • 在合并请求的流水线选项卡中,将 artifacts: paths 设置为 gl-sast-report.json

有关信息,请参阅下载作业产物

在 SELinux 中运行 SAST

默认情况下,托管在 SELinux 上的实例支持 SAST 分析器。在被覆盖的 SAST 作业中添加 before_script 可能不起作用,因为托管在 SELinux 上的 runner 权限受限。

故障排除

SAST 调试日志记录

将全局 CI 变量中的安全扫描器日志详细程度调整到 debug,以帮助排除 SAST 作业的故障。

variables:
  SECURE_LOG_LEVEL: "debug"

Error response from daemon: error processing tar file: docker-tar: relocation error

当运行 SAST 作业的 Docker 版本为 19.03.0 时会出现此错误。考虑更新到 Docker 19.03.1 或更高版本。旧版本不受影响。

收到警告信息 gl-sast-report.json: no matching files

有关这方面的信息,请参阅一般应用程序安全故障排除部分

使用 rules:exists 的限制

SAST CI 模板使用rules:exists参数。出于性能原因,针对给定的 glob 模式进行最大匹配数。 果匹配数超过最大值,则 rules:exists 参数返回 true。根据仓库中的文件数量,即使扫描程序不支持您的项目,也可能会触发 SAST 作业。有关此问题的更多详细信息,请参阅 rules:exists 文档

SpotBugs UTF-8 无法映射的字符错误

当 SpotBugs 构建中未启用 UTF-8 编码并且源代码中有 UTF-8 字符时,会发生这些错误。要修复此错误,请为项目的构建工具启用 UTF-8。

对于 Gradle 构建,将以下内容添加到您的 build.gradle 文件中:

compileJava.options.encoding = 'UTF-8'
tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
}

对于 Maven 构建,将以下内容添加到您的 pom.xml 文件中:

<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

SpotBugs Error: Project couldn't be built

如果您的作业在构建步骤中失败并显示 Project couldn't be built 消息,这很可能是因为您的作业要求 SpotBugs 使用不属于其默认工具的工具进行构建。

解决方案是使用预编译。预编译确保 SpotBugs 所需的图像在作业的容器中可用。

Flawfinder 编码错误

当 Flawfinder 遇到无效的 UTF-8 字符时会发生这种情况。要解决此问题,请将项目中的所有源代码转换为 UTF-8 字符编码。可以通过 cvt2utficonv,在整个项目或每个作业中使用 before_script 功能。

Semgrep 缓慢、意外结果或其他错误

如果 Semgrep 速度慢、报告太多误报或误报、崩溃、失败或以其他方式损坏,请参阅 Semgrep 文档以了解如何进行故障排除