自定义规则集
- 引入于 13.5 版本。
- 添加了对透传链的支持。在版本 14.6 中,扩展为包括额外的传递类型的
file
、git
和url
。- 对覆盖规则的支持添加于 14.8 版本。
您可以自定义我们的 SAST 分析器提供的默认扫描规则。 规则集自定义支持可同时使用的以下内容:
- 禁用预定义规则。适用于所有分析器。
- 覆盖预定义规则。适用于所有分析器。
- 通过合成并传递自定义配置,修改特定分析器的默认行为。仅适用于
nodejs-scan
、gosec
和semgrep
。
要自定义默认扫描规则,请创建一个包含自定义规则的文件。这些规则被传递到分析器的底层扫描工具。
创建自定义规则集:
- 在项目的根目录下创建一个
.gitlab
目录,如果该目录尚不存在。 - 在
.gitlab
目录下创建一个名为sast-ruleset.toml
的自定义规则集文件。
禁用预定义的分析器规则
要禁用分析器规则:
-
在
ruleset
部分的上下文中将disabled
标志设置为true
。 -
在一个或多个
ruleset.identifier
中,列出您要禁用的规则。每个ruleset.identifier
都有:
- 一个
type
字段,用于命名目标分析器使用的预定义规则标识符。 - 一个
value
字段,用于命名要禁用的规则。
示例:禁用 SAST 分析器的预定义规则
在以下示例中,通过匹配标识符的 type
和 value
将禁用的规则分配给 eslint
和 sobelow
:
[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"
那些包含提供的类型和值的漏洞现在被禁用,这意味着它们不会显示在合并请求或漏洞报告中。
覆盖预定义的分析器规则
要覆盖分析器规则:
-
在一个或多个
ruleset.identifier
中,列出您要覆盖的规则。每个ruleset.identifier
都有:- 一个
type
字段,用于命名目标分析器使用的预定义规则标识符。 - 一个
value
字段,用于命名要覆盖的规则。
- 一个
-
在
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
的规则由标识符的 type
和 value
匹配,然后被覆盖:
[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 ,则验证传递的目标文件(raw 、file 和 url )。验证适用于 yaml 、xml 、json 和 toml 文件。根据目标文件的扩展名识别正确的验证器。默认情况下,validate 设置为 false 。
|
interpolate
| 如果设置为 true ,则启用环境变量插值,以便配置使用 secret/令牌。 我们建议谨慎使用此功能,不要泄露任何 secret。默认情况下,interpolate 设置为 false 。
|
timeout
| 评估透传链的 timeout 设置为 60 秒。如果未设置 timeout ,则默认超时为 60 秒。超时不能超过 300 秒。
|
配置部分可以包括一个或多个透传部分。透传部分的最大数量为 20。 有几种类型的透传:
类型 | 描述 |
---|---|
file
| 使用 Git 仓库中已有的文件。 |
raw
| 提供行内配置。 |
git
| 从远端 Git 仓库中提取配置。 |
url
| 通过 HTTP 获取分析器配置。 |
如果在透传链中定义了多个透传部分,则它们在链中的位置定义了它们的评估顺序。
- 链序列中后面列出的透传具有更高的优先级。
- 具有更高优先级的透传覆盖(默认)并附加先前透传产生的数据,对于需要使用或修改现有配置的情况很有用。
配置透传的以下参数:
参数 | 说明 |
---|---|
type
|
file 、raw 、git 或 url 之一。
|
target
| 包含透传评估写入的数据的目标文件。如果未提供任何值,则会生成一个随机目标文件。 |
mode
|
overwrite :如果 target 存在,覆盖文件;append :改为追加到文件。默认值为 overwrite 。
|
ref
| 此选项仅适用于 git 直通类型,并包含要使用的分支名称或 SHA。使用分支名称时,请以 refs/heads/<branch> 的形式指定,而不是 refs/remotes/<remote_name>/<branch> 。
|
subdir
| 此选项仅适用于 git 直通类型,可用于仅考虑源 Git 仓库的某个子目录。
|
value
| 对于 file 、url 和 git 类型,value 定义了文件/Git 仓库的源位置;对于 raw 类型,value 携带要传递的原始内容。
|
validator
| 可用于在应用透传后,在目标文件上显式调用验证器(xml 、yaml 、json 、toml )。默认情况下,没有设置验证器。
|
单次透传产生的数据量限制为 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/heads/test
的头部,并从sast-rules
Git 仓库中提取 revision97f7686
。在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/heads/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/heads/main"
为透传配置附加模式
要将数据附加到先前的传递,请对传递类型 file
、url
和 raw
使用 append
模式。
override
模式下的透传会覆盖链中前面的透传发现命名冲突时创建的文件。如果 mode
设置为 append
,则透传会将数据附加到其前身创建的文件中,而不是覆盖。
在下面的 Semgrep 配置中,/sgrules/insecure.yml
组装了两个透传。规则是:
insecure
secret
这些规则将搜索模式添加到分析器并扩展 Semgrep 功能。
对于透传链,我们建议您启用验证。要启用验证,您可以:
-
将
validate
设置为true
-
将透传
validator
设置为xml
、json
、yaml
或toml
。
[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"
"""