ウェブフックのセキュリティに関するベストプラクティス
Gints Dreimanis
2022年7月6日
0 分で読めますウェブフックは、あるシステムから別のシステムへ、発生頻度の低いイベントに関する情報を転送する優れた方法の1つです。クライアントがサーバーに情報を繰り返し要求するHTTPポーリングなどの方法とは異なり、ウェブフックはイベントをきっかけに実行されます。
そのため、ウェブフックはシンプルかつ効果的です。クライアントはウェブフックを登録することで、特定のイベントが発生するたびにエンドポイントへメッセージを送信できます。
しかし、ウェブフックではインターネット上の公開エンドポイントにメッセージを送信することが多いため、セキュリティ上の問題が発生する可能性があります。適切なセキュリティ対策を講じていないと、攻撃者にメッセージを読まれたり改ざんされたりするだけでなく、あなたになりすまされるおそれもあります。そのため、ウェブフックサービスの運用では、必要なセキュリティレベルを確保するためにあらゆる対策を講じる必要があります。
このブログでは、攻撃対象領域を広げることなくアプリケーション間でデータを共有するために、ウェブフックを保護する効果的な方法をご紹介します。
ウェブフックの作成時に実践したい8つのセキュリティベストプラクティス
ウェブフックを実装する際は、単一のセキュリティ対策だけに頼らないようにしましょう。複数の方法を組み合わせれば、攻撃者が一部の対策を突破した場合でも、システムの安全性を保つことができます。
最低限、クライアントとの送受信メッセージのプライバシーを守るために暗号化を使用し、クライアントとサーバーの双方が通信相手を確認できるよう、相互認証を導入しましょう。
ウェブフックで送信するデータを暗号化する
悪意のある第三者によるメッセージの傍受を防ぐことはできなくても、その内容を読まれないようにすることは可能です。すべての通信を安全に行う簡単な方法は、HTTPではなくHTTPSを使用することです。
HTTPSの導入は非常に簡単で、利用しない理由はほとんどありません。HTTPSはすべてのデータを暗号化するため、第三者がアクセスすることは格段に難しくなります。
ウェブフックに署名する
悪意のある第三者は、インターネット上で送信されるメッセージを傍受し、自分たちに都合のよい内容に改ざんする可能性があります。こうした改ざんを防ぐには、メッセージに署名します。ハッシュベースのメッセージ認証コード(HMAC)を使用できます。HMACは、ハッシュアルゴリズムと、双方が共有する秘密のコードまたはキーで構成されます。
HMACハッシュ(またはスクランブル)は、各メッセージに固有のハッシュ関数を割り当てます。これにより、ウェブフックの受信側はメッセージをハッシュと照合し、真正性と完全性を確認できます。
ウェブフックへの署名については、Twilioのこちらの記事をご覧ください。
接続を認証する
ウェブフックのエンドポイントは、多くの場合、公開されており、インターネット上の誰もがアクセスできます。エンドポイントが公開されていると、ウェブフックの受信側には、脆弱性やサービス拒否攻撃など、複数のリスクが生じます。この問題を解決するには、受信側でメッセージの送信元を認証する必要があります。ユーザー名とパスワード、または認証トークンを使って送信元を認証できます。
さらに、メッセージが正しい宛先に届くよう、受信側も認証することをおすすめします。
メッセージにタイムスタンプを付ける
リプレイ攻撃を防ぐために、メッセージに送信時刻を付けることができます。リプレイ攻撃ではメッセージの読み取りや改ざんは行われませんが、正規の暗号化済みメッセージを傍受し、攻撃者にとって都合のよいタイミングで再送されるおそれがあります。
メッセージにタイムスタンプを付けることで、クライアントは、受信したメッセージが現在のものであり、数週間前に送信したものではないことを確認できます。また、メッセージには署名も付いているため、攻撃者はタイムスタンプを変更したり、メッセージを保存してリプレイ攻撃に使ったりできません。
証明書ピンニングを使用する
クライアントがAPI用の信頼できる証明書を持つWebサーバーから接続を受けても、そのWebサイト(および証明書)が自社のものだとは限りません。攻撃者が自社APIのコピーを作成し、そこに信頼できる証明書を追加する可能性があります。そのうえで正規のメッセージを傍受し、代わりに自分のメッセージを送信することもできます。
この問題を解決する方法の1つが、証明書ピンニングです。イベントが毎回同じサーバーから送信される場合、クライアントのコードにサーバーの証明書を固定できます。証明書をピンニングするとは、証明書またはそのハッシュ(フィンガープリント)をアプリにハードコードし、接続を確立するたびに提示された証明書と照合することです。
ただし、この手法はパラメーターをハードコードするため、使用には注意が必要です。証明書が変更または失効した場合、クライアント側で十分な速さで証明書を更新できない可能性があります。
証明書ピンニングの例については、Mozillaのドキュメントをご覧ください。
機密データにウェブフックを使用しない
ウェブフックは、保護されている場合でも、パスワードやクレジットカード情報などの機密データの送信には適していません。一般に、ウェブフックはイベントの通知に使うものです。ウェブフックで送信するメッセージに機密データを含めている場合は、ユースケースを見直してください。
送信するすべてのウェブフックメッセージをログに記録する
ウェブフックのメッセージは、自社開発のソリューションやサードパーティ製ソリューションを使って記録できます。ログには送信したすべてのメッセージが記録されるため、監査に役立ちます。また、セキュリティインシデントが発生した場合に、送信済みのメッセージや確立された接続をすべて確認できます。ログを監視することで、配信失敗などの不審な動きを、セキュリティインシデントが発生する前に検知することもできます。
ウェブフックのメッセージをログに記録すると、効率性の向上にもつながります。たとえば、長期間ログを正常に受信していないユーザーを登録解除すれば、リストを正確かつ最新の状態に保てます。ウェブフックメッセージのログ記録について詳しくは、こちらのNearFormの動画をご覧ください。また、ウェブフックのログ記録に使えるツールについては、こちらのNode.jsロガーをご確認ください。
有効期限付きのサブスクリプションモデルを使用する
ユーザーがサブスクリプションの有効期限を設定できるようにすることをおすすめします。有効期限だけで大きな影響があるわけではありませんが、ほかのセキュリティ対策と併用することで、保護をさらに強化できます。
さまざまな暗号化、認証、認可の方法と組み合わせることで、サーバーやクライアントが権限を保持できる期間を制限し、多層的なセキュリティを実現できます。また、有効期限が切れるとクライアントは再度サブスクリプションの手続きを行う必要があるため、盗まれた認証情報などの弱点を攻撃者に見つけられるまでの時間を短縮できます。
ウェブフックのセキュリティを確立する
ウェブフックメッセージの暗号化は、クライアントがメッセージを検証できるようにするための基盤です。ほかのセキュリティ対策を加えて組み合わせることで、より包括的な保護を実現できます。
ウェブフックは通常、システム内で発生したイベントをクライアントに知らせるためのものです。新しいGitHubのPRリクエストや、新しいフォロワーの登録など、こうしたイベントの大半は無害であり、攻撃者が通信を改ざんする動機もあまりありません。ウェブフックで機密性の高いデータを送信することは、強く避けるべきです。
包括的なセキュリティ対策は、アプリケーションの領域と送信する情報の性質に合ったセキュリティ対策を選ぶことから始まります。たとえば、イベントの予定に関する更新には、個々のクライアントの詳細な情報を含むメッセージほど多くの対策は必要ありません。アプローチを適切に調整し、重層的なセキュリティを構築することで、今日見られるさまざまな脆弱性からコードとクライアントデータを保護できるという確信を高められます。
