カスタムスクリプト
カスタム・スクリプトを使用すると、DAST スキャンをより動的に実行できます。JavaScript を追加して、スキャン中に HTTP 要求または応答を操作できます。これは、要求がサーバーに送られる前、または応答が受信された後に行うことができます。
AppScan に対してカスタム・スクリプトを有効にする方法
カスタム・スクリプトは、デフォルトでは有効になっています (CustomScripts.Enable 設定がTrue に設定されています)。
スクリプトを無効にするには、次の手順を実行します。
- 「ツール」 > 「オプション」 > 「拡張」タブに移動します。
- CustomScripts.Enable 設定を「False」に設定します。
DAST スキャンに対してカスタム・スクリプトを追加して有効にする方法
- 構成設定の「拡張」セクションの「カスタム・スクリプト」に移動します。
- 「+ 追加」ボタンをクリックします。
- 「名前」フィールドには、スクリプト作成の日時が事前に入力されています。必要に応じて、名前を変更できます。
- 「実行コンテキスト」ドロップダウンで、スクリプトを実行するタイミングに応じて、「要求前」または「要求後」を選択します。
- 「JavaScript」フィールドに、JavaScript コードを入力します。AppScan 環境内で
JavaScript コードの提案を受け取るには、「Ctrl+Space」
を押します。
コードに構文エラーがなく、AppScan によってサポートされている JavaScript のバージョンと互換性があることを確認します。ルール、およびコードの記述方法について詳しくは、「JavaScript コード」を参照してください。
例 1: ログイン詳細を要求に自動的に追加します (ログイン管理構成を使用しない場合)。
// Before each request if(request.method == "POST") { request.body = JSON.stringify({ "username": "jsmith", "password": "demo1234" }) }
例 2: 応答に API キーが含まれるかどうかを確認し、グローバル変数に格納します。
// After each response try { var result = JSON.parse(response.body) log(`parsing: ${JSON.parse(response.body).Authorization}`) if(result.Authorization) { environment.globalVariables.addOrUpdate("Authorization", result.Authorization) log(`key = ${result.Authorization}`) } } catch (error) { log(error) }例 3: 許可 API キーが存在する場合は、許可 API キーをヘッダーに設定します。
// Before each request var authorization = environment.globalVariables.get("Authorization") if(authorization) { request.headers.set("Authorization", authorization) log(`authorization is ${authorization}`) }
- 「追加」をクリックしてスクリプトを保存します。スクリプトがリストに追加され、デフォルトで有効になります。Note: 追加したスクリプトは、DAST スキャン中に HTTP 要求または応答ごとに実行されます。この機能を適切に使用して、スキャンの効率および有効性を高めてください。予期しない動作または結果を避けるため、スクリプトをライブ・スキャンにデプロイする前に、制御された環境でスクリプトを必ずテストしてください。
- 「有効」チェックボックスを使用して、カスタム・スクリプトのリストからスクリプトを有効または無効にすることができます。
- スクリプトの実行の順序は修正、削除または変更できます。スクリプトの右隅で、
をクリックし、次のようにオプションを選択します。- 編集
- 削除
- 上に移動
- 下に移動
- 「フル・スキャンの開始」をクリックして、スキャンを実行します。
- 結果: 有効なスクリプトが、要求または応答ごとに実行されます。「データ」 > 「要求」タブ > 「要求/応答」から、スクリプトの詳細を表示できます。Note: テンプレートでカスタム・スクリプトをエクスポートすると、デフォルトで暗号化されます。この暗号化を手動で無効にするには、スキャンの構成設定から「詳細設定」に移動して「全般: 機密データを暗号化」を「False」に設定します。
JavaScript コード
コンテキスト
要求: 要求データは、サーバーに送信される前に読み取りまたは変更を行うことができます。各要求は、要求オブジェクトによって表されます。要求オブジェクトは、次のプロパティーを持ちます。- ヘッダー: すべての要求ヘッダーを含んでいます。デフォルト・ヘッダー以外の任意のヘッダーを追加、削除または変更できます。
// Add header request.headers.add(key, value)
// Override header if exist request.headers.set(key, value)
Note: 「設定」ではなく「追加」を使用すると、要求にヘッダーのインスタンスが複数含まれることになります。このため、「追加」より「設定」を選択することをおすすめします。// Remove header request.headers.remove(key)
// Modify header request.headers[key]
// Examples request.headers.add("Authorization", "MyCoolApiKey") request.headers.set("Authorization", "SecondApiKey") request.headers.remove("Authorization") request.headers['Authorization'] = "myapikey3"
デフォルト・ヘッダー (大文字と小文字は区別されません): デフォルト・ヘッダーは読み取り専用であり、変更できません。- ホスト: 要求の送信先ホストを識別します。
- コンテンツ長: 要求のサイズを計算し、この情報をサーバーに送信します。
- 本文: 要求の本文に関する情報を含んでいます。本文のタイプは「ストリング」です。
// Access body request.body
// Example request.body = "{ "username":"user" }"
- パス: 要求が意図されたエンドポイントに関する情報を保持します。エンドポイント形式では、base-url (例:
/api/v1/test) は除外されます。このプロパティーは読み取り専用であり、スクリプトを実行する前に変更しようとした場合でも、最初に設定されたときと同じままです。// Access url path request.path
// Example if (request.path.startsWith("api/v1/test")) - 照会: 現在の要求の照会ストリングおよびパラメーター (存在する場合) を保持します。このオブジェクトから照会パラメーターを追加または削除できます。各値は、「キー = 値」のように単一オブジェクトとして扱われます。「getQueryString」を使用すると、「&」記号で連結されたすべての項目を持つストリングが提供されます。このストリングは項目のコピーであるため、ストリングを変更すると、照会のコピーのみを変更することになります。Note: 照会パラメーターが空の場合、AppScan は照会区切り文字 (「?」) を送信しません
// Retrieve the current query string request.query.getQueryString()
// Example // Add new value (or update existing one) request.query.addOrUpdate("appscan","appscanvalue")
// Check if value exist request.query.contains("appscan") // for key only check request.query.contains("appscan=appscanvalue") // for key and value check
// Remove an item request.query.remove("appscan") // for key only check request.query.remove("appscan=appscanvalue") // for key and value check request.query.clear() // remove all values
- メソッド: 要求のメソッド (例: GET/POST/etc)。このプロパティーは読み取り専用であり、スクリプトを実行する前に変更しようとした場合でも、最初に設定されたときと同じままです。
// Access to the method request.method
// Example if (request.method == "GET")
- 本文: 要求の応答本文を保持します。応答はストリング形式であるため、必要に応じて手動で (例: JSON に) 変換する必要があります。
// Access body response.body
// Example let json = JSON.parse(config.response)
- パス: 応答エンドポイントに関する情報を含んでいます。
// Access to the relative url response.path
// Example if (response.path.startsWith("api/v1/test")) - ステータス: 応答ステータスに関する詳細を格納します。ステータスは、次のプロパティーを持つオブジェクトです。
// Access status response.status.statusCode // A numeric representation of the status response.status.statusDescription // The description of the status code response.status.statusLine //the whole status line including the http version
// Example if (response.status.statusCode == 200) // check only the number if (response.status.statusDescription == "OK") // Check only the description if (response.status.statusLine == "HTTP1.1 200 OK") // Full line
- ヘッダー: すべての応答ヘッダーを含んでいます。デフォルト・ヘッダー以外の任意のヘッダーを追加、削除または変更できます。
// Add header response.headers.add(key, value)
// Override header if exist response.headers.set(key, value)
// Remove header response.headers.remove(key)
// Modify header response.headers[key]
// Examples response.headers.add("Authorization", "MyCoolApiKey") response.headers.set("Authorization", "SecondApiKey") response.headers.remove("Authorization") response.headers['Authorization'] = "myapikey3"
- 親要求: 応答の前に送信された要求を含んでいるオブジェクト。要求データは読み取り専用です。要求は、以前に定義された要求オブジェクトとしてすべてのプロパティーを持ちます。
// Example response.request.path //- access to the path from the request
環境データ
短期データ・オブジェクトは、スキャンの一時停止、停止、または完了、ログイン、あるいは手動テストの実行など、タスクが終了するまで重要な情報を格納します。
- グローバル変数: グローバル変数データは、ユーザー固有のデータ・ペアを格納するために設計されたキー - 値データ構造です。キーは一意 (2 つの要素が同じキーを持つことはできませんが、複数の要素が同じ値を共有することはできます) であり、実行中のスクリプト間でデータを共有するのに便利です。
このデータは、新しいスキャンまたは再スキャンが行われるたびに消去されます。
// Add data to the globals or update existing one environment.globalVariables.addOrUpdate(key, value)
// Remove key data from the globals environment.globalVariables.remove(key)
// Read data - retrieves the value for the current key (without removing it) environment.globalVariables.get(key)
- スキャン状況: 現在のスキャンに関する情報を含んでいます。
// determine if the current phase is explore phase environment.status.isInExplore()
// determine if the current phase is test phase environment.status.isInTest()
ロギング
スクリプトのロギング機能を有効にして、デバッグおよび問題の特定に役立てます。コマンド「console.log」は、ここでは機能しません。代わりに、単語「log」を使用し、その後に、引用符で囲んだメッセージを続けます。また、エンジンの動作中に JavaScript の構文または使用方法に関係のないエラーが発生した場合、このエラーは、エンジン・トレース・ログに記録されます。
// Log message to file log("my cool logging") // Log message with custom source log("message", "my-cool-source")
制約
- eval
- 関数 (コンストラクター)
- setTimeout
- setInterval
エラー処理
制限のある関数をスクリプトが使用しているときにエラーまたは例外が発生した場合、スクリプトは動作を停止します。このエラーが発生すると実行中のスキャンは一時停止します。エラーの詳細内容が「UserScript.log」ファイルに記録され、詳しい内容を確認できます。
スクリプトで構成されたテンプレートのロード
スクリプトを有効にして構成されたテンプレートをロードすることで、スキャンを開始できます。demo.testfire 実行記述ファイル用のスクリプトで事前構成されたサンプル・テンプレートが Program Files (x86)\HCL\AppScan Standard\Templates で入手可能です。
AppScan でサポートされている JavaScript バージョン
- ES6 (2015)
- ジェネレータ
- 末尾呼び出し
- ES8 (2017)
- 共有メモリとアトミック機能
- ES15 (2024)
- Atomics.waitAsync
- 正規表現 \v フラグ