Webhook エンドポイントを保護する
Castify の Webhook エンドポイントは、Castify から呼び出せる必要があるため、 インターネット上に公開する必要がありますので、そのエンドポイントはセキュリティ的に保護する必要があります。
このドキュメントでは、Webhook エンドポイントに対する保護の方法について説明します。
署名の確認
Castify から送られる Webhook リクエストには、Castify による署名が含まれています。 この値を検証することによって、イベントが第三者ではなく Castify によって送信されたことを確認できます。
署名を検証する前にコンソールの Webhook 設定からエンドポイントの Secret Token を取得する必要があります。
Secret token を取得したいエンドポイント内の、[クリックして表示] ボタンを選択します。
署名の計算方法は以下の通りです。
- HTTP ヘッダー
X-Castify-Timestamp
から時刻を表す十進数文字列(=timestamp
)を取得 - HTTP リクエストボディから JSON 形式のペイロード(=
payload
)を取得 - HMAC の秘密鍵として Secret token を指定し、SHA256 で
timestamp
+ "." +payload
をハッシュ化します。このハッシュが Signature です。
以上のようにして得られた signature
を HTTP ヘッダー X-Castify-Signature
に含まれる文字列と比較します。
正しい Signature のサンプル
この処理において、Secretが a
, X-Castify-Timestamp が b
, HTTP リクエストボディが c
の場合、 Signature は 6aa719255fca3dbbb8b20b8ebc67f1d29a3f7f4f923e544ba1432be46d92cb92
となります。 署名を生成する処理のテストにご利用ください。
実装例
以下は、各言語における実装例です。
Java
hexDigest(HmacSHA256(value: timestamp + "." + requestBody, secret: SECRET_TOKEN))
TypeScript
crypto.createHmac('SHA256', secret).update(timestamp + '.' + request.rawBody.toString("utf-8")).digest('hex');
PHP
hash_hmac("sha256", $timestamp . $requestBody . "c", $secret)
リプレイ攻撃の防止
リプレイ攻撃とは、有効なペイロード及びその署名が傍受されていた場合に、 攻撃者が同一のリクエストを再度送り直すことによる攻撃手法です。
HTTP ヘッダー X-Castify-Timestamp
には、 Castify のサーバから送信されたイベントの発生時刻が含まれています。 この発生時刻がごく古い場合には、傍受した攻撃者によるリクエストの可能性があります。
ただし、Castify のサーバと時刻がずれている場合には、 正しいリクエストを拒否してしまう可能性が出てきます。 NTP による時刻の同期を行うとともに、5分等の誤差を許容するようにすることで、 NTP 障害時のエラーを防ぎつつ、 攻撃者による不正なアクセスから守ることが可能です。