- DAST APIスキャン実行時
- DAST APIスキャンの設定例
- DASTスキャンのためのターゲットAPI
- 認証
- 設定ファイル
- 利用可能な CI/CD 変数
- オーバーライド
- リクエストヘッダー
- 除外パス
- 最初のスキャンの実行
- DAST API 脆弱性の表示
- オフライン環境での DAST API の実行
- パフォーマンス・チューニングとテスト速度
-
トラブルシューティング
- DAST APIジョブがN時間後にタイムアウトします。
- DAST APIジョブの完了に時間がかかりすぎる
- エラー:
Error waiting for DAST API 'http://127.0.0.1:5000' to become available
Failed to start scanner session (version header not found)
Failed to start session with scanner. Please retry, and if the problem persists reach out to support.
-
Application cannot determine the base URL for the target API
- 無効なスキーマで OpenAPI を使用
No operation in the OpenAPI document is consuming any supported media type
Error, error occurred trying to download `<URL>`: There was an error when retrieving content from Uri:' <URL>'. Error:The SSL connection could not be established, see inner exception.
ERROR: Job failed: failed to pull image
- サポートまたは改善要求
- 用語解説
DAST API アナライザ
DAST API analyzerはGitLab 15.6でオンデマンドDAST APIスキャンのデフォルトアナライザーとなりました。
ウェブAPIの動的アプリケーションセキュリティテスト(DAST) を実行することで、他のQAプロセスが見逃す可能性のあるバグや潜在的なセキュリティ問題を発見することができます。他のGitLab Secureセキュリティスキャナや独自のテストプロセスに加えて、DAST API テストを使用してください。DAST API テストは、CI/CD ワークフローの一部として、またはオンデマンドで、あるいはその両方で実行することができます。
DAST API は、以下の Web API タイプをテストすることができます:
- REST API
- SOAP
- GraphQL
- フォームボディ、JSON、またはXML
DAST APIスキャン実行時
CI/CD パイプラインで実行する場合、DAST API スキャンはdast
デフォルトでステージで dast
実行されます。dast
DAST API スキャンが最新のコードを検査するようにするには、CI/CD パイプラインがステージの前にステージのテスト環境に変更をデプロイ dast
するようにしてください。
パイプラインが各実行で同じ Web サーバーにデプロイされるように設定されている場合、別のパイプラインがまだ実行されている間にパイプラインを実行すると、あるパイプラインが別のパイプラインのコードを上書きするという競合状態が発生する可能性があります。スキャン対象のAPIは、DAST APIスキャンの間、変更から除外する必要があります。API に対する変更は、DAST API スキャナによるものだけにしてください。スキャン中に API に加えられた変更(ユーザー、スケジュールされたタスク、データベースの変更、コードの変更、他のパイプライン、他のスキャナなど)は、不正確な結果を引き起こす可能性があります。
DAST APIスキャンの設定例
以下のプロジェクトは、DAST API スキャンを実演しています:
- OpenAPI v2 仕様プロジェクトの例
- Example HTTP Archive(HAR) プロジェクト
- Postman コレクション・プロジェクトの例
- GraphQL プロジェクトの例
- SOAP プロジェクトの例
- Seleniumを使った認証トークン
DASTスキャンのためのターゲットAPI
を使ってスキャンしたい API を指定します:
OpenAPIの仕様
OpenAPI仕様(旧Swagger仕様)は、REST API用のAPI記述フォーマットです。このセクションでは、テスト対象のAPIに関する情報を提供するOpenAPI仕様書を使用してDAST APIスキャンを設定する方法を説明します。OpenAPI 仕様書は、ファイルシステムのリソースまたは URL として提供されます。JSON と YAML の両方の OpenAPI フォーマットに対応しています。
DAST API は、リクエストボディを生成するために OpenAPI ドキュメントを使用します。リクエストボディが必要な場合、ボディの生成はこれらのボディタイプに限定されます:
application/x-www-form-urlencoded
multipart/form-data
application/json
application/xml
OpenAPI およびメディアタイプ
メディアタイプ (以前は MIME タイプとして知られていました) は、ファイルフォーマットと送信されるフォーマットコンテンツの識別子です。OpenAPI ドキュメントでは、あるオペレーションが異なるメディアタイプを受け付けることを指定できます。たとえば、PUT /user
ユーザーデータを更新するオペレーションでは、XML (メディアタイプapplication/xml
) または JSON (メディアタイプapplication/json
) 形式のデータを受け取ることができます。OpenAPI 2.x では、受け入れられるメディアタイプをグローバルまたはオペレーションごとに指定することができ、OpenAPI 3.x では、受け入れられるメディアタイプをオペレーションごとに指定することができます。DAST APIは、リストされたメディアタイプをチェックし、サポートされている各メディアタイプのサンプルデータを作成しようとします。
- GitLab 14.10以降では、デフォルトの動作として、サポートされているメディアタイプの中から1つを選択して使用します。最初にサポートされたメディアタイプがリストから選ばれます。この動作は設定可能です。
- GitLab 14.9以前では、デフォルトの動作はサポートされている全てのメディアタイプを使ってテストを実行します。つまり、2つのメディアタイプがリストされている場合(例えば、
application/json
とapplication/xml
)、テストはJSONを使って行われ、次にXMLを使って同じテストが行われます。
異なるメディアタイプ(例えば、application/json
とapplication/xml
)を使って、同じオペレーション(例えば、POST /user
)をテストすることは、必ずしも望ましいことではありません。例えば、ターゲットアプリケーショ ンがリクエストのコンテントタイプに関係なく同じコードを実行する場合、テストセッションを終了するのに時間がかかり、ターゲッ トアプリによってはリクエストボディに関連する脆弱性を重複して報告するかもしれません。
環境DAST_API_OPENAPI_ALL_MEDIA_TYPES
変数によって、与えられたオペレーションに対するリクエストを生成するときに、1つのメディアタイプではなく、サポートされているすべてのメディアタイプを使うかどうかを指定 DAST_API_OPENAPI_ALL_MEDIA_TYPES
できます。DAST_API_OPENAPI_ALL_MEDIA_TYPES
環境変数が DAST_API_OPENAPI_ALL_MEDIA_TYPES
任意の値に設定されている場合、DAST API は指定されたオペレーションにおいて、1つのメディアタイプではなく、サポートされているすべてのメディアタイプのリクエストを生成しようとします。この場合、提供されたメディアタイプごとにテストが繰り返されるため、テストに時間がかかります。
別の方法として、このDAST_API_OPENAPI_MEDIA_TYPES
変数を使ってテストするメディアタイプの一覧を指定 DAST_API_OPENAPI_MEDIA_TYPES
します。DAST_API_OPENAPI_MEDIA_TYPES
複数のメディアタイプを提供すると、選択されたメディアタイプごとにテストが実行されるため、テストに時間がかかります。環境変数が DAST_API_OPENAPI_MEDIA_TYPES
メディアタイプのリストに設定されているときは、 リクエストを作成するときにリストされたメディアタイプだけが含まれます。
DAST_API_OPENAPI_MEDIA_TYPES
、複数のメディアタイプはコロン(:
)で区切られます。たとえば、リクエスト生成をメディアタイプapplication/x-www-form-urlencoded
とmultipart/form-data
に制限するには、環境変数DAST_API_OPENAPI_MEDIA_TYPES
をapplication/x-www-form-urlencoded:multipart/form-data
に設定します。このリストでサポートされているメディアタイプだけがリクエスト作成時に 含まれますが、サポートされていないメディアタイプは常にスキップされます。メディアタイプのテキストは異なるセクションを含むかもしれません。例えば、application/vnd.api+json; charset=UTF-8
はtype "/" [tree "."] subtype ["+" suffix]* [";" parameter]
の複合です。 リクエスト生成時にメディアタイプのフィルタリングを実行するとき、 パラメータは考慮されません。
環境変数DAST_API_OPENAPI_ALL_MEDIA_TYPES
とDAST_API_OPENAPI_MEDIA_TYPES
でメディアタイプの扱い方を決めることができます。これらの設定は互いに排他的です。両方が有効な場合、DAST API はエラーを報告します。
OpenAPI 仕様による DAST API の設定
OpenAPI 仕様で DAST API スキャンを設定するには、以下の手順に従います:
-
.gitlab-ci.yml
ファイルにDAST-API.gitlab-ci.yml
テンプレート を含めます。 -
設定ファイルには、異なるチェックを有効にした複数のテストプロファイルが定義されています。
Quick
プロファイルから始めることを推奨します。このプロファイルを使ったテストはより速く完了し、設定の検証がより簡単になります。.gitlab-ci.yml
ファイルにDAST_API_PROFILE
CI/CD 変数を追加してプロファイルを指定します。 -
OpenAPI Specification の場所をファイルか URL で指定します。
DAST_API_OPENAPI
変数を追加して場所を指定します。 -
ターゲットAPIインスタンスのベースURLも必要です。
DAST_API_TARGET_URL
変数かenvironment_url.txt
ファイルを使って指定してください。プロジェクトのルートにある
environment_url.txt
ファイルに URL を追加すると、動的環境でのテストに最適です。GitLab CI/CDパイプライン中に動的に作成されたアプリに対してDAST APIを実行するには、アプリにそのURLをenvironment_url.txt
ファイルに保持させます。DAST APIは自動的にそのファイルを解析してスキャン対象を見つけます。この例はAuto DevOps CI YAMLで見ることができます。
OpenAPI 仕様を使用する完全な設定例:
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_PROFILE: Quick
DAST_API_OPENAPI: test-api-specification.json
DAST_API_TARGET_URL: http://test-deployment/
これはDAST APIの最小設定です。ここから以下のことができます:
- 最初のスキャンを実行します。
- 認証を追加します。
- 偽陽性の対処法を学びます。
HTTPアーカイブ(HAR)
HTTP Archive フォーマット(HAR)はHTTPトランザクションを記録するためのアーカイブファイルフォーマットです。GitLab DAST APIスキャナで使用する場合、HARファイルにはテストするWeb APIを呼び出した記録が含まれていなければなりません。DAST API スキャナは全てのリクエストを抽出し、テストの実行に使用します。
HARファイルを生成するには様々なツールを使うことができます:
- Insomnia Core:APIクライアント
- Chrome: ブラウザ
- Firefox: ブラウザブラウザ
- Fiddler:ウェブデバッグプロキシ
- GitLab HAR Recorder:コマンドライン
HAR ファイルを使用した DAST API スキャン
テスト対象の API に関する情報を提供する HAR ファイルを使用するように DAST API を設定します:
-
.gitlab-ci.yml
ファイルにDAST-API.gitlab-ci.yml
テンプレート を含めます。 -
設定ファイルには、異なるチェックを有効にした複数のテストプロファイルが定義されています。
Quick
プロファイルから始めることを推奨します。このプロファイルでのテストはより速く完了し、設定の検証がより簡単になります。.gitlab-ci.yml
ファイルにDAST_API_PROFILE
CI/CD 変数を追加してプロファイルを指定します。 -
HARファイルの場所を指定します。場所はファイルパスかURLで指定できます。URL サポートはGitLab 13.10 以降で導入されました。
DAST_API_HAR
変数を追加して場所を指定してください。 -
ターゲットAPIインスタンスのベースURLも必要です。
DAST_API_TARGET_URL
変数かenvironment_url.txt
ファイルを使って指定してください。プロジェクトのルートにある
environment_url.txt
ファイルに URL を追加すると、動的環境でのテストに最適です。GitLab CI/CDパイプライン中に動的に作成されたアプリに対してDAST APIを実行するには、アプリにそのURLをenvironment_url.txt
ファイルに保持させます。DAST APIは自動的にそのファイルを解析してスキャン対象を見つけます。この例はAuto DevOps CI YAMLで見ることができます。
HARファイルを使用する完全な設定例:
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_PROFILE: Quick
DAST_API_HAR: test-api-recording.har
DAST_API_TARGET_URL: http://test-deployment/
この例は、DAST APIの最小限の設定です。ここから以下のことができます:
- 最初のスキャンを実行します。
- 認証を追加します。
- 偽陽性の対処法を学びます。
GraphQL スキーマ
GraphQL SchemaのサポートはGitLab 15.4で導入されました。
GraphQLはAPIのクエリ言語であり、REST APIに代わるものです。DAST APIは複数の方法でGraphQLエンドポイントのテストをサポートしています:
- GraphQL Schemaを使ったテスト。GitLab 15.4で導入されました。
- GraphQLクエリの記録(HAR) 。
- GraphQLクエリを含むPostmanコレクションを使用してテストします。
このセクションでは、GraphQL スキーマを使用したテスト方法を説明します。DAST API の GraphQL スキーマサポートは、イントロスペクションをサポートするエンドポイントからスキーマをクエリできます。GraphiQL のようなツールが動作するように、イントロスペクションはデフォルトで有効になっています。イントロスペクションを有効にする方法の詳細については、GraphQL フレームワークのドキュメントを参照してください。
GraphQL エンドポイント URL による DAST API スキャン
DAST API の GraphQL サポートは、スキーマの GraphQL エンドポイントをクエリできます。
テスト対象の API に関する情報を提供する GraphQL エンドポイント URL を使用するように DAST API を設定するには、以下の手順に従います:
-
.gitlab-ci.yml
ファイルにDAST-API.gitlab-ci.yml
テンプレート を含めます。 -
例えば
/api/graphql
のように、GraphQL エンドポイントへのパスを指定します。DAST_API_GRAPHQL
変数を追加して場所を指定します。 -
ターゲットAPIインスタンスのベースURLも必要です。
DAST_API_TARGET_URL
変数かenvironment_url.txt
ファイルを使って指定してください。プロジェクトのルートにある
environment_url.txt
ファイルに URL を追加すると、動的環境でのテストに最適です。詳細については、ドキュメントの動的環境ソリューションのセクションを参照してください。
GraphQL エンドポイント パスを使用する完全な設定例:
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
dast_api:
variables:
DAST_API_GRAPHQL: /api/graphql
DAST_API_TARGET_URL: http://test-deployment/
この例は、DAST APIの最小限の設定です。ここから以下のことができます:
- 最初のスキャンを実行します。
- 認証を追加します。
- 偽陽性の対処法を学びます。
GraphQL スキーマファイルによる DAST API スキャン
DAST API は GraphQL スキーマファイルを使用して、イントロスペクションが無効になっている GraphQL エンドポイントを理解し、テストすることができます。GraphQL スキーマファイルを使用するには、introspection JSON 形式である必要があります。GraphQL スキーマは、オンラインのサードパーティツール(https://transform.tools/graphql-to-introspection-json)を使用して introspection JSON フォーマットに変換できます。
テスト対象の API に関する情報を提供する GraphQL スキーマファイルを使用するように DAST API を設定するには、以下の手順に従います:
-
.gitlab-ci.yml
ファイルにDAST-API.gitlab-ci.yml
テンプレート を含めます。 -
例えば
/api/graphql
のように、GraphQL エンドポイントのパスを指定します。DAST_API_GRAPHQL
変数を追加してパスを指定します。 -
GraphQLスキーマファイルの場所を指定します。ファイルのパスまたは URL として場所を指定できます。
DAST_API_GRAPHQL_SCHEMA
変数を追加して場所を指定します。 -
ターゲットAPIインスタンスのベースURLも必要です。
DAST_API_TARGET_URL
変数かenvironment_url.txt
ファイルを使って指定してください。プロジェクトのルートにある
environment_url.txt
ファイルに URL を追加すると、動的環境でのテストに最適です。詳細については、ドキュメントの動的環境ソリューションのセクションを参照してください。
GraphQLスキーマファイルを使用する完全な設定例:
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
dast_api:
variables:
DAST_API_GRAPHQL: /api/graphql
DAST_API_GRAPHQL_SCHEMA: test-api-graphql.schema
DAST_API_TARGET_URL: http://test-deployment/
GraphQLスキーマファイルのURLを使用する設定の完全な例:
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
dast_api:
variables:
DAST_API_GRAPHQL: /api/graphql
DAST_API_GRAPHQL_SCHEMA: http://file-store/files/test-api-graphql.schema
DAST_API_TARGET_URL: http://test-deployment/
この例は、DAST APIの最小限の設定です。ここから以下のことができます:
- 最初のスキャンを実行します。
- 認証を追加します。
- 偽陽性の対処法を学びます。
ポストマンコレクション
Postman API Clientは、開発者やテスターが様々なタイプのAPIを呼び出すために使用する一般的なツールです。API 定義は、DAST API で使用するためにPostman Collection ファイルとしてエクスポートすることができます。エクスポートする際は、サポートされているPostman Collectionのバージョン(v2.0またはv2.1)を選択してください。
GitLab DAST APIスキャナで使用する場合、Postman Collectionには有効なデータでテストするWeb APIの定義が含まれている必要があります。DAST APIスキャナは全てのAPI定義を抽出し、テストを実行するために使用します。
Postman コレクションファイルによる DAST API スキャン
テスト対象の API に関する情報を提供する Postman Collection ファイルを使用するように DAST API を設定します:
-
設定ファイルには、異なるチェックを有効にした複数のテストプロファイルが定義されています。
Quick
プロファイルから始めることを推奨します。このプロファイルでのテストはより速く完了し、設定の検証がより簡単になります。.gitlab-ci.yml
ファイルにDAST_API_PROFILE
CI/CD 変数を追加してプロファイルを指定します。 -
Postman Collection ファイルの場所をファイルまたは URL で指定します。
DAST_API_POSTMAN_COLLECTION
変数を追加して場所を指定します。 -
ターゲットAPIインスタンスのベースURLも必要です。
DAST_API_TARGET_URL
変数かenvironment_url.txt
ファイルを使って指定してください。プロジェクトのルートにある
environment_url.txt
ファイルに URL を追加すると、動的環境でのテストに最適です。GitLab CI/CDパイプライン中に動的に作成されたアプリに対してDAST APIを実行するには、アプリにそのURLをenvironment_url.txt
ファイルに保持させます。DAST APIは自動的にそのファイルを解析してスキャン対象を見つけます。この例はAuto DevOps CI YAMLで見ることができます。
Postman コレクションを使用する完全な設定例です:
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_PROFILE: Quick
DAST_API_POSTMAN_COLLECTION: postman-collection_serviceA.json
DAST_API_TARGET_URL: http://test-deployment/
これはDAST APIの最小設定です。ここから以下のことができます:
- 最初のスキャンを実行します。
- 認証を追加します。
- 偽陽性の対処法を学びます。
Postman の変数
Postman クライアントの変数
Postman では開発者がリクエストの様々な部分で使えるプレースホルダを定義できます。変数の使い方で説明したように、これらのプレースホルダは変数と呼ばれます。変数を使ってリクエストやスクリプトに値を保存したり再利用したりできます。たとえば、コレクションを編集してドキュメントに変数を追加できます:
あるいは、環境変数を追加することもできます:
URLやヘッダーなどのセクションで変数を使うことができます:
Postmanは素敵なUXを体験できる基本的なクライアントツールから、スクリプトでAPIをテストしたり、二次リクエストをトリガーする複雑なコレクションを作成したり、途中で変数を設定したりできる、より複雑なエコシステムに成長しました。Postmanエコシステムのすべての機能がサポートされているわけではありません。例えば、スクリプトはサポートされていません。Postmanサポートの主な焦点は、Postmanクライアントで使用されるPostmanコレクション定義と、ワークスペース、環境、コレクション自体で定義された関連変数を取り込むことです。
Postmanは異なるスコープで変数を作成できます。それぞれのスコープは、Postmanツールでの可視性のレベルが異なります。例えば、すべてのオペレーション定義とワークスペースから見える_グローバル環境_スコープに変数を作成できます。また、特定の_環境_スコープに変数を作成し、その特定の環境が選択されているときのみ表示・使用されるようにすることもできます。例えば Postman エコシステムでは、Postman クライアントでリクエストを作成することができます。
Postman の変数スコープは難しいトピックで、誰もが知っているわけではありません。先に進む前に Postman ドキュメントの変数スコープを読むことを強くお勧めします。
上述したように、変数スコープには様々なものがあり、それぞれに目的があり、Postmanドキュメントに柔軟性を持たせるために使用することができます。Postmanのドキュメントにあるように、変数の値がどのように計算されるかについて重要な注意があります:
同じ名前の変数が2つの異なるスコープで宣言されている場合、最も狭いスコープの変数に格納されている値が使用されます。例えば、グローバル変数
username
名とローカル変数名がusername
ある場合、リクエストが実行されるときにはローカル変数の値が使われます。
Postman クライアントと DAST API がサポートする変数のスコープを以下にまとめます:
- グローバル環境 (Global) スコープは、ワークスペース全体で利用可能な、あらかじめ定義された特別な環境です。_グローバル環境_スコープを_グローバル_スコープと呼ぶこともあります。Postman Client ではグローバル環境を JSON ファイルにエクスポートでき、DAST API で使用できます。
- 環境スコープとは、ユーザーが Postman Client で作成した、名前付きの変数グループです。Postman Client はグローバル環境とともに、1つのアクティブ環境をサポートします。ユーザーが作成したアクティブ環境で定義された変数は、グローバル環境で定義された変数よりも優先されます。Postman クライアントでは、DAST API で使用できる JSON ファイルに環境をエクスポートできます。
- コレクションスコープとは、あるコレクションで宣言された変数のグループのことです。コレクション変数は宣言されたコレクションと、ネストされたリクエストやコレクションで使用できます。コレクションスコープで定義された変数は_グローバル環境_スコープや_環境_スコープよりも優先されます。この JSON ファイルには選択されたコレクション、リクエスト、コレクション変数が含まれます。
-
DAST API スコープはDAST API によって追加された新しいスコープで、ユーザーが追加の変数を提供したり、他のサポートされているスコープで定義された変数を上書きしたりすることができます。このスコープは Postman ではサポートされていません。_DAST API スコープの_変数は、カスタム JSON ファイル形式で提供されます。
- 環境またはコレクションで定義された値をオーバーライドします。
- スクリプトからの変数の定義
- サポートされていない_データ・スコープから_1行のデータを定義
- データスコープとは、JSON や CSV ファイルの名前と値を持つ変数のグループです。NewmanやPostman Collection Runnerのような Postman コレクションランナーは、JSON や CSV ファイルがある回数だけコレクション内のリクエストを実行します。これらの変数の良い使用例は、Postman のスクリプトを使ってテストを自動化することです。DAST API は CSV や JSON ファイルからの読み込みをサポートしていません。
- ローカルスコープはPostman スクリプト内で定義される変数です。DAST API は Postman スクリプトをサポートしておらず、スクリプト内で定義された変数もサポートしていません。スクリプトで定義された変数は、サポートされているスコープ、またはカスタム JSON フォーマットのいずれかで定義することで、値を提供することができます。
すべてのスコープが DAST API でサポートされているわけではなく、スクリプトで定義された変数はサポートされていません。以下の表は、最も広いスコープから最も狭いスコープにソートされています。
スコープ | ポストマン | DAST API | コメント |
---|---|---|---|
グローバル環境 | はい | はい | 特別な事前定義環境 |
環境 | はい | はい | 指定環境 |
コレクション | はい | はい | postmanコレクションで定義 |
DAST API スコープ | なし | はい | DAST APIによって追加されたカスタムスコープ |
データ | はい | なし | CSVまたはJSON形式の外部ファイル |
ローカル | はい | なし | スクリプトで定義された変数 |
異なるスコープで変数を定義し、変数をエクスポートする方法の詳細については、以下を参照してください:
Postman クライアントからのエクスポート
Postman Client では様々なファイル形式でエクスポートできます。例えば、Postman コレクションや Postman 環境をエクスポートできます。エクスポートする環境はグローバル環境(常に利用可能)でも、以前に作成したカスタム環境でもかまいません。Postman コレクションをエクスポートする場合、コレクションと _ローカル_スコープ変数の宣言のみを含むことができます。
_環境_スコープ変数の宣言を得るには、その時点で指定された環境をエクスポートする必要があります。エクスポートされたファイルには、選択した環境の変数のみが含まれます。
サポートされるスコープが異なる変数のエクスポートの詳細については、こちらを参照してください:
DAST API スコープ、カスタム JSON ファイル形式
カスタムJSONファイルフォーマットは、各オブジェクトプロパティが変数名を表し、プロパティ値が変数値を表すJSONオブジェクトです。このファイルはお好みのテキストエディタを使用して作成することもできますし、パイプライン内の以前のジョブで作成することもできます。
この例では、DAST API スコープで 2 つの変数base_url
とtoken
を定義しています:
{
"base_url": "http://127.0.0.1/",
"token": "Token 84816165151"
}
DAST API でのスコープの使用
GitLab15.1以降では、global、environment、collection、_GitLab DAST APIの_スコープがサポートされています。GitLab 15.0以前では、_collectionと_GitLab D_AST APIの_スコープのみをサポートしています。
以下の表は、スコープファイル/URLを DAST API 設定変数にマッピングするためのクイックリファレンスです:
スコープ | 提供方法 |
---|---|
グローバル環境 | dast_api_postman_collection_variables |
環境 | dast_api_postman_collection_variables |
コレクション | dast_api_postman_collection |
DAST API スコープ | dast_api_postman_collection_variables |
データ | 未対応 |
ローカル | 未対応 |
Postman Collection ドキュメントには、_コレクションに_スコープされた変数が自動的に含まれます。Postman Collection は設定変数DAST_API_POSTMAN_COLLECTION
で提供されます。この変数はエクスポートされた1つのPostmanコレクションに設定できます。
他のスコープの変数はDAST_API_POSTMAN_COLLECTION_VARIABLES
設定変数を通して提供されます。この設定変数は、GitLab 15.1以降ではカンマ(,
)区切りのファイルリストをサポートしています。GitLab 15.0とそれ以前では、単一のファイルのみをサポートしています。ファイルが必要なスコープ情報を提供するので、提供されるファイルの順番は重要ではありません。
設定変数DAST_API_POSTMAN_COLLECTION_VARIABLES
:
未定義のPostman変数
Postman コレクションファイルが使用しているすべての変数参照を、DAST API エンジンが見つけられない可能性があります。以下のようなケースが考えられます:
- _データ_または_ローカル_スコープ変数を使用しており、前述のようにこれらのスコープは DAST API でサポートされていません。したがって、これらの変数の値がDAST API スコープを通して提供されていないと仮定すると、_データ_変数と_ローカル_スコープ変数の値は未定義です。
- 変数名の入力に誤りがあり、定義されている変数と名前が一致しません。
- Postman クライアントが、DAST API ではサポートされていない新しい動的変数をサポートしました。
可能な限り、DAST API は未定義の変数を扱う際に Postman Client と同じ動作をします。変数参照のテキストはそのままで、テキストの置換は行われません。サポートされていない動的変数についても同じ動作が適用されます。
例えば、Postman コレクションのリクエスト定義が変数を{{full_url}}
参照していて、その変数が見つから なかった場合、その変数は変更されずに . {{full_url}}
動的な Postman 変数
ユーザーが様々なスコープレベルで定義できる変数に加えて、Postman には_動的_変数と呼ばれる定義済みの変数があります。動的変数はすでに定義されており、その名前の先頭にはドル記号 ($
) が付きます。インスタンスでは$guid
となります。_動的_変数は他の変数と同じように使うことができ、Postmanクライアントではリクエスト/コレクションの実行中にランダムな値を生成します。
DAST API と Postman の重要な違いは、DAST API は同じ動的変数を使用するたびに同じ値を返すことです。これは、同じ動的変数を使用するたびにランダムな値を返す Postman Client の動作とは異なります。言い換えると、DAST API は動的変数に静的な値を使用するのに対し、Postman はランダムな値を使用します。
スキャン処理中にサポートされる動的変数は以下の通りです:
変数 | 値 |
---|---|
$guid | 611c2e81-2ccb-42d8-9ddc-2d0bfa65c1b4 |
$isoTimestamp | 2020-06-09T21:10:36.177Z |
$randomAbbreviation | PCI |
$randomAbstractImage | http://no-a-valid-host/640/480/abstract |
$randomAdjective | auxiliary |
$randomAlphaNumeric | a |
$randomAnimalsImage | http://no-a-valid-host/640/480/animals |
$randomAvatarImage | https://no-a-valid-host/path/to/some/image.jpg |
$randomBankAccount | 09454073 |
$randomBankAccountBic | EZIAUGJ1 |
$randomBankAccountIban | MU20ZPUN3039684000618086155TKZ |
$randomBankAccountName | Home Loan Account |
$randomBitcoin | 3VB8JGT7Y4Z63U68KGGKDXMLLH5 |
$randomBoolean | true |
$randomBs | killer leverage schemas |
$randomBsAdjective | viral |
$randomBsBuzz | repurpose |
$randomBsNoun | markets |
$randomBusinessImage | http://no-a-valid-host/640/480/business |
$randomCatchPhrase | Future-proofed heuristic open architecture |
$randomCatchPhraseAdjective | Business-focused |
$randomCatchPhraseDescriptor | bandwidth-monitored |
$randomCatchPhraseNoun | superstructure |
$randomCatsImage | http://no-a-valid-host/640/480/cats |
$randomCity | Spinkahaven |
$randomCityImage | http://no-a-valid-host/640/480/city |
$randomColor | fuchsia |
$randomCommonFileExt | wav |
$randomCommonFileName | well_modulated.mpg4 |
$randomCommonFileType | audio |
$randomCompanyName | Grady LLC |
$randomCompanySuffix | Inc |
$randomCountry | Kazakhstan |
$randomCountryCode | MD |
$randomCreditCardMask | 3622 |
$randomCurrencyCode | ZMK |
$randomCurrencyName | Pound Sterling |
$randomCurrencySymbol | £ |
$randomDatabaseCollation | utf8_general_ci |
$randomDatabaseColumn | updatedAt |
$randomDatabaseEngine | Memory |
$randomDatabaseType | text |
$randomDateFuture | Tue Mar 17 2020 13:11:50 GMT+0530 (India Standard Time) |
$randomDatePast | Sat Mar 02 2019 09:09:26 GMT+0530 (India Standard Time) |
$randomDateRecent | Tue Jul 09 2019 23:12:37 GMT+0530 (India Standard Time) |
$randomDepartment | Electronics |
$randomDirectoryPath | /usr/local/bin |
$randomDomainName | trevor.info |
$randomDomainSuffix | org |
$randomDomainWord | jaden |
$randomEmail | Iva.Kovacek61@no-a-valid-host.com |
$randomExampleEmail | non-a-valid-user@example.net |
$randomFashionImage | http://no-a-valid-host/640/480/fashion |
$randomFileExt | war |
$randomFileName | neural_sri_lanka_rupee_gloves.gdoc |
$randomFilePath | /home/programming_chicken.cpio |
$randomFileType | application |
$randomFirstName | Chandler |
$randomFoodImage | http://no-a-valid-host/640/480/food |
$randomFullName | Connie Runolfsdottir |
$randomHexColor | #47594a |
$randomImageDataUri | data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20baseProfile%3D%22full%22%20width%3D%22undefined%22%20height%3D%22undefined%22%3E%20%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22grey%22%2F%3E%20%20%3Ctext%20x%3D%220%22%20y%3D%2220%22%20font-size%3D%2220%22%20text-anchor%3D%22start%22%20fill%3D%22white%22%3Eundefinedxundefined%3C%2Ftext%3E%20%3C%2Fsvg%3E |
$randomImageUrl | http://no-a-valid-host/640/480 |
$randomIngverb | navigating |
$randomInt | 494 |
$randomIP | 241.102.234.100 |
$randomIPV6 | dbe2:7ae6:119b:c161:1560:6dda:3a9b:90a9 |
$randomJobArea | Mobility |
$randomJobDescriptor | Senior |
$randomJobTitle | International Creative Liaison |
$randomJobType | Supervisor |
$randomLastName | Schneider |
$randomLatitude | 55.2099 |
$randomLocale | ny |
$randomLongitude | 40.6609 |
$randomLoremLines | Ducimus in ut mollitia.\nA itaque non.\nHarum temporibus nihil voluptas.\nIste in sed et nesciunt in quaerat sed. |
$randomLoremParagraph | Ab aliquid odio iste quo voluptas voluptatem dignissimos velit. Recusandae facilis qui commodi ea magnam enim nostrum quia quis. Nihil est suscipit assumenda ut voluptatem sed. Esse ab voluptas odit qui molestiae. Rem est nesciunt est quis ipsam expedita consequuntur. |
$randomLoremParagraphs | Voluptatem rem magnam aliquam ab id aut quaerat. Placeat provident possimus voluptatibus dicta velit non aut quasi. Mollitia et aliquam expedita sunt dolores nam consequuntur. Nam dolorum delectus ipsam repudiandae et ipsam ut voluptatum totam. Nobis labore labore recusandae ipsam quo. |
$randomLoremSentence | Molestias consequuntur nisi non quod. |
$randomLoremSentences | Et sint voluptas similique iure amet perspiciatis vero sequi atque. Ut porro sit et hic. Neque aspernatur vitae fugiat ut dolore et veritatis. Ab iusto ex delectus animi. Voluptates nisi iusto. Impedit quod quae voluptate qui. |
$randomLoremSlug | eos-aperiam-accusamus, beatae-id-molestiae, qui-est-repellat |
$randomLoremText | Quisquam asperiores exercitationem ut ipsum. Aut eius nesciunt. Et reiciendis aut alias eaque. Nihil amet laboriosam pariatur eligendi. Sunt ullam ut sint natus ducimus. Voluptas harum aspernatur soluta rem nam. |
$randomLoremWord | est |
$randomLoremWords | vel repellat nobis |
$randomMACAddress | 33:d4:68:5f:b4:c7 |
$randomMimeType | audio/vnd.vmx.cvsd |
$randomMonth | February |
$randomNamePrefix | Dr. |
$randomNameSuffix | MD |
$randomNatureImage | http://no-a-valid-host/640/480/nature |
$randomNightlifeImage | http://no-a-valid-host/640/480/nightlife |
$randomNoun | bus |
$randomPassword | t9iXe7COoDKv8k3 |
$randomPeopleImage | http://no-a-valid-host/640/480/people |
$randomPhoneNumber | 700-008-5275 |
$randomPhoneNumberExt | 27-199-983-3864 |
$randomPhrase | You can't program the monitor without navigating the mobile XML program! |
$randomPrice | 531.55 |
$randomProduct | Pizza |
$randomProductAdjective | Unbranded |
$randomProductMaterial | Steel |
$randomProductName | Handmade Concrete Tuna |
$randomProtocol | https |
$randomSemver | 7.0.5 |
$randomSportsImage | http://no-a-valid-host/640/480/sports |
$randomStreetAddress | 5742 Harvey Streets |
$randomStreetName | Kuhic Island |
$randomTransactionType | payment |
$randomTransportImage | http://no-a-valid-host/640/480/transport |
$randomUrl | https://no-a-valid-host.net |
$randomUserAgent | Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.9.8; rv:15.6) Gecko/20100101 Firefox/15.6.6 |
$randomUserName | Jarrell.Gutkowski |
$randomUUID | 6929bb52-3ab2-448a-9796-d6480ecad36b |
$randomVerb | navigate |
$randomWeekday | Thursday |
$randomWord | withdrawal |
$randomWords | Samoa Synergistic sticky copying Grocery |
$timestamp | 1562757107 |
例グローバルスコープ
この例では、_グローバル_スコープはPostman Client からglobal-scope.json
としてエクスポートされ、DAST_API_POSTMAN_COLLECTION_VARIABLES
設定変数を通して DAST API に提供されます。
DAST_API_POSTMAN_COLLECTION_VARIABLES
を使う例です:
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_PROFILE: Quick
DAST_API_POSTMAN_COLLECTION: postman-collection.json
DAST_API_POSTMAN_COLLECTION_VARIABLES: global-scope.json
DAST_API_TARGET_URL: http://test-deployment/
例環境スコープ
この例では、_環境_スコープはPostman クライアントからenvironment-scope.json
としてエクスポートされ、DAST_API_POSTMAN_COLLECTION_VARIABLES
設定変数を通して DAST API に提供されます。
DAST_API_POSTMAN_COLLECTION_VARIABLES
を使う例です:
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_PROFILE: Quick
DAST_API_POSTMAN_COLLECTION: postman-collection.json
DAST_API_POSTMAN_COLLECTION_VARIABLES: environment-scope.json
DAST_API_TARGET_URL: http://test-deployment/
例コレクション・スコープ
_コレクション_スコープ変数はエクスポートされた Postman Collection ファイルに含まれ、DAST_API_POSTMAN_COLLECTION
設定変数を通して提供されます。
DAST_API_POSTMAN_COLLECTION
を使う例です:
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_PROFILE: Quick
DAST_API_POSTMAN_COLLECTION: postman-collection.json
DAST_API_TARGET_URL: http://test-deployment/
例DAST API スコープ
DAST API スコープは、_DAST_API でサポートされていないデータや_ローカル_スコープの変数を定義することと、別のスコープで定義された既存の変数の値を変更することです。DAST API スコープはDAST_API_POSTMAN_COLLECTION_VARIABLES
設定変数を通じて提供されます。
DAST_API_POSTMAN_COLLECTION_VARIABLES
を使う例です:
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_PROFILE: Quick
DAST_API_POSTMAN_COLLECTION: postman-collection.json
DAST_API_POSTMAN_COLLECTION_VARIABLES: dast-api-scope.json
DAST_API_TARGET_URL: http://test-deployment/
ファイルdast-api-scope.json
は、私たちのカスタムJSONファイル形式を使用しています。このJSONは、プロパティにキーと値のペアを持つオブジェクトです。キーは変数の名前で、値は変数の値です。例えば
{
"base_url": "http://127.0.0.1/",
"token": "Token 84816165151"
}
例複数のスコープ
この例では、_グローバル_スコープ、_環境_スコープ、_コレクション_スコープを設定します。まず最初に、さまざまなスコープをエクスポートします。
-
_グローバル_スコープを
global-scope.json
- として_環境_スコープをエクスポートします。
environment-scope.json
- _コレクション_スコープを含む Postman Collection を次のようにエクスポートします。
postman-collection.json
Postman Collection はDAST_API_POSTMAN_COLLECTION
変数を使用して提供され、他のスコープはDAST_API_POSTMAN_COLLECTION_VARIABLES
を使用して提供されます。 DAST API は、各ファイルで提供されるデータを使用して、提供されたファイルがどのスコープに一致するかを識別できます。
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_PROFILE: Quick
DAST_API_POSTMAN_COLLECTION: postman-collection.json
DAST_API_POSTMAN_COLLECTION_VARIABLES: global-scope.json,environment-scope.json
DAST_API_TARGET_URL: http://test-deployment/
例変数の値の変更
Exporter されたスコープを使用する場合、変数の値を DAST API で使用するために変更しなければならないことがよくあります。たとえば、_コレクション_スコープの変数にapi_version
という名前の変数があり、その値がv2
であるのに対し、テストではv1
という値が必要です。これは、_DAST API_スコープが他のすべてのスコープよりも優先されるためです。
_コレクション_スコープ変数はエクスポートされた Postman Collection ファイルに含まれ、DAST_API_POSTMAN_COLLECTION
設定変数を通して提供されます。
DAST API スコープはDAST_API_POSTMAN_COLLECTION_VARIABLES
設定変数を通して提供されますが、まずファイルを作成する必要があります。ファイルdast-api-scope.json
は、カスタムJSONファイル形式を使用しています。このJSONは、プロパティにキーと値のペアを持つオブジェクトです。キーは変数の名前で、値は変数の値です。例えば
{
"api_version": "v1"
}
私たちのCI定義:
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_PROFILE: Quick
DAST_API_POSTMAN_COLLECTION: postman-collection.json
DAST_API_POSTMAN_COLLECTION_VARIABLES: dast-api-scope.json
DAST_API_TARGET_URL: http://test-deployment/
例複数のスコープで変数の値を変更する例
Exporter スコープを使用する場合、DAST API で使用するために変数の値を変更しなければならないことがよくあります。たとえば、_環境_スコープにapi_version
という変数があり、その値がv2
であるのに対し、テストではv1
という値が必要です。これは、_DAST API_スコープが他のすべてのスコープよりも優先されるためです。
この例では、_グローバル_スコープ、_環境_スコープ、_コレクション_スコープ、_DAST API_スコープを設定しています。まず最初に、さまざまなスコープをエクスポートして作成します。
-
_グローバル_スコープを
global-scope.json
- として_環境_スコープをエクスポートします。
environment-scope.json
- _コレクション_スコープを含む Postman Collection を次のようにエクスポートします。
postman-collection.json
DAST APIスコープは、カスタムJSONファイルフォーマットを使用してファイルdast-api-scope.json
を作成することで使用されます。このJSONは、プロパティのキーと値のペアを持つオブジェクトです。キーは変数名で、値は変数の値です。例えば
{
"api_version": "v1"
}
Postman Collection はDAST_API_POSTMAN_COLLECTION
変数を使用して提供され、他のスコープはDAST_API_POSTMAN_COLLECTION_VARIABLES
を使用して提供されます。 DAST API は、各ファイルで提供されるデータを使用して、提供されたファイルがどのスコープに一致するかを識別できます。
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_PROFILE: Quick
DAST_API_POSTMAN_COLLECTION: postman-collection.json
DAST_API_POSTMAN_COLLECTION_VARIABLES: global-scope.json,environment-scope.json,dast-api-scope.json
DAST_API_TARGET_URL: http://test-deployment/
認証
認証は、認証トークンをヘッダまたはクッキーとして提供することで処理されます。認証フローを実行したりトークンを計算したりするスクリプトを提供することができます。
HTTP ベーシック認証
HTTPベーシック認証は、HTTPプロトコルに組み込まれた認証方式で、トランスポートレイヤーセキュリティ(TLS)と組み合わせて使用されます。
パスワード用のCI/CD変数(例えば、TEST_API_PASSWORD
)を作成し、それをマスクするように設定することをお勧めします。CI/CD変数は、GitLabプロジェクトのページのSettings > CI/CDのVariablesセクションから作成できます。マスクされた変数には制限があるため、パスワードを変数として追加する前にBase64エンコードする必要があります。
最後に、.gitlab-ci.yml
ファイルに CI/CD 変数を2つ追加します:
-
DAST_API_HTTP_USERNAME
:認証用のユーザー名。 -
DAST_API_HTTP_PASSWORD_BASE64
:認証用の Base64 エンコードされたパスワード。
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_PROFILE: Quick
DAST_API_HAR: test-api-recording.har
DAST_API_TARGET_URL: http://test-deployment/
DAST_API_HTTP_USERNAME: testuser
DAST_API_HTTP_PASSWORD_BASE64: $TEST_API_PASSWORD
生のパスワード
パスワードをBase64エンコードしたくない場合(あるいはGitLab 15.3以前を使っている場合)、DAST_API_HTTP_PASSWORD_BASE64
を使う代わりに生のパスワードDAST_API_HTTP_PASSWORD
を指定することができます。
ベアラートークン
ベアラートークンは、OAuth2 や JSON Web Tokens(JWT)など、さまざまな認証メカニズムで使用されます。Bearer トークンはAuthorization
HTTP ヘッダを使用して送信されます。DAST API で Bearer トークンを使用するには、以下のいずれかが必要です:
- 有効期限がないトークン
- テスト期間中有効なトークンを生成する方法。
- DAST API がトークンを生成するために呼び出す Python スクリプト。
トークンの有効期限はありません
Bearer トークンに有効期限がない場合は、DAST_API_OVERRIDES_ENV
変数を使用してください。この変数の内容は、DAST API の送信 HTTP リクエストに追加するヘッダーとクッキーを提供する JSON スニペットです。
以下の手順に従って、DAST_API_OVERRIDES_ENV
でベアラートークンを提供してください:
-
CI/CD 変数、例えば
TEST_API_BEARERAUTH
を作成し、その値を{"headers":{"Authorization":"Bearer dXNlcm5hbWU6cGFzc3dvcmQ="}}
とします(トークンを代入してください)。CI/CD変数はGitLabプロジェクトページのSettings > CI/CDの Variablesセクションから作成できます。変数のフォーマット上、TEST_API_BEARERAUTH
変数をマスクTEST_API_BEARERAUTH
することはできません。TEST_API_BEARERAUTH
トークンの値をマスクするには、トークンの値で2つ目の変数を作成し、そのTEST_API_BEARERAUTH
値を{"headers":{"Authorization":"Bearer $MASKED_VARIABLE"}}
。 -
.gitlab-ci.yml
ファイルで、DAST_API_OVERRIDES_ENV
に先ほど作成した変数を設定します:stages: - dast include: - template: DAST-API.gitlab-ci.yml variables: DAST_API_PROFILE: Quick DAST_API_OPENAPI: test-api-specification.json DAST_API_TARGET_URL: http://test-deployment/ DAST_API_OVERRIDES_ENV: $TEST_API_BEARERAUTH
-
認証が機能していることを確認するには、DAST API テストを実行し、ジョブログとテスト API のアプリケーションログをレビューします。
テスト実行時に生成されるトークン
ベアラ トークンを生成する必要があり、テスト中に期限切れにならない場合は、トークンを含むファイルを DAST API に提供できます。前のステージとジョブ、または DAST API ジョブの一部が、このファイルを生成できます。
DAST API は、以下の構造を持つ JSON ファイルを受け取ることを想定しています:
{
"headers" : {
"Authorization" : "Bearer dXNlcm5hbWU6cGFzc3dvcmQ="
}
}
このファイルは前のステージで生成され、DAST_API_OVERRIDES_FILE
CI/CD 変数を通して DAST API に提供されます。
.gitlab-ci.yml
ファイルにDAST_API_OVERRIDES_FILE
を設定してください:
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_PROFILE: Quick
DAST_API_OPENAPI: test-api-specification.json
DAST_API_TARGET_URL: http://test-deployment/
DAST_API_OVERRIDES_FILE: dast-api-overrides.json
認証が機能していることを確認するには、DAST API テストを実行し、ジョブログとテスト API のアプリケーションログをレビューします。
トークンの有効期限が短い
Bearer トークンを生成する必要があり、スキャンが完了する前に有効期限が切れる場合は、DAST API スキャナにプログラムまたはスクリプトを提供して、指定した間隔で実行させることができます。提供されたスクリプトは、Python 3 と Bash がインストールされた Alpine Linux コンテナで実行されます。Python スクリプトに追加パッケージが必要な場合は、それを検出して実行時にパッケージをインストールする必要があります。
スクリプトは、ベアラ・トークンを特定の形式で含むJSONファイルを作成する必要があります:
{
"headers" : {
"Authorization" : "Bearer dXNlcm5hbWU6cGFzc3dvcmQ="
}
}
3つのCI/CD変数を提供する必要があり、それぞれ正しくオペレーションできるように設定されています:
-
DAST_API_OVERRIDES_FILE
:コマンドが生成するJSONファイル。 -
DAST_API_OVERRIDES_CMD
:JSONファイルを生成するコマンド。 -
DAST_API_OVERRIDES_INTERVAL
:コマンドを実行する間隔(秒)。
使用例:
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_PROFILE: Quick
DAST_API_OPENAPI: test-api-specification.json
DAST_API_TARGET_URL: http://test-deployment/
DAST_API_OVERRIDES_FILE: dast-api-overrides.json
DAST_API_OVERRIDES_CMD: renew_token.py
DAST_API_OVERRIDES_INTERVAL: 300
認証が機能していることを確認するには、DAST API テストを実行し、ジョブ・ログとテスト API のアプリ ケーション・ログをレビューします。オーバーライド・コマンドの詳細については、「オーバーライド」のセクションを参照してください。
設定ファイル
すぐに始められるように、GitLab は設定ファイルgitlab-dast-api-config.yml
を用意しています。このファイルには、さまざまな数のテストを実行するいくつかのテストプロファイルがあります。各プロファイルの実行時間は、テストの数が増えるにつれて長くなります。設定ファイルを使うには、リポジトリのルートに.gitlab/gitlab-dast-api-config.yml
のように追加します。
プロファイル
以下のプロファイルは、デフォルト設定ファイルにあらかじめ定義されています。カスタム設定を作成することで、プロファイルを追加、削除、変更できます。
受動的
- アプリケーション情報チェック
- クリアテキスト認証チェック
- JSONハイジャック・チェック
- 機密情報チェック
- セッションクッキーチェック
クイック
- アプリケーション情報チェック
- クリアテキスト認証チェック
- フレームワークデバッグモードチェック
- HTMLインジェクションチェック
- 安全でない Http メソッドのチェック
- JSONハイジャック・チェック
- JSONインジェクション検査
- 機密情報チェック
- セッションクッキーチェック
- SQLインジェクション検査
- トークンのチェック
- XMLインジェクション検査
フル
- アプリケーション情報チェック
- クリアテキスト認証チェック
- CORSチェック
- DNSリバインディングチェック
- フレームワークデバッグモードチェック
- HTMLインジェクションチェック
- 安全でない Http メソッドのチェック
- JSONハイジャック・チェック
- JSONインジェクション検査
- オープンリダイレクト検査
- 機密ファイルチェック
- 機密情報チェック
- セッションクッキーチェック
- SQLインジェクション検査
- TLS設定チェック
- トークンのチェック
- XMLインジェクション検査
利用可能な CI/CD 変数
CI/CD 変数 | 説明 |
---|---|
SECURE_ANALYZERS_PREFIX | アナライザをダウンロードするDockerレジストリのベースアドレスを指定します。 |
DAST_API_VERSION | DAST APIコンテナバージョンを指定します。デフォルトは2 。 |
DAST_API_IMAGE_SUFFIX | コンテナイメージのサフィックスを指定します。デフォルトはnone。 |
DAST_API_API_PORT | DAST API エンジンが使用する通信ポート番号を指定します。デフォルトは5500 。 GitLab 15.5 で導入されました。 |
DAST_API_TARGET_URL | APIテスト対象のベースURL。 |
DAST_API_CONFIG | DAST API 設定ファイル。デフォルトは.gitlab-dast-api.yml 。 |
DAST_API_PROFILE | テスト中に使用する設定プロファイル。デフォルトはQuick 。 |
DAST_API_EXCLUDE_PATHS | API URL パスをテストから除外します。 |
DAST_API_EXCLUDE_URLS | テストからAPI URLを除外GitLab 14.10 で導入されました。 |
DAST_API_EXCLUDE_PARAMETER_ENV | 除外するパラメータを含むJSON文字列。 |
DAST_API_EXCLUDE_PARAMETER_FILE | 除外されたパラメータを含むJSONファイルへのパス。 |
DAST_API_REQUEST_HEADERS | 各スキャン要求に含めるヘッダのカンマ区切り (, ) リスト。文字セットの制限があるマスク変数にシークレットヘッダ値を格納するときは、DAST_API_REQUEST_HEADERS_BASE64 の使用を考慮してください。 |
DAST_API_REQUEST_HEADERS_BASE64 | 各スキャンリクエストに含めるヘッダのカンマ区切り (, ) リスト。Base64 エンコードされています。GitLab 15.6 で導入されました。 |
DAST_API_OPENAPI | OpenAPI 仕様ファイルまたは URL。 |
DAST_API_OPENAPI_RELAXED_VALIDATION | ドキュメント検証を緩和します。デフォルトは無効。GitLab 14.7 で導入されました。GitLabチームメンバーはこちらのイシューをご覧ください:https://gitlab.com/gitlab-org/gitlab/-/issues/345950
|
DAST_API_OPENAPI_ALL_MEDIA_TYPES | リクエストを生成する際に、1つのメディアタイプではなく、サポートされているすべてのメディアタイプを使用します。テスト時間が長くなります。デフォルトは無効です。GitLab 14.10 で導入。 |
DAST_API_OPENAPI_MEDIA_TYPES | コロン (: ) 区切りのメディアタイプ。デフォルトは無効。GitLab 14.10 で導入。 |
DAST_API_HAR | HTTP アーカイブ(HAR) ファイル。 |
DAST_API_GRAPHQL | GraphQLエンドポイントへのパス、例えば/api/graphql 。GitLab 15.4で導入されました。 |
DAST_API_GRAPHQL_SCHEMA | JSON形式のGraphQLスキーマのURLまたはファイル名。GitLab 15.4で導入。 |
DAST_API_POSTMAN_COLLECTION | Postman コレクションファイル。 |
DAST_API_POSTMAN_COLLECTION_VARIABLES | Postman変数の値を抽出するJSONファイルへのパス。カンマ区切り (, ) ファイルのサポートは GitLab 15.1 で導入されました。 |
DAST_API_OVERRIDES_FILE | オーバーライドを含むJSONファイルへのパス。 |
DAST_API_OVERRIDES_ENV | オーバーライドするヘッダーを含む JSON 文字列。 |
DAST_API_OVERRIDES_CMD | コマンドを上書きします。 |
DAST_API_OVERRIDES_CMD_VERBOSE | 任意の値に設定するとジョブ出力の一部としてオーバーライドコマンド出力を表示します。GitLab 14.6で導入されました。 |
DAST_API_PRE_SCRIPT | スキャンセッションが始まる前にユーザーコマンドやスクリプトを実行します。 |
DAST_API_POST_SCRIPT | スキャン セッション終了後にユーザー コマンドまたはスクリプトを実行します。 |
DAST_API_OVERRIDES_INTERVAL | オーバーライド コマンドを実行する頻度を秒単位で指定します。デフォルトは0 (1 回) です。 |
DAST_API_HTTP_USERNAME | HTTP認証のユーザー名。 |
DAST_API_HTTP_PASSWORD | HTTP認証用のパスワード。代わりにDAST_API_HTTP_PASSWORD_BASE64 。 |
DAST_API_HTTP_PASSWORD_BASE64 | base64エンコードされたHTTP認証用のパスワード。GitLab 15.4で導入されました。 |
DAST_API_SERVICE_START_TIMEOUT | ターゲットAPIが利用可能になるまでの待ち時間(秒)。デフォルトは300秒です。 |
DAST_API_TIMEOUT | APIの応答を待つ時間(秒)。デフォルトは30秒です。 |
オーバーライド
DAST API は、リクエストに特定の項目を追加したりオーバーライドしたりするメソッドを提供します:
- ヘッダー
- クッキー
- クエリ文字列
- フォームデータ
- JSONノード
- XMLノード
これを使用して、セマンティック・バージョン・ヘッダや認証などを注入できます。認証のセクションには、オーバーライドの使用例が記載されています。
オーバーライドは JSON ドキュメントを使用し、オーバーライドの各タイプは JSON オブジェクトで表されます:
{
"headers": {
"header1": "value",
"header2": "value"
},
"cookies": {
"cookie1": "value",
"cookie2": "value"
},
"query": {
"query-string1": "value",
"query-string2": "value"
},
"body-form": {
"form-param1": "value",
"form-param2": "value"
},
"body-json": {
"json-path1": "value",
"json-path2": "value"
},
"body-xml" : {
"xpath1": "value",
"xpath2": "value"
}
}
単一のヘッダーを設定する例:
{
"headers": {
"Authorization": "Bearer dXNlcm5hbWU6cGFzc3dvcmQ="
}
}
ヘッダーとクッキーの両方を設定する例:
{
"headers": {
"Authorization": "Bearer dXNlcm5hbWU6cGFzc3dvcmQ="
},
"cookies": {
"flags": "677"
}
}
body-form
オーバーライドを設定する場合の使用例:
{
"body-form": {
"username": "john.doe"
}
}
オーバーライド・エンジンは、リクエスト・ボディにフォーム・データ・コンテンツのみがある場合にbody-form
を使用します。
body-json
オーバーライドを設定する場合の使用例:
{
"body-json": {
"$.credentials.access-token": "iddqd!42.$"
}
}
オブジェクトbody-json
内の各 JSON プロパティ名は、JSON Path式に設定されます。JSON Path 式$.credentials.access-token
は、値iddqd!42.$
でオーバーライドするノードを識別します。オーバーライド・エンジンは、リクエスト・ボディにJSONコンテンツのみがある場合、body-json
を使用します。
例えば、ボディが以下の JSON に設定されている場合:
{
"credentials" : {
"username" :"john.doe",
"access-token" : "non-valid-password"
}
}
に変更されます:
{
"credentials" : {
"username" :"john.doe",
"access-token" : "iddqd!42.$"
}
}
body-xml
をオーバーライドする例を示します。最初のエントリは XML 属性をオーバーライドし、2 番目のエントリは XML 要素をオーバーライドします:
{
"body-xml" : {
"/credentials/@isEnabled": "true",
"/credentials/access-token/text()" : "iddqd!42.$"
}
}
オブジェクトbody-xml
内の各 JSON プロパティ名は、XPath v2式に設定されます。XPath 式/credentials/@isEnabled
は、値true
でオーバーライドする属性ノードを識別します。XPath 式/credentials/access-token/text()
は、オーバーライドする要素ノードを値iddqd!42.$
で識別します。オーバーライド・エンジンは、リクエスト・ボディにXMLコンテンツのみがある場合にbody-xml
を使用します。
例えば、ボディが以下の XML に設定されている場合:
<credentials isEnabled="false">
<username>john.doe</username>
<access-token>non-valid-password</access-token>
</credentials>
に変更されます:
<credentials isEnabled="true">
<username>john.doe</username>
<access-token>iddqd!42.$</access-token>
</credentials>
このJSONドキュメントは、ファイルまたは環境変数として提供できます。また、JSONドキュメントを生成するコマンドを指定することもできます。このコマンドは、期限切れの値をサポートするために間隔を空けて実行できます。
ファイルの使用
オーバーライドJSONをファイルとして提供するには、DAST_API_OVERRIDES_FILE
CI/CD変数が設定されます。パスはジョブの現在の作業ディレクトリからの相対パスです。
以下は.gitlab-ci.yml
の例です:
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_PROFILE: Quick
DAST_API_OPENAPI: test-api-specification.json
DAST_API_TARGET_URL: http://test-deployment/
DAST_API_OVERRIDES_FILE: dast-api-overrides.json
CI/CD変数の使用
オーバーライド JSON を CI/CD 変数として提供するには、DAST_API_OVERRIDES_ENV
変数を使用します。これにより、JSON をマスクして保護できる変数として配置できます。
この例では、.gitlab-ci.yml
、DAST_API_OVERRIDES_ENV
変数が直接 JSON に設定されます:
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_PROFILE: Quick
DAST_API_OPENAPI: test-api-specification.json
DAST_API_TARGET_URL: http://test-deployment/
DAST_API_OVERRIDES_ENV: '{"headers":{"X-API-Version":"2"}}'
この例では、.gitlab-ci.yml
、SECRET_OVERRIDES
変数がJSONを提供します。これはUIで定義されたグループまたはインスタンスレベルのCI/CD変数です:
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_PROFILE: Quick
DAST_API_OPENAPI: test-api-specification.json
DAST_API_TARGET_URL: http://test-deployment/
DAST_API_OVERRIDES_ENV: $SECRET_OVERRIDES
コマンドの使用
期限切れ時に値を生成または再生成する必要がある場合、DAST API スキャナにプログラムまたはスクリプトを提供して、指定した間隔で実行させることができます。提供されたコマンドは、Python 3 と Bash がインストールされた Alpine Linux コンテナで実行されます。
実行したいプログラムまたはスクリプトに環境変数DAST_API_OVERRIDES_CMD
を設定する必要があります。提供されるコマンドは、先に定義したオーバーライドJSONファイルを作成します。
NodeJSやRubyのような他のスクリプト・ランタイムをインストールしたい場合や、overridesコマンドの依存関係をインストールする必要がある場合があります。この場合、DAST_API_PRE_SCRIPT
これらの前提条件を提供するスクリプトのファイル・パスに DAST_API_PRE_SCRIPT
設定することをお勧めします。DAST_API_PRE_SCRIPT
で指定したスクリプトは DAST_API_PRE_SCRIPT
、アナライザが起動する前に一度だけ実行されます。
Alpine Linuxパッケージのインストールについては、Alpine Linuxパッケージ管理ページを参照してください。
3つのCI/CD変数を提供する必要があり、それぞれ正しくオペレーションできるように設定されています:
-
DAST_API_OVERRIDES_FILE
:提供されたコマンドによって生成されたファイル。 -
DAST_API_OVERRIDES_CMD
:定期的にオーバーライドJSONファイルを生成するオーバーライド・コマンド。 -
DAST_API_OVERRIDES_INTERVAL
:コマンドの実行間隔(秒
オプション
-
DAST_API_PRE_SCRIPT
:スキャン開始前にランタイムまたは依存関係をインストールするスクリプト。
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_PROFILE: Quick
DAST_API_OPENAPI: test-api-specification.json
DAST_API_TARGET_URL: http://test-deployment/
DAST_API_OVERRIDES_FILE: dast-api-overrides.json
DAST_API_OVERRIDES_CMD: renew_token.py
DAST_API_OVERRIDES_INTERVAL: 300
デバッグのオーバーライド
GitLab 14.8で導入されました。
デフォルトではoverridesコマンドの出力は非表示です。overridesコマンドが0以外の終了コードを返した場合、コマンドはジョブ出力の一部として表示されます。オプションで、変数DAST_API_OVERRIDES_CMD_VERBOSE
を任意の値に設定して、overrides コマンド出力を生成時に表示できます。これは、overrides スクリプトをテストするときに便利ですが、テストが遅くなるため、テスト後は無効にしてください。
ジョブが完了または失敗したときに収集されるログファイルに、スクリプトからのメッセージを書き込むこともできます。ログファイルは特定の場所に、命名規則に従って作成する必要があります。
オーバーライド・スクリプトに基本的なロギングを追加しておくと、ジョブの標準実行中にスクリプトが予期せず失敗した場合に便利です。ログファイルはジョブのアーティファクトとして自動的に含まれるため、ジョブ終了後にダウンロードできます。
この例では、環境変数DAST_API_OVERRIDES_CMD
にrenew_token.py
を指定しています。スクリプトの中で2つのことに注目してください:
- ログファイルは環境変数
CI_PROJECT_DIR
で指定された場所に保存されます。 - ログファイル名は
gl-*.log
と一致する必要があります。
#!/usr/bin/env python
# Example of an overrides command
# Override commands can update the overrides json file
# with new values to be used. This is a great way to
# update an authentication token that will expire
# during testing.
import logging
import json
import os
import requests
import backoff
# [1] Store log file in directory indicated by env var CI_PROJECT_DIR
working_directory = os.environ.get( 'CI_PROJECT_DIR')
overrides_file_name = os.environ.get('DAST_API_OVERRIDES_FILE', 'dast-api-overrides.json')
overrides_file_path = os.path.join(working_directory, overrides_file_name)
# [2] File name should match the pattern: gl-*.log
log_file_path = os.path.join(working_directory, 'gl-user-overrides.log')
# Set up logger
logging.basicConfig(filename=log_file_path, level=logging.DEBUG)
# Use `backoff` decorator to retry in case of transient errors.
@backoff.on_exception(backoff.expo,
(requests.exceptions.Timeout,
requests.exceptions.ConnectionError),
max_time=30)
def get_auth_response():
authorization_url = 'https://authorization.service/api/get_api_token'
return requests.get(
f'{authorization_url}',
auth=(os.environ.get('AUTH_USER'), os.environ.get('AUTH_PWD'))
)
# In our example, access token is retrieved from a given endpoint
try:
# Performs a http request, response sample:
# { "Token" : "b5638ae7-6e77-4585-b035-7d9de2e3f6b3" }
response = get_auth_response()
# Check that the request is successful. may raise `requests.exceptions.HTTPError`
response.raise_for_status()
# Gets JSON data
response_body = response.json()
# If needed specific exceptions can be caught
# requests.ConnectionError : A network connection error problem occurred
# requests.HTTPError : HTTP request returned an unsuccessful status code. [Response.raise_for_status()]
# requests.ConnectTimeout : The request timed out while trying to connect to the remote server
# requests.ReadTimeout : The server did not send any data in the allotted amount of time.
# requests.TooManyRedirects : The request exceeds the configured number of maximum redirections
# requests.exceptions.RequestException : All exceptions that related to Requests
except json.JSONDecodeError as json_decode_error:
# logs errors related decoding JSON response
logging.error(f'Error, failed while decoding JSON response. Error message: {json_decode_error}')
raise
except requests.exceptions.RequestException as requests_error:
# logs exceptions related to `Requests`
logging.error(f'Error, failed while performing HTTP request. Error message: {requests_error}')
raise
except Exception as e:
# logs any other error
logging.error(f'Error, unknown error while retrieving access token. Error message: {e}')
raise
# computes object that holds overrides file content.
# It uses data fetched from request
overrides_data = {
"headers": {
"Authorization": f"Token {response_body['Token']}"
}
}
# log entry informing about the file override computation
logging.info("Creating overrides file: %s" % overrides_file_path)
# attempts to overwrite the file
try:
if os.path.exists(overrides_file_path):
os.unlink(overrides_file_path)
# overwrites the file with our updated dictionary
with open(overrides_file_path, "wb+") as fd:
fd.write(json.dumps(overrides_data).encode('utf-8'))
except Exception as e:
# logs any other error
logging.error(f'Error, unknown error when overwriting file {overrides_file_path}. Error message: {e}')
raise
# logs informing override has finished successfully
logging.info("Override file has been updated")
# end
overrides コマンドの例では、Python スクリプトはbackoff
ライブラリに依存しています。Python スクリプトを実行する前にライブラリがインストールされていることを確認するために、DAST_API_PRE_SCRIPT
は overrides コマンドの依存関係をインストールするスクリプトに設定されます。たとえば、次のスクリプトのようになります。user-pre-scan-set-up.sh
#!/bin/bash
# user-pre-scan-set-up.sh
# Ensures python dependencies are installed
echo "**** install python dependencies ****"
python3 -m ensurepip
pip3 install --no-cache --upgrade \
pip \
backoff
echo "**** python dependencies installed ****"
# end
DAST_API_PRE_SCRIPT
を新しいuser-pre-scan-set-up.sh
スクリプトに設定するように設定を更新する必要があります。例えば
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_PROFILE: Quick
DAST_API_OPENAPI: test-api-specification.json
DAST_API_TARGET_URL: http://test-deployment/
DAST_API_PRE_SCRIPT: user-pre-scan-set-up.sh
DAST_API_OVERRIDES_FILE: dast-api-overrides.json
DAST_API_OVERRIDES_CMD: renew_token.py
DAST_API_OVERRIDES_INTERVAL: 300
前のサンプルでは、user-pre-scan-set-up.sh
スクリプトを使用して、後で overrides コマンドで使用する新しいランタイムやアプリケーションもインストールできました。
リクエストヘッダー
リクエストヘッダ機能を使うと、スキャンセッション中のヘッダに固定値を指定できます。例えば、設定変数DAST_API_REQUEST_HEADERS
を使用して、Cache-Control
ヘッダーに固定値を設定できます。設定する必要があるヘッダーにAuthorization
ヘッダーのような敏感な値が含まれる場合、変数DAST_API_REQUEST_HEADERS_BASE64
とともにマスクされた変数機能を使用します。
スキャンの進行中にAuthorization
ヘッダーやその他のヘッダーを更新する必要がある場合は、オーバーライド機能の使用を検討してください。
変数DAST_API_REQUEST_HEADERS
、ヘッダのカンマ区切り(,
)リストを指定できます。これらのヘッダーはスキャナが実行する各リクエストに含まれます。リストの各ヘッダーエントリは、名前の後にコロン(:
)、その後に値で構成されます。キーまたは値の前の空白は無視されます。例えば、ヘッダー名Cache-Control
と値max-age=604800
を宣言するには、ヘッダーエントリーはCache-Control: max-age=604800
.2つのヘッダー、 Cache-Control: max-age=604800
Age: 100
をCache-Control: max-age=604800
使用するには Cache-Control: max-age=604800
、DAST_API_REQUEST_HEADERS
変数をCache-Control: max-age=604800, Age: 100
に設定します。
異なるヘッダーを変数に入れる順番はDAST_API_REQUEST_HEADERS
結果に影響しません DAST_API_REQUEST_HEADERS
。Cache-Control: max-age=604800, Age: 100
にDAST_API_REQUEST_HEADERS
設定しても DAST_API_REQUEST_HEADERS
、Age: 100, Cache-Control: max-age=604800
に設定したのと同じ結果になります。
Base64
DAST_API_REQUEST_HEADERS_BASE64
変数はDAST_API_REQUEST_HEADERS
と同じヘッダーのリストを受け付けますが、唯一の違いは変数の値全体が Base64 エンコードされていなければならないということです。例えば、DAST_API_REQUEST_HEADERS_BASE64
変数をAuthorization: QmVhcmVyIFRPS0VO, Cache-control: bm8tY2FjaGU=
に設定するためには、リストをBase64の等価値:QXV0aG9yaXphdGlvbjogUW1WaGNtVnlJRlJQUzBWTywgQ2FjaGUtY29udHJvbDogYm04dFkyRmphR1U9
に変換し、Base64エンコードされた値を使わなければなりません。これは、文字セットの制限があるマスクされた変数にシークレットヘッダー値を格納するときに便利です。
例プレーンテキストを使って各リクエストにヘッダのリストを追加する場合
.gitlab-ci.yml
の次の例では、DAST_API_REQUEST_HEADERS
設定変数がリクエストヘッダで説明されているように 2 つのヘッダ値を提供するように設定されています。
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_PROFILE: Quick
DAST_API_OPENAPI: test-api-specification.json
DAST_API_TARGET_URL: http://test-deployment/
DAST_API_REQUEST_HEADERS: 'Cache-control: no-cache, Save-Data: on'
例マスクされたCI/CD変数の使用
以下の.gitlab-ci.yml
サンプルは、マスクされた変数が SECRET_REQUEST_HEADERS_BASE64
UIで定義されたグループまたはインスタンスレベルのCI/CD変数として定義されて SECRET_REQUEST_HEADERS_BASE64
いると仮定しています。SECRET_REQUEST_HEADERS_BASE64
の値は SECRET_REQUEST_HEADERS_BASE64
、X-ACME-Secret: s3cr3t!, X-ACME-Token: 705d16f5e3fb
の Base64 エンコードされたテキストバージョンであるWC1BQ01FLVNlY3JldDogc31jcnt0ISwgWC1BQ01FLVRva2VuOiA3MDVkMTZmNWUzZmI=
に設定されます。そして、次のように使用することができます:
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_PROFILE: Quick
DAST_API_OPENAPI: test-api-specification.json
DAST_API_TARGET_URL: http://test-deployment/
DAST_API_REQUEST_HEADERS_BASE64: $SECRET_REQUEST_HEADERS_BASE64
文字セットの制限があるマスクされた変数にシークレットヘッダーの値を格納するときは、DAST_API_REQUEST_HEADERS_BASE64
の使用を検討してください。
除外パス
GitLab 14.0 で導入されました。
APIをテストする際に、特定のパスを除外すると便利です。例えば、認証サービスや古いバージョンのAPIのテストを除外することができます。パスを除外するには、DAST_API_EXCLUDE_PATHS
CI/CD 変数を使います。この変数は.gitlab-ci.yml
ファイルで指定します。複数のパスを除外するには、;
文字を使用してエントリを区切ります。提供されたパスでは、1文字のワイルドカード?
と複数文字のワイルドカード*
を使用できます。
パスが除外されていることを確認するには、ジョブ出力のTested Operations
とExcluded Operations
の部分をレビューします。Tested Operations
の下に除外されたパスは表示されないはずです。
2021-05-27 21:51:08 [INF] DAST API: --[ Tested Operations ]-------------------------
2021-05-27 21:51:08 [INF] DAST API: 201 POST http://target:7777/api/users CREATED
2021-05-27 21:51:08 [INF] DAST API: ------------------------------------------------
2021-05-27 21:51:08 [INF] DAST API: --[ Excluded Operations ]-----------------------
2021-05-27 21:51:08 [INF] DAST API: GET http://target:7777/api/messages
2021-05-27 21:51:08 [INF] DAST API: POST http://target:7777/api/messages
2021-05-27 21:51:08 [INF] DAST API: ------------------------------------------------
使用例
この例では/auth
リソースを除外します。子リソース (/auth/child
) は除外しません。
variables:
DAST_API_EXCLUDE_PATHS: /auth
/auth
、および子リソース (/auth/child
) を除外するには、ワイルドカードを使用します。
variables:
DAST_API_EXCLUDE_PATHS: /auth*
複数のパスを除外するには、;
を使用します。この例では、/auth*
と/v1/*
を除外しています。
variables:
DAST_API_EXCLUDE_PATHS: /auth*;/v1/*
パス内の1つ以上の入れ子レベルを除外するには、**
を使用します。この例では、API エンドポイントをテストしています。planet
,moon
,star
,satellite
オブジェクトのmass
,brightness
,coordinates
データを要求するデータクエリの/api/v1/
と/api/v2/
をテストしています。スキャンされる可能性のあるパスの例には以下が含まれますが、これらに限定されるものではありません:
/api/v2/planet/coordinates
/api/v1/star/mass
/api/v2/satellite/brightness
この例では、brightness
エンドポイントのみをテストします:
variables:
DAST_API_EXCLUDE_PATHS: /api/**/mass;/api/**/coordinates
パラメータの除外
GitLab 14.10で導入されました。
APIのテスト中に、あるパラメータ(クエリ文字列、ヘッダ、ボディ要素)をテストから除外したいことがあるかもしれません。これは、あるパラメータが常に失敗を引き起こしたり、テストが遅くなったり、その他の理由で必要になることがあります。パラメータを除外するには、次の変数のいずれかを設定します:DAST_API_EXCLUDE_PARAMETER_ENV
あるいはDAST_API_EXCLUDE_PARAMETER_FILE
。
DAST_API_EXCLUDE_PARAMETER_ENV
では、除外するパラメータを含む JSON 文字列を指定できます。これは、JSONが短く、頻繁に変更されない場合に有効なオプションです。もう1つのオプションは、変数DAST_API_EXCLUDE_PARAMETER_FILE
です。この変数は、リポジトリにチェックインするか、別のジョブがアーティファクトとして作成するか、DAST_API_PRE_SCRIPT
を使用してプリスクリプトで実行時に生成できるファイルパスに設定されます。
JSONドキュメントを使用したパラメータの除外
JSONドキュメントにはJSONオブジェクトが含まれており、このオブジェクトは特定のプロパティを使用して、除外するパラメータを特定します。スキャン処理中に特定のパラメータを除外するには、以下のプロパティを指定します:
-
headers
:特定のヘッダを除外するには、このプロパティを使用します。プロパティの値は、除外するヘッダ名の配列です。名前の大文字と小文字は区別されません。 -
cookies
:特定のクッキーを除外するには、このプロパティの値を使用します。このプロパティの値は、除外するクッキー名の配列です。名前の大文字と小文字は区別されます。 -
query
:クエリ文字列から特定のフィールドを除外するには、このプロパティを使用します。プロパティの値は、除外するクエリ文字列のフィールド名の配列です。名前の大文字と小文字は区別されます。 -
body-form
:このプロパティを使用して、メディア・タイプapplication/x-www-form-urlencoded
を使用する要求から特定のフィールドを除外します。このプロパティの値は、除外する本文のフィールド名の配列です。名前の大文字と小文字は区別されます。 -
body-json
:このプロパティを使用して、メディアタイプapplication/json
を使用するリクエストから特定の JSON ノードを除外します。プロパティの値は配列で、配列の各エントリはJSON Path式です。 -
body-xml
:このプロパティを使用して、メディアタイプapplication/xml
を使用する要求から特定の XML ノードを除外します。プロパティの値は配列で、配列の各エントリはXPath v2式です。
したがって、以下のJSONドキュメントは、パラメータを除外するために期待される構造の例です。
{
"headers": [
"header1",
"header2"
],
"cookies": [
"cookie1",
"cookie2"
],
"query": [
"query-string1",
"query-string2"
],
"body-form": [
"form-param1",
"form-param2"
],
"body-json": [
"json-path-expression-1",
"json-path-expression-2"
],
"body-xml" : [
"xpath-expression-1",
"xpath-expression-2"
]
}
使用例
単一ヘッダの除外
ヘッダUpgrade-Insecure-Requests
を除外するには、header
プロパティの値を、ヘッダ名:[ "Upgrade-Insecure-Requests" ]
を持つ配列に設定します。例えば、JSONドキュメントは以下のようになります:
{
"headers": [ "Upgrade-Insecure-Requests" ]
}
ヘッダー名は大文字と小文字を区別しないので、ヘッダー名UPGRADE-INSECURE-REQUESTS
はUpgrade-Insecure-Requests
と同じです。
ヘッダと二つのクッキーの両方を除きます。
ヘッダAuthorization
とクッキーPHPSESSID
とcsrftoken
を除外するには、headers
プロパティの値をヘッダ名[ "Authorization" ]
の配列に設定し、cookies
プロパティの値をクッキー名[ "PHPSESSID", "csrftoken" ]
の配列に設定します。例えば、JSONドキュメントは次のようになります:
{
"headers": [ "Authorization" ],
"cookies": [ "PHPSESSID", "csrftoken" ]
}
body-form
パラメータの除外
application/x-www-form-urlencoded
を使用する要求でpassword
フィールドを除外するには、body-form
プロパティの値をフィールド名[ "password" ]
の配列に設定します。例えば、JSONドキュメントは以下のようになります:
{
"body-form": [ "password" ]
}
exclude パラメータは、要求がコンテンツ・タイプapplication/x-www-form-urlencoded
を使用している場合、body-form
を使用します。
JSON Path を使用した特定の JSON ノードの除外
ルート・オブジェクトのschema
プロパティを除外するには、body-json
プロパティの値を、JSON Path 式[ "$.schema" ]
を持つ配列に設定します。
JSON パス式は、JSON ノードを識別するために特別な構文を使用します。$
は JSON ドキュメントのルートを指し、.
は現在のオブジェクト (この場合はルート オブジェクト) を指し、schema
というテキストはプロパティ名を指します。したがって、JSON パス式$.schema
は、ルート オブジェクトのプロパティschema
を参照します。インスタンスのJSONドキュメントは次のようになります:
{
"body-json": [ "$.schema" ]
}
リクエストがコンテンツタイプapplication/json
を使用する場合、 exclude パラメータはbody-json
を使用します。body-json
の各エントリは、JSON Path 式であることが期待されます。$
、*
、.
などの JSON Path 文字は特別な意味を持ちます。
JSON Path を使用した複数の JSON ノードの除外
ルートレベルの配列users
の各エントリでプロパティpassword
を除外するには、body-json
プロパティの値を、JSON Path 式[ "$.users[*].paswword" ]
を持つ配列に設定します。
JSON Path 式は、$
で開始してルート・ノードを参照し、.
を使用して現在のノードを参照します。次に、users
を使用してプロパティを参照し、[
と]
という文字を使用して、使用する配列のインデックスを囲みます。インデックスとして数値を指定する代わりに、*
を使用して任意のインデックスを指定します。インデックス参照の後、.
が見つかります。これは、配列内の任意の選択されたインデックスを参照するもので、その前にプロパティ名password
が付きます。
インスタンスのJSONドキュメントは次のようになります:
{
"body-json": [ "$.users[*].paswword" ]
}
リクエストがコンテンツタイプapplication/json
を使用する場合、 exclude パラメータはbody-json
を使用します。body-json
の各エントリは、JSON Path 式であることが期待されます。$
、*
、.
などの JSON Path 文字は特別な意味を持ちます。
XML 属性の除外
ルート要素credentials
にあるisEnabled
という名前の属性を除外するには、body-xml
プロパティの値を、XPath 式[ "/credentials/@isEnabled" ]
を持つ配列に設定します。
XPath 式/credentials/@isEnabled
は、XML 文書のルートを示す/
で始まり、マッチさせる要素の名前を示すcredentials
が続きます。前の XML 要素のノードを参照するために/
を使用し、名前isEnable
が属性であることを示すために文字@
を使用します。
インスタンスのJSONドキュメントは次のようになります:
{
"body-xml": [
"/credentials/@isEnabled"
]
}
リクエストがコンテントタイプapplication/xml
を使用している場合、 exclude パラメータはbody-xml
を使用します。body-xml
の各エントリは、XPath v2 式であることが期待されます。XPath 式では、@
、/
、:
、[
、]
などの文字が特別な意味を持ちます。
XML テキストの要素の除外
ルート・ノードcredentials
に含まれるusername
要素のテキストを除外するには、body-xml
プロパティの値を、XPath 式[/credentials/username/text()" ]
を持つ配列に設定します。
XPath 式/credentials/username/text()
では、最初の文字/
はルート XML ノードを指し、その後に XML 要素の名前credentials
を示します。同様に、文字/
は現在の要素を参照し、その後に新しい XML 要素の名前username
が続きます。最後の部分には、現在の要素を参照する/
があり、現在の要素のテキストを識別するtext()
という XPath 関数を使用しています。
インスタンスのJSONドキュメントは次のようになります:
{
"body-xml": [
"/credentials/username/text()"
]
}
リクエストがコンテントタイプapplication/xml
を使用している場合、 exclude パラメータはbody-xml
を使用します。body-xml
の各エントリは、XPath v2 式であることが期待されます。XPath 式では、@
、/
、:
、[
、]
などの文字が特別な意味を持ちます。
XML 要素の除外
ルート・ノードcredentials
に含まれる要素username
を除外するには、body-xml
プロパティの値を、XPath 式[/credentials/username" ]
を持つ配列に設定します。
XPath 式/credentials/username
では、最初の文字/
はルート XML ノードを指し、その後に XML 要素の名前credentials
を示します。同様に、文字/
は現在の要素を参照し、その後に新しい XML 要素の名前username
が続きます。
インスタンスのJSONドキュメントは次のようになります:
{
"body-xml": [
"/credentials/username"
]
}
リクエストがコンテントタイプapplication/xml
を使用している場合、 exclude パラメータはbody-xml
を使用します。body-xml
の各エントリは、XPath v2 式であることが期待されます。XPath 式では、@
、/
、:
、[
、]
などの文字が特別な意味を持ちます。
名前空間を持つ XML ノードの除外
名前空間s
で定義され、credentials
ルート・ノード内部に含まれる XML 要素login
を除外するには、body-xml
プロパティの値を、XPath 式[ "/credentials/s:login" ]
を持つ配列に設定します。
XPath 式/credentials/s:login
では、最初の文字/
はルート XML ノードを指し、その後に XML 要素の名前credentials
を示します。同様に、文字/
は現在の要素を指し、その後に新しい XML 要素の名前s:login
が続きます。:
この文字は、名前空間とノード名を分離します。
名前空間名は、ボディ・リクエストの一部である XML ドキュメントで定義されている必要があります。名前空間は、仕様ドキュメント HAR、OpenAPI、または Postman Collection ファイルで確認できます。
{
"body-xml": [
"/credentials/s:login"
]
}
リクエストがコンテントタイプapplication/xml
を使用している場合、 exclude パラメータはbody-xml
を使用します。body-xml
の各エントリはXPath v2 式であることが期待されます。XPathでは、@
,/
,:
,[
,]
などの表現文字は特別な意味を持ちます。
JSON 文字列の使用
除外JSONドキュメントを提供するには、変数DAST_API_EXCLUDE_PARAMETER_ENV
にJSON文字列を設定します。以下の例では、.gitlab-ci.yml
,DAST_API_EXCLUDE_PARAMETER_ENV
変数にJSON文字列が設定されています:
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_PROFILE: Quick
DAST_API_OPENAPI: test-api-specification.json
DAST_API_TARGET_URL: http://test-deployment/
DAST_API_EXCLUDE_PARAMETER_ENV: '{ "headers": [ "Upgrade-Insecure-Requests" ] }'
ファイルの使用
除外JSONドキュメントを提供するために、変数DAST_API_EXCLUDE_PARAMETER_FILE
にJSONファイルパスを設定します。ファイルパスは、ジョブの現在の作業ディレクトリからの相対パスです。次の例.gitlab-ci.yml
の内容では、DAST_API_EXCLUDE_PARAMETER_FILE
変数に JSON ファイルパスが設定されています:
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_PROFILE: Quick
DAST_API_OPENAPI: test-api-specification.json
DAST_API_TARGET_URL: http://test-deployment/
DAST_API_EXCLUDE_PARAMETER_FILE: dast-api-exclude-parameters.json
dast-api-exclude-parameters.json
は、exclude パラメータ文書の構造に従った JSON 文書です。
除外URL
GitLab 14.10で導入されました。
パスで除外する代わりに、DAST_API_EXCLUDE_URLS
CI/CD変数を使ってURL内の他のコンポーネントでフィルタリングすることができます。この変数は.gitlab-ci.yml
ファイルで設定できます。この変数にはカンマ(,
)で区切られた複数の値を格納することができます。各値は正規表現です。各エントリは正規表現なので、.*
のようなエントリは、すべてにマッチする正規表現なので、すべての URL を除外します。
ジョブ出力では、DAST_API_EXCLUDE_URLS
から指定された正規表現に一致する URL があるかどうかを確認できます。一致するオペレーションは、[除外されたオペレーション]セクションにリストされています。Excluded OperationsセクションにリストされたオペレーションはTested Operationsセクションにリストされるべきではありません。たとえば、ジョブ出力の次の部分です:
2021-05-27 21:51:08 [INF] DAST API: --[ Tested Operations ]-------------------------
2021-05-27 21:51:08 [INF] DAST API: 201 POST http://target:7777/api/users CREATED
2021-05-27 21:51:08 [INF] DAST API: ------------------------------------------------
2021-05-27 21:51:08 [INF] DAST API: --[ Excluded Operations ]-----------------------
2021-05-27 21:51:08 [INF] DAST API: GET http://target:7777/api/messages
2021-05-27 21:51:08 [INF] DAST API: POST http://target:7777/api/messages
2021-05-27 21:51:08 [INF] DAST API: ------------------------------------------------
DAST_API_EXCLUDE_URLS
の各値は正規表現です。.
、*
、$
などの文字はDAST_API_EXCLUDE_URLS
正規DAST_API_EXCLUDE_URLS
表現で特別な意味を持ちます。使用例
URLと子リソースの除外
次の例は、URLhttp://target/api/auth
とその子リソースを除外します。
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_TARGET_URL: http://target/
DAST_API_OPENAPI: test-api-specification.json
DAST_API_EXCLUDE_URLS: http://target/api/auth
2つのURLを除外し、その子リソースを許可します。
http://target/api/buy
とhttp://target/api/sell
のURLを除外し、その子リソースのスキャンを許可するには、インスタンス:http://target/api/buy/toy
またはhttp://target/api/sell/chair
.http://target/api/buy/$,http://target/api/sell/$
という値を使用できます。この値は、,
文字で区切られた 2 つの正規表現を使用しています。したがって、http://target/api/buy$
とhttp://target/api/sell$
をコンテナとして含んでいます。 それぞれの正規表現において、末尾の$
文字は、マッチする URL がどこで終わるべきかを示しています。
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_TARGET_URL: http://target/
DAST_API_OPENAPI: test-api-specification.json
DAST_API_EXCLUDE_URLS: http://target/api/buy/$,http://target/api/sell/$
つのURLとその子リソースの除外
http://target/api/buy
とhttp://target/api/sell
のURLとその子リソースを除外します。複数のURLを指定するには、,
の文字を次のように使用します:
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_TARGET_URL: http://target/
DAST_API_OPENAPI: test-api-specification.json
DAST_API_EXCLUDE_URLS: http://target/api/buy,http://target/api/sell
正規表現を使用したURLの除外
https://target/api/v1/user/create
、https://target/api/v2/user/create
、またはその他のバージョン(v3
、v4
、およびその他)を正確に除外するには。https://target/api/v.*/user/create$
.
は任意の文字、*
は0回以上を表し、さらに$
は URL がそこで終わることを表します。
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_TARGET_URL: http://target/
DAST_API_OPENAPI: test-api-specification.json
DAST_API_EXCLUDE_URLS: https://target/api/v.*/user/create$
最初のスキャンの実行
正しく設定されている場合、CI/CDパイプラインはdast
ステージとdast_api
ジョブを含んでいます。ジョブが失敗するのは、無効な設定が提供されたときだけです。典型的なオペレーションでは、テスト中に脆弱性が特定されたとしても、ジョブは常に成功します。
脆弱性はセキュリティパイプラインタブにスイート名とともに表示されます。リポジトリのデフォルトブランチに対してテストを行う場合、DAST API の脆弱性はセキュリティとコンプライアンスの脆弱性レポートページにも表示されます。
報告される脆弱性の数が過剰になるのを防ぐため、DAST API スキャナはオペレーションごとに報告する脆弱性の数を制限しています。
DAST API 脆弱性の表示
DAST API アナライザは、脆弱性を GitLab 脆弱性スクリーンに入力するために収集・使用される JSON レポートを作成します。
報告される偽陽性の数を制限するための設定変更については、偽陽性の処理を参照してください。
DAST API 脆弱性の詳細を見る
脆弱性の詳細を表示するには、以下の手順に従ってください:
-
プロジェクトまたはマージリクエストの脆弱性を表示できます:
- プロジェクトで、プロジェクトのセキュリティ > 脆弱性レポートページに移動します。このページには、デフォルトブランチからのすべての脆弱性のみが表示されます。
- マージリクエストでは、マージリクエストの [セキュリティ] セクションに移動し、[展開] ボタンを選択します。DAST API 脆弱性は、DAST detected N potential vulnerabilitiesというラベルの付いたセクションで確認できます。タイトルを選択すると、脆弱性の詳細が表示されます。
-
脆弱性のタイトルを選択すると、詳細が表示されます。これらの詳細については、以下の表を参照してください。
項目 説明 説明 何が変更されたかを含む脆弱性の説明。 プロジェクト 脆弱性が検出された名前空間とプロジェクト。 方法 脆弱性の検出に使用される HTTP メソッド。 URL 脆弱性が検出されたURL。 リクエスト 脆弱性の原因となった HTTP リクエスト。 変更されていないレスポンス 変更されていないリクエストのレスポンスです。これが典型的なレスポンスです。 実際のレスポンス テストリクエストから受信したレスポンス。 証拠 脆弱性が発生したと判断した方法。 識別子 この脆弱性を発見するために使用された DAST API 検査。 深刻度 脆弱性の深刻度。 スキャナの種類 テストに使用するスキャナ。
セキュリティダッシュボード
セキュリティダッシュボードは、あなたのグループ、プロジェクト、パイプラインのすべてのセキュリティ脆弱性の概要を把握するのに適した場所です。詳細については、セキュリティダッシュボードのドキュメントを参照してください。
脆弱性との対話
脆弱性が見つかったら、それに対処することができます。脆弱性へのアドレスについては、こちらをご覧ください。
誤検出への対処
誤検出にはいくつかの対処法があります:
- 脆弱性を棄却します。
- 検査によっては、脆弱性が特定されたときにそれを検出するためのいくつかの方法(_アサーションと_呼ばれる)があります。アサーションはオフにしたり設定したりすることもできます。例えば、DAST API スキャナのデフォルトでは、HTTP ステータスコードを使用して、何かが本当のイシューであることを識別します。テスト中にAPIが500エラーを返すと、脆弱性が発生します。フレームワークによっては500エラーを頻繁に返すものもあるので、これは必ずしも望ましいことではありません。
- 偽陽性を生成するチェックをオフにしてください。これは、チェックが脆弱性を生成するのを防ぎます。チェックの例としては、SQL インジェクションチェックや JSON ハイジャックチェックがあります。
チェックをオフに
チェックは特定のタイプのテストを実行し、特定の設定プロファイルに対してオン/オフを切り替えることができます。提供される設定ファイルには、使用できるプロファイルがいくつか定義されています。設定ファイルのプロファイル定義には、スキャン中にアクティブになるすべてのチェックがリストされています。特定のチェックをオフにするには、設定ファイルのプロファイル定義からそのチェックを削除します。プロファイルは、設定ファイルのProfiles
セクションで定義します。
プロファイル定義の例:
Profiles:
- Name: Quick
DefaultProfile: Empty
Routes:
- Route: *Route0
Checks:
- Name: ApplicationInformationCheck
- Name: CleartextAuthenticationCheck
- Name: FrameworkDebugModeCheck
- Name: HtmlInjectionCheck
- Name: InsecureHttpMethodsCheck
- Name: JsonHijackingCheck
- Name: JsonInjectionCheck
- Name: SensitiveInformationCheck
- Name: SessionCookieCheck
- Name: SqlInjectionCheck
- Name: TokenCheck
- Name: XmlInjectionCheck
JSONハイジャックチェックをオフにするには、以下の行を削除してください:
- Name: JsonHijackingCheck
この結果、YAMLは次のようになります:
- Name: Quick
DefaultProfile: Empty
Routes:
- Route: *Route0
Checks:
- Name: ApplicationInformationCheck
- Name: CleartextAuthenticationCheck
- Name: FrameworkDebugModeCheck
- Name: HtmlInjectionCheck
- Name: InsecureHttpMethodsCheck
- Name: JsonInjectionCheck
- Name: SensitiveInformationCheck
- Name: SessionCookieCheck
- Name: SqlInjectionCheck
- Name: TokenCheck
- Name: XmlInjectionCheck
チェックのアサーションをオフにします
アサーションは、検査によって生成されたテストの脆弱性を検出します。多くの検査では、ログ解析、レスポンス解析、ステータスコードなど、複数のアサーションをサポートしています。脆弱性が検出されると、使用されるアサーションが提供されます。どのアサーションがデフォルトで有効になっているかを確認するには、設定ファイルの Checks default configuration を参照してください。Checks
というセクションがあります。
この例はSQLインジェクション・チェックを示しています:
- Name: SqlInjectionCheck
Configuration:
UserInjections: []
Assertions:
- Name: LogAnalysisAssertion
- Name: ResponseAnalysisAssertion
- Name: StatusCodeAssertion
デフォルトで 3 つのアサーションがオンになっていることがわかります。よくある誤検出の原因はStatusCodeAssertion
です。これをオフにするには、Profiles
セクションの設定を変更してください。この例では、他の2つのアサーション (LogAnalysisAssertion
,ResponseAnalysisAssertion
) だけを提供しています。これにより、SqlInjectionCheck
がStatusCodeAssertion
を使用することを防ぎます:
Profiles:
- Name: Quick
DefaultProfile: Empty
Routes:
- Route: *Route0
Checks:
- Name: ApplicationInformationCheck
- Name: CleartextAuthenticationCheck
- Name: FrameworkDebugModeCheck
- Name: HtmlInjectionCheck
- Name: InsecureHttpMethodsCheck
- Name: JsonHijackingCheck
- Name: JsonInjectionCheck
- Name: SensitiveInformationCheck
- Name: SessionCookieCheck
- Name: SqlInjectionCheck
Assertions:
- Name: LogAnalysisAssertion
- Name: ResponseAnalysisAssertion
- Name: TokenCheck
- Name: XmlInjectionCheck
オフライン環境での DAST API の実行
インターネットを介した外部リソースへのアクセスが制限されている、制限されている、または断続的な環境にある自己管理型 GitLab インスタンスでは、DAST API テストジョブを正常に実行するためにいくつかの調整が必要です。
ステップ
- ローカルのコンテナレジストリにDockerイメージをホストします。
-
SECURE_ANALYZERS_PREFIX
をローカル・コンテナ・レジストリに設定します。
DAST API 用の Docker イメージを公開レジストリからプル(ダウンロード)し、ローカルレジストリにプッシュ(インポート)する必要があります。Dockerイメージをローカルにホストするには、GitLabコンテナレジストリを使用します。このプロセスは特別なテンプレートを使って実行できます。手順についてはオフラインホストへのDockerイメージのロードを参照してください。
Dockerイメージがローカルにホストされると、SECURE_ANALYZERS_PREFIX
変数にローカルレジストリの場所が設定されます。この変数は、/api-security:2
を連結すると有効なイメージの場所になるように設定する必要があります。
api-security:2
を使用します。例えば、以下の行はregistry.gitlab.com/security-products/api-security:2
というイメージのレジストリを設定します:
SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/security-products"
SECURE_ANALYZERS_PREFIX
を設定すると、すべてのGitLab SecureテンプレートのDockerイメージレジストリの場所が変更されます。詳細については、オフライン環境を参照してください。
パフォーマンス・チューニングとテスト速度
DAST API のような、動的な分析テストを実施するセキュリティツールは、実行中のアプリケーションのインスタンスにリクエストを 送ることによってテストを実施します。リクエストは、アプリケーションに存在するかもしれない特定の脆弱性をテストするように設計されています。動的解析テストの速度は、以下に依存します:
- ファジングツールがアプリケーションに送信できる1秒あたりのリクエスト数
- アプリケーションがリクエストに応答する速度
- アプリケーションのテストに必要なリクエスト数
- APIがいくつのオペレーションで構成されているか
- 各オペレーションに含まれるフィールドの数(JSONボディ、ヘッダー、クエリ文字列、クッキーなど)
このパフォーマンスガイドのアドバイスに従っても、DAST API テストジョブに予想以上の時間がかかる場合は、サポートにお問い合わせください。
パフォーマンスの問題の診断
パフォーマンスの問題を解決するための最初のステップは、テスト時間が予想よりも遅い原因となっている貢献者を理解することです。よく見られるイシューは以下のとおりです:
- DAST APIが低速またはシングルCPUのGitLab Runner上で動作している(GitLab Shared RunnerはシングルCPUです)
- アプリケーションが低速/シングル CPU インスタンスにデプロイされ、テストの負荷に追いついていない場合。
- アプリケーションに全体的なテスト速度に影響を与える遅いオペレーションが含まれている(1/2 秒以上)
- アプリケーションに、大量のデータを返すオペレーションが含まれている(> 500K+) 場合。
- アプリケーションに大量のオペレーションが含まれている (> 40)
アプリケーションに全体的なテスト速度に影響を与える遅いオペレーションが含まれている(1/2 秒以上)
DAST API のジョブ出力には、テスト速度、テスト中の各オペレーションの応答速度、サマリー情報などの有用な情報が含まれています。いくつかのサンプル出力を見て、パフォーマンスの問題を追跡する際にどのように使用できるかを見てみましょう:
DAST API: Loaded 10 operations from: assets/har-large-response/large_responses.har
DAST API:
DAST API: Testing operation [1/10]: 'GET http://target:7777/api/large_response_json'.
DAST API: - Parameters: (Headers: 4, Query: 0, Body: 0)
DAST API: - Request body size: 0 Bytes (0 bytes)
DAST API:
DAST API: Finished testing operation 'GET http://target:7777/api/large_response_json'.
DAST API: - Excluded Parameters: (Headers: 0, Query: 0, Body: 0)
DAST API: - Performed 767 requests
DAST API: - Average response body size: 130 MB
DAST API: - Average call time: 2 seconds and 82.69 milliseconds (2.082693 seconds)
DAST API: - Time to complete: 14 minutes, 8 seconds and 788.36 milliseconds (848.788358 seconds)
このジョブコンソールの出力スニペットは、いくつのオペレーションが見つかったか(10)から始まり、特定のオペレーションでテストが開始されたことの通知と、オペレーションが完了したことの要約が続きます。要約はこのログ出力のもっとも興味深い部分です。要約では、このオペレーションとその関連フィールドを完全にテストするのに DAST API 767 リクエストを要したことがわかります。また、平均応答時間は2秒で、この1つのオペレーションが完了するまでの時間は14分でした。
平均応答時間が2秒であることは、この特定のオペレーションがテストに時間がかかることを示す最初の良い指標です。さらに、レスポンスのボディ・サイズがかなり大きいことがわかります。各リクエストで多くのデータを転送することが、2秒の大部分を占めているのです。
このイシューに対して、チームは次のことを決定するかもしれません:
- マルチCPUランナーの使用。マルチ CPU ランナーを使用することで、DAST API は実行中の作業を Parallels することができます。これはテスト時間の短縮に役立ちますが、テストにかかるオペレーションが長いため、ハイ CPU マシンに移行しない限り、テストを 10 分未満に短縮するのはまだ難しいかもしれません。
- CPU数とコストのトレードオフ。
- このオペレーションを DAST API テストから除外します。これは最も単純ですが、セキュリティテストのカバレッジにギャップが生じるという欠点があります。
- このオペレーションを機能ブランチの DAST API テストから除外しますが、デフォルトブランチのテストには含めます。
- DAST API テストを複数のジョブに分割します。
チームの要件が5-7分の範囲にあると仮定すると、これらの解決策を組み合わせて、許容可能なテスト時間を達成することが考えられます。
パフォーマンス問題へのアドレス
以下のセクションでは、DAST APIのパフォーマンス問題に対処するための様々なオプションについて説明します:
マルチCPUランナーの使用
DAST APIを使ったマルチCPUランナーを使うことで、最も簡単にパフォーマンスを向上させることができます。この表はJava Spring Boot REST APIのベンチマークで収集された統計情報です。このベンチマークでは、ターゲットとDAST APIは単一のRunnerインスタンスを共有しています。
CPU数 | リクエスト/秒 |
---|---|
1CPU(共有ランナー) | 75 |
4 CPU | 255 |
8 CPU | 400 |
この表からわかるように、RunnerのCPU数を増やすことは、テストのスピード/パフォーマンスに大きな影響を与えます。
マルチCPUを使うには、通常、セルフマネージドGitLab RunnerをマルチCPUマシンやクラウドコンピュートインスタンスにデプロイする必要があります。
複数のタイプのGitLab Runnerが使用可能な場合、様々なインスタンスは一般的にジョブ定義でランナーのタイプを選択するために使用できるタグで設定されています。
以下は DAST API 用のジョブ定義の例で、multi-cpu
というタグでtags
セクションを追加しています。このジョブはDAST APIテンプレートに含まれるジョブ定義を自動的に拡張します。
dast_api:
tags:
- multi-cpu
DAST API がランナー内で複数の CPU を検出できることを確認するには、完了したジョブのアーティファクトからgl-api-security-scanner.log
ファイルをダウンロードします。このファイルで文字列Starting work item processor
を検索し、レポーターの最大 DOP (並列度) を調べます。最大DOPは、ランナーに割り当てられたCPU数以上でなければなりません。設定変数によって強制されない限り、シングルCPU Runnerであっても、値が2より小さくなることはありません。レポートされた値がランナーに割り当てられたCPU数より小さい場合、ランナーのデプロイに何か問題があります。問題を特定できない場合は、サポートにチケットを提出してください。
ログエントリの例
17:00:01.084 [INF] <Peach.Web.Core.Services.WebRunnerMachine> Starting work item processor with 2 max DOP
低速オペレーションの除外
遅いオペレーションが1つまたは2つある場合、チームはそのオペレーションのテストを省略することを決定するかもしれません。オペレーションを除外するには、このセクションで説明するように、DAST_API_EXCLUDE_PATHS
設定変数を使用します。
この例では、大量のデータを返すオペレーションがあります。このオペレーションはGET http://target:7777/api/large_response_json
です。これを除外するために、DAST_API_EXCLUDE_PATHS
設定変数にオペレーションURLのパス部分/api/large_response_json
を指定します。
オペレーションが除外されていることを確認するには、DAST API ジョブを実行し、ジョブコンソール出力をレビューします。テストの最後に、含まれるオペレーションと除外されるオペレーションのリストが含まれています。
dast_api:
variables:
DAST_API_EXCLUDE_PATHS: /api/large_response_json
オペレーションをテストから除外すると、脆弱性が発見されない可能性があります。{: .alert .alert-warning} {: .alert .alert-warning
テストの複数ジョブへの分割
DAST API では、DAST_API_EXCLUDE_PATHS
およびDAST_API_EXCLUDE_URLS
を使用することで、テストを複数のジョブに分割することができます。テストを分割する場合、dast_api
のジョブを無効にし、それを識別名のついた 2 つのジョブで置き換えるのがよいパターンです。この例では 2 つのジョブがあり、それぞれのジョブが API のバージョンをテストしているので、名前もそれを反映しています。しかし、このテクニックはAPIのバージョンに限らず、どんな状況にも適用できます。
dast_api_v1
とdast_api_v2
のジョブで使用しているルールは、DAST API テンプレートからコピーしたものです。
# Disable the main dast_api job
dast_api:
rules:
- if: $CI_COMMIT_BRANCH
when: never
dast_api_v1:
extends: dast_api
variables:
DAST_API_EXCLUDE_PATHS: /api/v1/**
rules:
- if: $DAST_API_DISABLED == 'true' || $DAST_API_DISABLED == '1'
when: never
- if: $DAST_API_DISABLED_FOR_DEFAULT_BRANCH == 'true' &&
$CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
when: never
- if: $DAST_API_DISABLED_FOR_DEFAULT_BRANCH == '1' &&
$CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
when: never
- if: $CI_COMMIT_BRANCH &&
$CI_GITLAB_FIPS_MODE == "true"
variables:
DAST_API_IMAGE_SUFFIX: "-fips"
- if: $CI_COMMIT_BRANCH
dast_api_v2:
variables:
DAST_API_EXCLUDE_PATHS: /api/v2/**
rules:
- if: $DAST_API_DISABLED == 'true' || $DAST_API_DISABLED == '1'
when: never
- if: $DAST_API_DISABLED_FOR_DEFAULT_BRANCH == 'true' &&
$CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
when: never
- if: $DAST_API_DISABLED_FOR_DEFAULT_BRANCH == '1' &&
$CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
when: never
- if: $CI_COMMIT_BRANCH &&
$CI_GITLAB_FIPS_MODE == "true"
variables:
DAST_API_IMAGE_SUFFIX: "-fips"
- if: $CI_COMMIT_BRANCH
機能ブランチでのオペレーションを除外し、デフォルトブランチでのオペレーションは除外しないこと。
遅いオペレーションがひとつふたつある場合、チームはそのオペレーションのテストを省略するか、 あるいはそのオペレーションを feature ブランチのテストからは除外して default ブランチのテストには含めることにします。オペレーションを除外するには、DAST_API_EXCLUDE_PATHS
設定変数を使います。
この例では、大量のデータを返すオペレーションがあります。このオペレーションはGET http://target:7777/api/large_response_json
です。このオペレーションを除外するには、DAST_API_EXCLUDE_PATHS
設定変数にオペレーションURL/api/large_response_json
のパス部分を指定します。この設定では、メインのdast_api
ジョブを無効にし、2つの新しいdast_api_main
ジョブとdast_api_branch
.は dast_api_branch
、長いオペレーションを除外し、デフォルト以外のブランチ (たとえば機能ブランチ) でのみ実行するように設定されています。ブランチは dast_api_main
、デフォルトブランチ (この例ではmain
) でのみ実行されるように設定されています。dast_api_branch
のジョブは高速に実行され、開発サイクルを短縮できます。一方、dast_api_main
のジョブはデフォルトブランチのビルドでのみ実行され、実行に時間がかかります。
オペレーションが除外されていることを確認するには、DAST API ジョブを実行し、ジョブコンソール出力をレビューします。テストの最後に、含まれるオペレーションと除外されるオペレーションのリストが含まれています。
# Disable the main job so we can create two jobs with
# different names
dast_api:
rules:
- if: $CI_COMMIT_BRANCH
when: never
# DAST API for feature branch work, excludes /api/large_response_json
dast_api_branch:
extends: dast_api
variables:
DAST_API_EXCLUDE_PATHS: /api/large_response_json
rules:
- if: $DAST_API_DISABLED == 'true' || $DAST_API_DISABLED == '1'
when: never
- if: $DAST_API_DISABLED_FOR_DEFAULT_BRANCH == 'true' &&
$CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
when: never
- if: $DAST_API_DISABLED_FOR_DEFAULT_BRANCH == '1' &&
$CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
when: never
- if: $CI_COMMIT_BRANCH &&
$CI_GITLAB_FIPS_MODE == "true"
variables:
DAST_API_IMAGE_SUFFIX: "-fips"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
when: never
- if: $CI_COMMIT_BRANCH
# DAST API for default branch (main in our case)
# Includes the long running operations
dast_api_main:
extends: dast_api
rules:
- if: $DAST_API_DISABLED == 'true' || $DAST_API_DISABLED == '1'
when: never
- if: $DAST_API_DISABLED_FOR_DEFAULT_BRANCH == 'true' &&
$CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
when: never
- if: $DAST_API_DISABLED_FOR_DEFAULT_BRANCH == '1' &&
$CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
when: never
- if: $CI_COMMIT_BRANCH &&
$CI_GITLAB_FIPS_MODE == "true"
variables:
DAST_API_IMAGE_SUFFIX: "-fips"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
トラブルシューティング
DAST APIジョブがN時間後にタイムアウトします。
DAST APIジョブがタイムアウトする理由の上位2つは、オペレーションが遅い(1秒以上)ことと、DAST APIにシングルCPUランナーを使用していることです(GitLab共有ランナーはシングルCPUです)。さらに問題を診断する前に、ジョブを完了させて出力を分析する必要があります。まずマルチCPUランナーで開始し、ジョブが完了して出力がさらにレビューできるようになるまで、APIオペレーションの一部を除外することをお勧めします。
支援については、以下のドキュメント・セクションを参照してください:
DAST APIジョブの完了に時間がかかりすぎる
パフォーマンス・チューニングとテスト速度を参照
エラー:Error waiting for DAST API 'http://127.0.0.1:5000' to become available
v1.6.196 より前のバージョンの DAST API アナライザには、特定の条件下でバックグラウンドプロセスが失敗するバグが存在します。この問題を解決するには、DAST API アナライザを新しいバージョンに更新してください。
バージョン情報は、dast_api
ジョブの詳細に記載されています。
もしv1.6.196以上のバージョンでイシューが発生している場合は、以下の情報をサポートまでご連絡ください:
- このトラブルシューティングのセクションを参照し、イシューをDynamic Analysis Teamにエスカレーションするよう依頼してください。
- ジョブの完全なコンソール出力。
- ジョブのアーティファクトとして利用可能な
gl-api-security-scanner.log
ファイル。ジョブの詳細ページの右側のパネルで、Browseボタンを選択します。 -
.gitlab-ci.yml
ファイルのdast_api
ジョブ定義。
エラーメッセージ
-
GitLab 15.6 以降では、
Error waiting for DAST API 'http://127.0.0.1:5000' to become available
- GitLab 15.5以前では、
Error waiting for API Security 'http://127.0.0.1:5000' to become available
。
Failed to start scanner session (version header not found)
DAST API エンジンは、スキャナーアプリケーションコンポーネントとの接続を確立できない場合にエラーメッセージを出力します。エラーメッセージはdast_api
ジョブのジョブ出力ウィンドウに表示されます。この問題の一般的な原因は、DAST_API_API
変数をデフォルトから変更することです。
エラーメッセージ
-
GitLab 13.11以降では、
Failed to start scanner session (version header not found).
- GitLab 13.10以前では、
API Security version header not found. Are you sure that you are connecting to the DAST API server?
。
解決方法
-
.gitlab-ci.yml
ファイルからDAST_API_API
変数を削除します。この値はDAST API CI/CDテンプレートから継承されます。手動で値を設定する代わりに、この方法をお勧めします。 - 変数を削除できない場合は、DAST API CI/CD テンプレートの最新バージョンでこの値が変更されていないか確認してください。もしそうであれば、
.gitlab-ci.yml
ファイルの値を更新してください。
Failed to start session with scanner. Please retry, and if the problem persists reach out to support.
スキャナアプリケーションコンポーネントとの接続を確立できない場合、DAST API エンジンはエラーメッセージを出力します。エラーメッセージはdast_api
ジョブのジョブ出力ウィンドウに表示されます。この問題の一般的な原因は、バックグラウンドコンポーネントが選択したポートをすでに使用しているため使用できないことです。このエラーは、タイミングが関係する場合(競合状態)、断続的に発生することがあります。このイシューはKubernetes環境で、他のサービスがコンテナにマッピングされてポートの競合を引き起こしている場合によく発生します。
解決策を進める前に、そのポートがすでに使用されているためにエラーメッセージが表示されたことを確認することが重要です。これが原因であることを確認するには
-
ジョブコンソールに移動します。
-
アーティファクト
gl-api-security-scanner.log
を探します。ダウンロード] を選択してすべてのアーティファクトをダウンロードしてからファイルを検索するか、[参照]を選択して直接検索を開始できます。 -
ファイル
gl-api-security-scanner.log
をテキストエディタで開きます。 -
ポートがすでに使用されていたためにエラーメッセージが表示された場合は、ファイルに以下のようなメッセージが表示されているはずです:
-
Failed to bind to address http://127.0.0.1:5500: address already in use.
-
GitLab 15.4以前の場合:
Failed to bind to address http://[::]:5000: address already in use.
http://[::]:5000
例えば、http://[::]:5500
やhttp://127.0.0.1:5500
などです。エラーメッセージの残りの部分が同じであれば、そのポートはすでに使われていると考えてもよいでしょう。
ポートが既に取られているという証拠が見つからなかった場合、ジョブコンソール出力に表示された同じエラーメッセージをアドレスとする他のトラブルシューティングのセクションもチェックしてください。これ以上の選択肢がない場合は、サポートを受けるか、適切なルートで改善を要求してください。
ポートが既に取られていたためにイシューが発生したことを確認したら、GitLab 15.5をインストールしてください。その後、GitLab 15.5以降では設定変数DAST_API_API_PORT
が導入されました。この設定変数により、スキャナバックグラウンドコンポーネントの固定ポート番号を設定することができます。
解決方法
-
.gitlab-ci.yml
ファイルが設定変数DAST_API_API_PORT
を定義していることを確認してください。 -
DAST_API_API_PORT
の値を1024以上の任意のポート番号に更新してください。新しい値がGitLabによって使用されていないか確認することをお勧めします。GitLabが使用するポートの一覧はPackage defaultsをご覧ください。
Application cannot determine the base URL for the target API
DAST API エンジンは、OpenAPI ドキュメントを検査してもターゲット API を特定できない場合にエラーメッセージを出力します。このエラーメッセージは、ターゲット API が.gitlab-ci.yml
ファイルに設定されていない場合、environment_url.txt
ファイルで利用できない場合、OpenAPI ドキュメントを使用して計算できなかった場合に表示されます。
DAST API エンジンが異なるソースをチェックする際にターゲット API を取得しようとする優先順位があります。DAST_API_TARGET_URL
環境変数が設定されていない場合、DAST API エンジンはenvironment_url.txt
ファイルの environment_url.txt
使用を試みます。environment_url.txt
ファイルが environment_url.txt
ない場合、DAST API エンジンは OpenAPI ドキュメントのコンテンツとDAST_API_OPENAPI
で提供された URL(URL が提供されている場合)を使用してターゲット API の計算を試みます。
最適なソリューションは、ターゲットAPIがデプロイごとに変更されるかどうかによって異なります。静的環境の場合、ターゲット API はデプロイごとに同じであるため、静的環境のソリューションを参照してください。ターゲット API がデプロイごとに変更される場合は、動的環境ソリューションを適用する必要があります。
静的環境ソリューション
このソリューションは、ターゲットAPIのURLが変更されない(静的である)パイプラインのためのものです。
環境変数を追加します。
ターゲットAPIが変わらない環境では、DAST_API_TARGET_URL
環境変数を使ってターゲットURLを指定することをお勧めします。.gitlab-ci.yml
内に、変数DAST_API_TARGET_URL
を追加してください。この変数には、APIテスト対象のベースURLを設定してください。例えば
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_TARGET_URL: http://test-deployment/
DAST_API_OPENAPI: test-api-specification.json
動的環境ソリューション
動的環境では、異なるデプロイごとにターゲットAPIが変更されます。この場合、可能な解決策は1つだけではありません。動的環境を扱う場合は、environment_url.txt
ファイルを使用することをお勧めします。
environment_url.txtを使用してください。
各パイプラインでターゲット API URL が変更される動的な環境をサポートするために、DAST API エンジンは使用する URL を含むenvironment_url.txt
ファイルの使用をサポートしています。このファイルはリポジトリにチェックインされるのではなく、テストターゲットをデプロイするジョブによってパイプライン中に作成され、パイプラインの後のジョブで使用できるアーティファクトとして収集されます。environment_url.txt
ファイルを作成するジョブは、DAST API エンジンのジョブの前に実行する必要があります。
- テストターゲットのデプロイジョブを変更し、プロジェクトのルートにある
environment_url.txt
ファイルにベース URL を追加します。 -
environment_url.txt
をアーティファクトとして収集するテスト ターゲットのデプロイ ジョブを修正します。
使用例:
deploy-test-target:
script:
# Perform deployment steps
# Create environment_url.txt (example)
- echo http://${CI_PROJECT_ID}-${CI_ENVIRONMENT_SLUG}.example.org > environment_url.txt
artifacts:
paths:
- environment_url.txt
無効なスキーマで OpenAPI を使用
文書が無効なスキーマで自動生成されたり、手動で適時に編集できない場合があります。このような場合、DAST API は変数DAST_API_OPENAPI_RELAXED_VALIDATION
を設定することで、緩やかな検証を行うことができます。予期せぬ動作を防ぐために、完全に準拠したOpenAPIドキュメントを提供することを推奨します。
非準拠OpenAPIファイルの編集
OpenAPI仕様に準拠していない要素を検出して修正するには、エディタの使用をお勧めします。エディタは一般的に、ドキュメントの検証や、スキーマに準拠した OpenAPI ドキュメントを作成するための提案を行います。推奨されるエディタは以下の通りです:
エディタ|OpenAPI 2.0|OpenAPI 3.0.x|OpenAPI 3.1.x| –| –| –||Swaggerエディタ |{check-circle}|YAML、JSONYAML、JSON|{check-circle}YAML、JSON|{check-circle}JSONYAML、JSON|{dotted-circle} YAML、JSON|{dotted-circle}YAML、JSONYAML, JSON | Stoplight Studio | {チェック-サークル} YAML, JSON | {チェック-サークルYAML、JSON|{チェック-サークル}|Stoplight Studio|{チェック-サークルYAML, JSON | {チェック・サークル} YAML, JSON | {チェック・サークルYAML、JSON|チェック・サークル |
OpenAPIドキュメントが手動で生成されている場合、ドキュメントをエディタに読み込み、非準拠な部分を修正します。ドキュメントが自動的に生成された場合は、それをエディタで読み込んでスキーマのイシューを特定し、アプリケーションに移動して、使用しているフレームワークに基づいて修正を行います。
OpenAPI緩和検証を有効にします
緩和されたバリデーションは、OpenAPIドキュメントがOpenAPI仕様に適合していないけれども、さまざまなツールで利用するのに十分なコンテンツを持っているような場合のためのものです。検証は行われますが、ドキュメントスキーマに関してはそれほど厳密ではありません。
DAST API は、OpenAPI 仕様に完全に適合していない OpenAPI ドキュメントを消費しようとすることができます。DAST API に緩和されたバリデーションの実行を指示するには、変数DAST_API_OPENAPI_RELAXED_VALIDATION
に任意の値を設定します:
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_PROFILE: Quick
DAST_API_TARGET_URL: http://test-deployment/
DAST_API_OPENAPI: test-api-specification.json
DAST_API_OPENAPI_RELAXED_VALIDATION: 'On'
No operation in the OpenAPI document is consuming any supported media type
DAST API は OpenAPI ドキュメントで指定されたメディアタイプを使用してリクエストを生成します。サポートされているメディアタイプがないためにリクエストを作成できない場合、エラーがスローされます。
エラーメッセージ
-
GitLab 14.10以降の場合、
Error, no operation in the OpenApi document is consuming any supported media type. Check 'OpenAPI Specification' to check the supported media types.
解決方法
- OpenAPI Specificationセクションでサポートされているメディアタイプをレビューしてください。
- OpenAPI ドキュメントを編集して、少なくとも指定されたオペレーションが、サポートされているメディアタイプのどれでも受け入れられるようにします。あるいは、サポートされるメディアタイプを OpenAPI ドキュメントレベルで設定し、すべてのオペレーションに適用することもできます。このステップでは、サポートされているメディアタイプがアプリケーションで受け入れられるように、アプリケーションの変更が必要になるかもしれません。
Error, error occurred trying to download `<URL>`: There was an error when retrieving content from Uri:' <URL>'. Error:The SSL connection could not be established, see inner exception.
DAST API は、古いプロトコルや暗号を含む幅広い TLS 設定に対応しています。幅広いサポートにもかかわらず、接続エラーが発生する場合があります。このエラーは、DAST API が指定された URL のサーバとのセキュアな接続を確立できなかったために発生します。
イシューを解決するには
エラーメッセージのホストが非TLS接続をサポートしている場合は、設定でhttps://
をhttp://
に変更してください。たとえば、以下の設定でエラーが発生した場合:
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_TARGET_URL: https://test-deployment/
DAST_API_OPENAPI: https://specs/openapi.json
DAST_API_OPENAPI
のプレフィックスをhttps://
からhttp://
に変更します:
stages:
- dast
include:
- template: DAST-API.gitlab-ci.yml
variables:
DAST_API_TARGET_URL: https://test-deployment/
DAST_API_OPENAPI: http://specs/openapi.json
URLにアクセスするために非TLS接続を使用できない場合は、サポートチームにお問い合わせください。
testssl.shツールを使用すると、調査を迅速に行うことができます。Bashシェルがあり、影響を受けるサーバーに接続できるマシンから:
- 最新リリースの
zip
またはtar.gz
ファイルをダウンロードし、https://github.com/drwetter/testssl.sh/releasesから展開します。 -
./testssl.sh --log https://specs
を実行してください。 - ログファイルをサポートチケットに添付してください。
ERROR: Job failed: failed to pull image
このエラーメッセージは、アクセスに認証が必要な(公開されていない)コンテナレジストリからイメージを取り出したときに発生します。
ジョブコンソールの出力では、エラーは次のようになります:
Running with gitlab-runner 15.6.0~beta.186.ga889181a (a889181a)
on blue-2.shared.runners-manager.gitlab.com/default XxUrkriX
Resolving secrets
00:00
Preparing the "docker+machine" executor
00:06
Using Docker executor with image registry.gitlab.com/security-products/api-security:2 ...
Starting service registry.example.com/my-target-app:latest ...
Pulling docker image registry.example.com/my-target-app:latest ...
WARNING: Failed to pull image with policy "always": Error response from daemon: Get https://registry.example.com/my-target-app/manifests/latest: unauthorized (manager.go:237:0s)
ERROR: Job failed: failed to pull image "registry.example.com/my-target-app:latest" with specified policies [always]: Error response from daemon: Get https://registry.example.com/my-target-app/manifests/latest: unauthorized (manager.go:237:0s)
エラーメッセージ
- GitLab 15.9 以前では、
ERROR: Job failed: failed to pull image
の後にError response from daemon: Get IMAGE: unauthorized
.
解決方法
認証情報は、「非公開のコンテナレジストリからイメージにアクセスする」のセクションで説明されている方法で提供されます。使用する方法は、コンテナレジストリのプロバイダとその設定によって決まります。クラウドプロバイダー(Azure、Google Could(GCP)、AWS など)のようなサードパーティーが提供するコンテナレジストリを使用している場合は、プロバイダーのコンテナレジストリへの認証方法に関する情報をプロバイダーのドキュメントで確認してください。
以下の例では、静的に定義された認証情報を使用します。この例では、コンテナレジストリはregistry.example.com
で、イメージはmy-target-app:latest
です。
-
DOCKER_AUTH_CONFIG
データの決定方法 を読んで、DOCKER_AUTH_CONFIG
の変数値の計算方法を理解してください。設定変数DOCKER_AUTH_CONFIG
には、適切な認証情報を提供するためのDocker JSON設定が含まれています。例えば、非公開コンテナレジストリregistry.example.com
に認証情報aGVsbG8gd29ybGQK
でアクセスする場合、Docker JSONは以下のようになります:{ "auths": { "registry.example.com": { "auth": "aGVsbG8gd29ybGQK" } } }
- CI/CD 変数として
DOCKER_AUTH_CONFIG
を追加します。設定変数を.gitlab-ci.yml
ファイルに直接追加する代わりに、プロジェクトCI/CD 変数を作成する必要があります。 -
ジョブを再実行すると、静的に定義された認証情報が非公開コンテナレジストリ
registry.example.com
にサインインするために使用され、イメージmy-target-app:latest
をプルできるようになります。成功すると、ジョブコンソールに次のような出力が表示されます:Running with gitlab-runner 15.6.0~beta.186.ga889181a (a889181a) on blue-4.shared.runners-manager.gitlab.com/default J2nyww-s Resolving secrets 00:00 Preparing the "docker+machine" executor 00:56 Using Docker executor with image registry.gitlab.com/security-products/api-security:2 ... Starting service registry.example.com/my-target-app:latest ... Authenticating with credentials from $DOCKER_AUTH_CONFIG Pulling docker image registry.example.com/my-target-app:latest ... Using docker image sha256:139c39668e5e4417f7d0eb0eeb74145ba862f4f3c24f7c6594ecb2f82dc4ad06 for registry.example.com/my-target-app:latest with digest registry.example.com/my-target- app@sha256:2b69fc7c3627dbd0ebaa17674c264fcd2f2ba21ed9552a472acf8b065d39039c ... Waiting for services to be up and running (timeout 30 seconds)...
サポートまたは改善要求
特定の問題についてサポートを受けるには、ヘルプを得るためのチャンネルをご利用ください。
GitLab.com の GitLab イシュー・トラッカーは、API セキュリティと DAST API に関するバグや機能提案に適した場所です。DAST API に関する新しいイシューを発行する際には~"Category:API Security"
ラベルを使用し、適切な担当者が迅速にレビューできるようにしてください。レビュアーがいつレスポンスを受け取るかについては、レビュアーレポート SLOを参照してください。
自分自身の課題を提出する前に、類似のエントリがないかイシュー・トラッカーを検索してください。絵文字によるリアクションやディスカッションへの参加で、あなたのサポートを示しましょう。
期待通りに動作しない動作が発生した場合は、コンテキスト情報を提供することを検討してください:
- セルフマネージドインスタンスを使用している場合は GitLab のバージョン。
-
.gitlab-ci.yml
ジョブの定義 - 完全なジョブコンソール出力。
-
gl-api-security-scanner.log
という名前のジョブアーティファクトとして利用可能なスキャナログファイル。
用語解説
- アサート:アサーションは、脆弱性をトリガーするためにチェックが使用する検出モジュールです。多くのアサーションには設定があります。チェックは複数のアサーションを使用することができます。例えば、「ログ解析」、「レスポンス解析」、「ステータスコード」は、検査で一緒に使用される一般的なアサーションです。複数のアサーションを使用する検査では、アサーションのオンとオフを切り替えることができます。
- チェック:特定のタイプのテストを実行するか、脆弱性のタイプに対するチェックを実行します。例えば、SQL インジェクションチェックは、SQL インジェクション脆弱性に対する DAST テストを実行します。DAST API スキャナは複数のチェックで構成されています。チェックはプロファイルでオン/オフできます。
- プロファイル:設定ファイルには 1 つ以上のテストプロファイル、あるいはサブ設定があります。機能ブランチ用のプロファイルと、メインブランチ用の特別なテスト用のプロファイルがあるかもしれません。