web-dev-qa-db-ja.com

REST認証スキームのセキュリティ

バックグラウンド:

REST Webサービスの認証スキームを設計しています。これは「本当に」安全である必要はありません(個人的なプロジェクトです)が、エクササイズ/学習体験として可能な限り安全にしたいです。面倒なことや、ほとんどの場合、セットアップにかかる費用は不要なので、SSLを使用したくありません。

これらのSOの質問は、始めるのに特に役立ちました。

Amazon S3の認証 の簡易バージョンを使用することを考えています( OAuth が好きですが、私のニーズには複雑すぎるようです)。リプレイ攻撃を防ぐために、サーバーから提供されたランダムに生成された nonce をリクエストに追加しています。

質問に答えるには:

S3とOAuthは両方とも、いくつかの選択されたヘッダーとともにリクエストURLに署名することに依存しています。 どちらもPOSTまたはPUT要求の要求本文に署名しません。これは、URLとヘッダーを保持し、リクエストの本文を攻撃者が必要とするデータに置き換える中間者攻撃に対して脆弱ではありませんか?

署名される文字列にリクエスト本文のハッシュを含めることで、これを防ぐことができるようです。これは安全ですか?

224
dF.

以前の回答では、データ転送のコンテキストでのみSSLについて言及していましたが、実際には認証については説明していませんでした。

あなたは本当にREST APIクライアントを安全に認証することを求めています。 TLSクライアント認証を使用していない限り、SSLaloneはREST APIの実行可能な認証メカニズムではありません。クライアントauthcを使用しないSSLは、serverのみを認証します。これは、ほとんどのREST APIには関係ありません。本当にclient

TLSクライアント認証を使用しない場合は、ダイジェストベースの認証スキーム(Amazon Web Serviceのカスタムスキームなど)またはOAuth 1.0aまたはHTTP Basic認証(ただしSSLのみ)を使用する必要があります。 )。

これらのスキームは、リクエストが予想される誰かによって送信されたことを認証します。 TLS(SSL)(クライアント認証なし)は、回線を介して送信されるデータが改ざんされないようにします。それらは別個の問題ですが、補完的な問題です。

興味のある方のために、私は HTTP認証スキームとその仕組み についてSOの質問を展開しました。

166
Les Hazlewood

RESTは、Webの標準を使用することを意味し、Web上の「安全な」転送の標準はSSLです。それ以外はファンキーになり、クライアントに追加の展開作業が必要になります。これには暗号化ライブラリが必要です。

SSLにコミットすると、原則として認証に必要なものは何もありません。精巧な署名プロトコルよりもはるかに単純であり、安全な接続のコンテキストで依然として有効であるため、Web標準を使用してHTTP基本認証(各リクエストとともに送信されるユーザー名とシークレットトークン)を使用できます。パスワードがプレーンテキストを超えないようにする必要があります。そのため、プレーンテキスト接続でパスワードを受け取った場合は、パスワードを無効にして開発者にメールすることもできます。また、通常のパスワードを記録しないのと同様に、受信時に資格情報がどこにも記録されないようにする必要があります。

HTTPダイジェストは、シークレットトークンが渡されるのを防ぐため、より安全なアプローチです。代わりに、サーバーが相手側で検証できるハッシュです。ただし、上記の予防措置を講じている場合は、感度の低いアプリケーションではやり過ぎかもしれません。結局、ユーザーのパスワードは、ログイン時にプレーンテキストで既に送信されます(ブラウザでJavaScriptの派手な暗号化を行っている場合を除きます)。同様に、各リクエストのCookieも送信されます。

APIでは、開発者がウェブサイトにログインするパスワードの代わりに、クライアントがトークン(ランダムに生成された文字列)を渡す方が良いことに注意してください。したがって、開発者はサイトにログインし、API検証に使用できる新しいトークンを生成できる必要があります。

トークンを使用する主な理由は、パスワードが侵害された場合にトークンを置き換えることができるのに対し、パスワードが侵害された場合、所有者は開発者のアカウントにログインして、必要な操作を実行できるからです。トークンのさらなる利点は、同じ開発者に複数のトークンを発行できることです。おそらく、彼らは複数のアプリを持っているか、異なるアクセスレベルのトークンが必要だからです。

(接続をSSLのみにすることの影響をカバーするために更新されました。)

60
mahemoff

または、この問題の既知の解決策を使用してSSLを使用することもできます。自己署名証明書は無料で、個人的なプロジェクトですよね?

8
wowest

URLのパラメーターの1つとして本文のハッシュが必要であり、そのURLが秘密キーを介して署名されている場合、中間者攻撃は本文を生成するコンテンツでのみ置き換えることができます同じハッシュ。少なくともMD5ハッシュ値を使用して簡単に実行できるようになり、SHA-1が破損した場合でも、状況を把握できます。

ボディが改ざんされないようにするには、ボディの署名が必要です。署名を生成する秘密鍵を知らないため、中間者攻撃が破られる可能性は低くなります。 。

5
ZaDDaZ

実際、元のS3 authdoesでは、MD5署名が弱い場合でも、コンテンツに署名することができます。 HMAC(署名される文字列)にContent-MD5ヘッダーを含めるというオプションの実践を単に強制することができます。

http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html

新しいv4認証スキームはより安全です。

http://docs.aws.Amazon.com/general/latest/gr/signature-version-4.html

3
djsadinoff

あなたの提案は、クライアントがサーバーと通信するのを難しくすることを覚えておいてください。彼らはあなたの革新的なソリューションを理解し、それに応じてデータを暗号化する必要があります。このモデルはパブリックAPIにはあまり適していません(あなたがAmazon\yahoo\googleでない限り)。

とにかく、本文コンテンツを暗号化する必要がある場合は、次のような既存の標準とソリューションを確認することをお勧めします。

XML暗号化(W3C標準)

XMLセキュリティ

1
LiorH