Riyad Kalla によるこの非常に優れたブログ投稿の一部に従って、プロジェクト用の単純な RESTful API を作成しました。現在、Stack Overflow で同様の質問を何十も読んでいますが、セキュリティに関する質問に対する答えが見つからないようです。
簡単に言うと、私のリクエストは次のようになります。
- クライアントには公開 API キーがあります (平文で、ネットワーク トラフィックを傍受したり、コード ソースを適切にチェックしたりする人なら誰でもアクセスできます)。
- クライアントは公開 API キーを使用してサーバーにリクエストを送信します
- サーバーには秘密の API キーがあります (開発者以外には秘密です)
- サーバーは、クライアントのリクエスト データとシークレット API キーで構成される HMAC-SHA1 ハッシュを作成します。
- サーバーは、クライアントのリクエストと同じリクエストをAPIサーバーに送信しますが、結果のHMAC-SHA1が含まれます
- API サーバーは、受信した公開 API キーに基づいて、データベース内の秘密 API キーを検索します。
- API サーバーは、開発者のサーバーと同じデータを使用して HMAC-SHA1 ハッシュを再作成します。
- ハッシュが一致する場合、リクエストは有効であると見なされ、正常に処理されます
私のサービスを使用している誰かが公開 API キーを取得し (たとえば、ネットワーク トラフィックをスニッフィングすることによって)、クライアントが AJAX を使用してブラウザー経由で開発者のサーバーに直接行うのと同じ要求を単純に cURL することができるのではないかと心配しています。したがって、悪意のあるユーザーは正当なユーザーとして認証され、他の誰かの秘密 API キーを使用して API にアクセスする可能性があります。
具体例を挙げてみます。通常、私は次のようにします:
- 私のサーバーへのAJAX取得リクエスト。
- サーバーは、API シークレットを使用してリクエストをハッシュし、API サーバーに送信します。
- API サーバーはリクエストを検証し、ペイロードを返します。
しかし、私はそれが怖いです:
- Dr. Evil が私の公開 API キーを盗聴します。
- Dr. Evil は、公開 API キーを使用してサーバーへの get リクエストを cURL で送信します。
- 私のサーバーは Dr. Evil のリクエストを私の API シークレットでハッシュし、それを API サーバーに送信します。
- API サーバーはペイロードを検証して返し、Dr. Evil の悪質な計画を完了します。
- Dr. Evil は邪悪な笑い声を上げます。
不足しているものはありますか、それとも RESTful API ゲームの一部ですか?
更新: 私は任意の形式のタイムスタンプ検証を自発的に省略して、物事をシンプルに保ち、認証の問題だけに集中しています。
$_SERVER['HTTP_REFERER']
更新 2:プロセスに検証を追加しました。ここでの目標は、クライアントがリクエストとともにリファラーを送信する必要があり、API 側のデータベースにリストされているリファラーと一致する必要があることです。残念ながら、HTTP リファラーは簡単に偽装できます。これはもう 1 つのレベルのセキュリティですが、まだ完全ではありません。
更新 3: サーバー側のコードを変更して、リファラーをリモート IP アドレスに設定しました。これにより、秘密の API キーを使用してハッシュする必要があるサーバーに送信されるすべての要求が、最終的に元の要求 IP アドレスで API サーバーに到達するようになります。その後、この IP を検証して、要求を通過させることができます。偽造することはまだ可能だと思います$_SERVER['REMOTE_ADDR']
が、偽造するよりも複雑$_SERVER['HTTP_REFERER']
です...まだ完全ではないと思います。
更新 4 : これらの投稿によると: $_SERVER['REMOTE_ADDR'] 変数を偽造するには? およびhttps://serverfault.com/questions/90725/are-ip-addresses-trivial-to-forge、偽造は$_SERVER['REMOTE_ADDR']
困難ですが可能です。ただし、偽造されたネットワークを制御できないため、偽造されたリクエストから応答を受け取ることは不可能です。リクエストは正常に検証されますが、そのレスポンスが悪意のある手に渡ることはありません。