ルールセットのカスタマイズ
スキャンするリポジトリにルールセット設定ファイルを定義することで、SASTアナライザーの動作をカスタマイズすることができます。カスタマイズには2種類あります:
- 定義済みルールの動作の変更。これには以下が含まれます:
- パススルーを使用してカスタム設定を合成することにより、定義済みのルールを置き換えます。nodejs-scanとsemgrepでのみ利用可能です。
定義済みルールの無効化
どの SAST アナライザでも、定義済みのルールを無効にすることができます。
ルールを無効にすると
- ほとんどのアナライザは脆弱性のスキャンを継続します。スキャン結果は、スキャン完了後の処理ステップとして削除され、
gl-sast-report.json
アーティファクトには表示されません。 - 無効化されたルールの検出結果は、パイプラインセキュリティタブに表示されなくなります。
- デフォルトブランチの無効化されたルールの既存の検出結果は、脆弱性レポートに「検出されなくなりました」と表示されます。
Semgrepベースのアナライザでは、無効化されたルールの処理が異なります:
- パフォーマンスを向上させるため、Semgrepベースの解析器は無効化されたルールをまったくスキャンしません。
- Semgrepベースのアナライザでルールを無効にすると、
sast-ruleset.toml
ファイルをデフォルトのブランチにマージした後、そのルールに対する既存の脆弱性発見が自動的に解決されます。
この動作の設定方法については、「スキーマ」および「例」のセクションを参照してください。
定義済みルールの上書き
定義済みルールの特定の属性は、どのSAST分析ツールでも上書きすることができます。これは、SASTを既存のワークフローやツールに適合させる場合に便利です。例えば、組織のポリシーに基づいて脆弱性の深刻度を上書きしたり、脆弱性レポートに表示するメッセージを別のものにしたりすることができます。
この動作の設定方法については、「スキーマ」および「例」のセクションを参照してください。
カスタム設定の合成
SASTアナライザによっては、事前に定義されたルールを完全に置き換えることができます:
- nodejs-scan- デフォルトのnjsscan設定ファイルを独自のファイルで置き換えることができます。
- semgrep-GitLabでメンテナンスされているルールセットをあなたのルールセットで置き換えることができます。
パススルーを通してカスタマイズを提供し、実行時にパススルーチェーンにComposerされ、完全な設定を生成するために評価されます。その後、基礎となるスキャナがこの新しい設定に対して実行されます。
複数のパススルー・タイプがあり、リポジトリにコミットされたファイルやルールセット設定ファイルのインラインを使用するなど、さまざまな方法で設定を提供できます。また、チェーン内の後続のパススルーをどのように扱うかを選択することもできます。
この動作の設定方法については、「スキーマ」および「例」のセクションを参照してください。
設定ファイルの作成
ルールセット設定ファイルを作成します:
- プロジェクトのルートに
.gitlab
ディレクトリを作成します(まだ存在しない場合)。 -
.gitlab
ディレクトリにsast-ruleset.toml
という名前のファイルを作成します。
リモート設定ファイルの指定
16.1で導入されました。
CI/CD変数に、現在のリポジトリの外に保存されているルールセット設定ファイルを使用するように設定できます。これは、複数のプロジェクトに同じルールを適用するのに役立ちます。
SAST_RULESET_GIT_REFERENCE
変数では、Git URL に似た書式でプロジェクト URI、オプションの認証、オプションの Git SHA を指定します。変数の書式は次のとおりです:
[<AUTH_USER>[:<AUTH_PASSWORD>]@]<PROJECT_PATH>[@<GIT_SHA>]
.gitlab/sast-ruleset.toml
のファイルがコミットされている場合は、そのローカル設定が優先され、SAST_RULESET_GIT_REFERENCE
のファイルは使われません。次の例では、SAST を有効にし、共有ルールセットカスタマイズファイルを使用します。この例では、ファイルはexample-ruleset-project
のデフォルトブランチのパス.gitlab/sast-ruleset.toml
にコミットされます。
include:
- template: Jobs/SAST.gitlab-ci.yml
variables:
SAST_RULESET_GIT_REFERENCE: "gitlab.com/example-group/example-ruleset-project"
高度な使用方法については、非公開リモート設定の例を参照してください。
スキーマ
トップレベルのセクション
トップレベル・セクションには、TOML テーブルとして定義された 1 つ以上の_設定セクションが_含まれます。
設定 | 説明 |
---|---|
[$analyzer] | 解析器の設定セクションを宣言します。名前は、SAST アナライザのリストで定義されているスネークケース名に従います。 |
設定例:
[semgrep]
...
既存のルールを変更する設定セクションを作成_したり、_カスタムルールセットを合成したりすることは避けてください。
[$analyzer]
設定セクション
[$analyzer]
セクションでは、解析器の動作をカスタマイズできます。有効なプロパティは設定の種類によって異なります。
設定 | 適用対象 | 説明 |
---|---|---|
[[$analyzer.ruleset]] | 定義済みルール | 既存のルールの変更を定義します。 |
interpolate | 全て |
true に設定すると、設定内で$VAR を使って環境変数を評価することができます。この機能は、シークレットやトークンを漏らさないように注意して使用してください。 (デフォルト:false ) |
description | パススルー | カスタムルールセットの説明 |
targetdir | パススルー | 最終的な設定を保存するディレクトリ。空の場合、ランダムな名前のディレクトリが作成されます。このディレクトリには最大 100 MB のファイルを置くことができます。 |
validate | パススルー |
true に設定すると、各パススルーの内部が検証されます。バリデーションはyaml ,xml ,json およびtoml の内容に対して動作します。適切なバリデータは、[[$analyzer.passthrough]] セクションのtarget パラメータで使用する拡張子をもとに決定されます。(デフォルト:false ) |
timeout | パススルー | タイムアウトするまでの、パススルー・チェーンの評価に費やす最大時間。タイムアウトは300秒を超えることはできません。(デフォルト: 60) |
interpolate
以下の例は、$GITURL
環境変数を使って非公開リポジトリにアクセスする設定です。この変数にはユーザー名とトークン(例えばhttps://user:token@url
)が含まれており、設定ファイルには明示的に格納されていません。
[semgrep]
description = "My private Semgrep ruleset"
interpolate = true
[[semgrep.passthrough]]
type = "git"
value = "$GITURL"
ref = "main"
[[$analyzer.ruleset]]
セクション
[[$analyzer.ruleset]]
セクションは、事前に定義された 1 つのルールを対象とし、変更します。このセクションは、アナライザごとに 1 つから複数まで定義できます。
設定 | 説明 |
---|---|
disable | ルールを無効にするかどうか。(デフォルト:false ) |
[$analyzer.ruleset.identifier] | 変更する定義済みルールを選択します。 |
[$analyzer.ruleset.override] | ルールのオーバーライドを定義します。 |
設定例:
[semgrep]
[[semgrep.ruleset]]
disable = true
...
[$analyzer.ruleset.identifier]
セクション
[$analyzer.ruleset.identifier]
セクションでは、変更したい定義済みルールの識別子を定義します。
設定 | 説明 |
---|---|
type | 定義済みルールで使用される識別子のタイプ。 |
value | 定義済みルールで使用される識別子の値。 |
type
、value
の正しい値は、アナライザが生成するgl-sast-report.json
を参照することで調べることができます。このファイルは、アナライザのCIジョブからジョブのアーティファクトとしてダウンロードできます。
たとえば、以下のスニペットは、3つの識別子を持つsemgrep
ルールの検出結果を示しています。JSONオブジェクトのtype
およびvalue
キーは、このセクションで指定する値に対応します。
...
"vulnerabilities": [
{
"id": "7331a4b7093875f6eb9f6eb1755b30cc792e9fb3a08c9ce673fb0d2207d7c9c9",
"category": "sast",
"message": "Key Exchange without Entity Authentication",
"description": "Audit the use of ssh.InsecureIgnoreHostKey\n",
...
"identifiers": [
{
"type": "semgrep_id",
"name": "gosec.G106-1",
"value": "gosec.G106-1"
},
{
"type": "cwe",
"name": "CWE-322",
"value": "322",
"url": "https://cwe.mitre.org/data/definitions/322.html"
},
{
"type": "gosec_rule_id",
"name": "Gosec Rule ID G106",
"value": "G106"
}
]
}
...
]
...
設定例:
[semgrep]
[[semgrep.ruleset]]
[semgrep.ruleset.identifier]
type = "semgrep_id"
value = "gosec.G106-1
...
[$analyzer.ruleset.override]
セクション
[$analyzer.ruleset.override]
セクションでは、定義済みのルールの属性を上書きできます。
設定 | 説明 |
---|---|
description | イシューの詳細。 |
message | (非推奨) イシューの説明。 |
name | ルールの名前。 |
severity | ルールの重大度。有効なオプションは以下のとおり:Critical High ,Medium ,Low ,Unknown ,Info ) です。 |
設定例:
[semgrep]
[[semgrep.ruleset]]
[semgrep.ruleset.override]
severity = "Critical"
name = "Command injection"
...
[[$analyzer.passthrough]]
セクション
nodejs-scan
およびsemgrep
アナライザーのみでサポートされています。[[$analyzer.passthrough]]
セクションでは、アナライザーのカスタム設定を合成できます。このセクションは、1つのアナライザにつき最大20個まで定義できます。パススルーは_パススルー・チェーンに_Composer され、アナライザの定義済みルールを置き換える完全な設定に評価されます。
パススルーは順番に評価されます。チェーンの後半に記載されているパススルーの優先順位が高くなり、前のパススルーによって生成されたデータを上書きまたは追加できます (mode
に依存)。これは、既存の設定を使用または変更する必要がある場合に便利です。
単一のパススルーによって生成されるデータ量は、1 MB に制限されています。
設定 | 適用対象 | 説明 |
---|---|---|
type | 全て |
file ,raw ,git ,url のいずれか。 |
target | 全て | パススルー評価によって書き込まれるデータを格納するターゲット・ファイル。空の場合、ランダムなファイル名が使用されます。 |
mode | 全て |
overwrite の場合、target ファイルは上書きされます。append の場合、新しい内容がtarget ファイルに追加されます。git タイプはoverwrite . overwrite NET のみサポートしています。 |
ref | type = "git" | ブランチ、タグ、またはプルする SHA の名前をコンテナで指定します。 |
subdir | type = "git" | Git リポジトリのサブディレクトリを設定ソースとして選択します。 |
value | 全て |
file ,url ,git タイプの場合、ファイルまたは Git リポジトリの場所を定義します。raw タイプの場合、インライン設定がコンテナに含まれます。 |
validator | 全て | パススルーの評価後に、ターゲットファイルに対してバリデータ (xml ,yaml ,json ,toml ) を明示的に起動するために使用します。 |
パススルーの型
種類 | 説明 |
---|---|
file | Git リポジトリに存在するファイルを使用します。 |
raw | 設定をインラインで提供します。 |
git | リモートの Git リポジトリから設定を取り込みます。 |
url | HTTPを使って設定を取得します。 |
raw
パススルーを使う場合、sast-ruleset.toml
ファイルのインデントをすべて空白にすることを推奨します。YAML の仕様ではタブよりもスペースが必須であり、インデントが適切に表現されないとアナライザーはカスタムルールセットの解析に失敗します。使用例
SASTアナライザの定義済みルールを無効にします。
以下のカスタムルールセット設定では、以下のルールがレポートから除外されます:
-
semgrep
semgrep_id
がgosec.G106-1
またはcwe
が322
のルール。 -
sobelow
sobelow_rule_id
がsql_injection
の規則。 -
flawfinder
flawfinder_func_name
がmemcpy
の規則。
[semgrep]
[[semgrep.ruleset]]
disable = true
[semgrep.ruleset.identifier]
type = "semgrep_id"
value = "gosec.G106-1"
[[semgrep.ruleset]]
disable = true
[semgrep.ruleset.identifier]
type = "cwe"
value = "322"
[sobelow]
[[sobelow.ruleset]]
disable = true
[sobelow.ruleset.identifier]
type = "sobelow_rule_id"
value = "sql_injection"
[flawfinder]
[[flawfinder.ruleset]]
disable = true
[flawfinder.ruleset.identifier]
type = "flawfinder_func_name"
value = "memcpy"
SASTアナライザの定義済みルールのオーバーライド
以下のカスタムルールセット設定では、semgrep
で検出された脆弱性で、タイプがCWE
で、値が322
の場合、深刻度がCritical
に上書きされます。
[semgrep]
[[semgrep.ruleset]]
[semgrep.ruleset.identifier]
type = "cwe"
value = "322"
[semgrep.ruleset.override]
severity = "Critical"
の生のパススルーを使用して、カスタム設定を合成します。nodejs-scan
以下のカスタムルールセット設定により、nodejs-scan
アナライザーの定義済みの動作がカスタム設定に置き換えられます。
value
、njsscan configフォーマットに従った構文が使用されます。
[nodejs-scan]
description = "My 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
'''
のファイル・パススルーを使用してカスタム設定を合成します。semgrep
次のカスタムルールセット設定により、semgrep
アナライザーの事前定義されたルールセットが、スキャン対象のリポジトリ内のmy-semgrep-rules.yaml
というファイルに含まれるカスタムルールセットで置き換えられます。
# my-semgrep-rules.yml
---
rules:
- id: my-custom-rule
pattern: print("Hello World")
message: |
Unauthorized use of Hello World.
severity: ERROR
languages:
- python
[semgrep]
description = "My custom ruleset for Semgrep"
[[semgrep.passthrough]]
type = "file"
value = "my-semgrep-rules.yml"
のパススルーチェーンを使用してカスタム設定を合成します。semgrep
以下のカスタム・ルールセット設定では、semgrep
アナライザの定義済みルールセットが、4 つのパススルーのチェーンを評価することによって生成されるカスタム・ルールセットに置き換えられます。各パススルーは、コンテナ内の/sgrules
ディレクトリに書き込まれるファイルを生成します。Gitリモートが応答しない場合に備えて、timeout
60秒が設定されています。
この例では、さまざまなパススルーのタイプを示します:
-
git
最初のブランチはmyrules
Git リポジトリからdevelop
ブランチを、2 番目のブランチはsast-rules
リポジトリから97f7686
リビジョンを取得し、go
サブディレクトリのファイルのみを対象とします。-
sast-rules
のエントリのほうが優先順位が高いのは、設定の後半に現れるからです。 - 2つのチェックアウトの間でファイル名が衝突すると、
sast-rules
リポジトリのファイルがmyrules
リポジトリのファイルを上書きします。
-
-
raw
パススルーは、そのvalue
を/sgrules/insecure.yml
に書き込みます。 - URLでホストされている設定をフェッチし、それを
/sgrules/gosec.yml
に書き込むurl
パススルー。
その後、Semgrepは/sgrules
の下にある最終設定で起動されます。
[semgrep]
description = "My custom ruleset for Semgrep"
targetdir = "/sgrules"
timeout = 60
[[semgrep.passthrough]]
type = "git"
value = "https://gitlab.com/user/myrules.git"
ref = "develop"
[[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"
チェーン内のパススルーモードの設定
チェイン内のパススルー間で発生するファイル名の衝突の処理方法を選択できます。デフォルトの動作は、同じ名前の既存のファイルを上書きすることですが、代わりにmode = append
を選択すると、後のファイルの内容を前のファイルに追加することができます。
append
モードは、file
、url
、raw
パススルー・タイプにのみ使用できます。
次のカスタムルールセット設定では、2つのraw
パススルーを使用して、/sgrules/my-rules.yml
ファイルを繰り返し組み立て、それをルールセットとしてSemgrepに提供します。各パススルーはルールセットに1つのルールを追加します。最初のパススルーは、Semgrepルール構文に従って、トップレベルのrules
オブジェクトを初期化します。
[semgrep]
description = "My custom ruleset for Semgrep"
targetdir = "/sgrules"
validate = true
[[semgrep.passthrough]]
type = "raw"
target = "my-rules.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 = "my-rules.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
metadata:
cwe: "..."
severity: "ERROR"
languages:
- "go"
"""
# /sgrules/my-rules.yml
rules:
- id: "insecure"
patterns:
- pattern: "func insecure() {...}"
message: |
Insecure function 'insecure' detected
metadata:
cwe: "..."
severity: "ERROR"
languages:
- "go"
- id: "secret"
patterns:
- pattern-either:
- pattern: '$MASK = "..."'
- metavariable-regex:
metavariable: "$MASK"
regex: "(password|pass|passwd|pwd|secret|token)"
message: |
Use of hard-coded password
metadata:
cwe: "..."
severity: "ERROR"
languages:
- "go"
非公開リモート設定の指定
以下の例では、SAST を有効にし、共有ルールセットカスタマイズファイルを使用します。ファイルは
- グループアクセストークンを使用して、認証を必要とする非公開プロジェクトからダウンロードされます。
- デフォルトのブランチではなく、特定の Git コミット SHA でチェックアウトした場合。
グループトークンに関連づけられたユーザー名を調べる方法についてはグループアクセストークンを参照ください。
include:
- template: Security/SAST.gitlab-ci.yml
variables:
SAST_RULESET_GIT_REFERENCE: "group_2504721_bot_7c9311ffb83f2850e794d478ccee36f5:glpat-1234567@gitlab.com/example-group/example-ruleset-project@c8ea7e3ff126987fb4819cc35f2310755511c2ab"