web-dev-qa-db-ja.com

REST API呼び出しにパスワードを入力する

REST APIがパスワードの設定/リセットにも使用されているとします。これがHTTPS接続で機能すると仮定します。そのパスを呼び出しパスに含めない理由はありますか? 、BASE64でエンコードするとしますか?

たとえば、次のようにパスワードをリセットします。

http://www.example.com/user/joe/resetpassword/OLDPASSWD/NEWPASSWD

BASE64は暗号化されていないことを理解していますが、この場合はショルダーサーフィンのためにパスワードを保護したいだけです。

33

優れたサーバーは、送信されたすべてのリクエストをログに記録します。これには、URL( '?'の後の可変部分がないことが多い)、ソースIP、実行時間などが含まれます...パスワードとして重要な情報を安全に保護しますか? Base64はそれらに対するストッパーではありません。

78
Netch

あなたが提案しているのは安全でもRESTfulでもありません。

@Netchはすでにログの問題について述べていますが、HTTPによって送信されるパスワードを表示しているという別の問題もあり、あらゆる種類のワイヤスニッファまたは中間者攻撃でパスワードをキャプチャすることは簡単です。

RESTを使用してGETリクエストを実行すると、URLのさまざまな要素がより細かい要素を表します。 URLは、resetpasswordの一部であるOLDPASSWDのNEWPASSWD部分を返すように読み取られます。それは、いかなる意味の意味も持ちません。 GETを使用してデータを保存しないでください。

あなたはこのようなことをしているはずです:

POST https://www.example.com/user/joe/resetpassword/
{oldpasswd:[data], newpasswd:[data]}

あなたがデータを書いているのでPOST、そしてあなたがそれを盗聴したくないのでhttps。

(これは実際には最低水準のセキュリティです。最低限行うべきことです。)

72
Gort the Robot

提案されたスキームはいくつかの分野で問題を抱えています。

セキュリティ

URLパスは頻繁にログに記録されます。パスにハッシュされていないパスワードを入れることは、あまりお勧めできません。

[〜#〜] http [〜#〜]

認証/承認情報は、承認ヘッダーに表示されます。または、ブラウザベースのものの場合は、Cookieヘッダーが含まれる可能性があります。

[〜#〜]レスト[〜#〜]

URLのresetpasswordなどの動詞は、通常、非表現状態転送パラダイムの明確な兆候です。 URLはリソースを表す必要があります。 GET resetpasswordとはどういう意味ですか?または削除しますか?

[〜#〜] api [〜#〜]

このスキームでは、常に以前のパスワードを知っている必要があります。あなたはおそらくより多くのケースを許可したいと思うでしょう。例えばパスワードは失われます。


BasicまたはDigest authentication を使用できます。これは、よく理解されているスキームです。

PUT /user/joe/password HTTP/1.0
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Content-Type: text/plain
Host: www.example.com

NEWPASSWD

パスに非常に機密性の高い情報を入れず、HTTPおよびRESTの規則に従います。

他の認証モードを許可する必要がある場合(検証済みチャネルを介して送信されたトークンなど、パスワードをリセットするため)、他に何も変更せずに、別のAuthorizationヘッダーを使用できます。

60
Paul Draper

問題は、リクエストでプレーンテキストのパスワードを回避することです。残りのWebサービス要件を満たす2つのオプションがあります。

1。クライアント側のハッシュ

  • Eのようなパスワードを保存していると思います。 g。ハッシュ(パスワード+塩)
  • クライアント側でソルトを使用して新しいパスワードをハッシュできます
  • つまり、クライアント側で新しいソルトを作成し、ハッシュeを作成します。 g。ハッシュ(新しいパスワード+新しいソルト)
  • 新しく作成したハッシュとソルトを休息のWebサービスに送信します
  • 古いパスワードもハッシュとして送信します(oldPassword + oldSalt)

2。暗号化

  • / otk/johnのようなユーザーの「ワンタイムキー」(otk)リソースを作成する
  • このリソースは、安全でランダムな一意のワンタイムキーを返します。 g。 kbDlJbmNmQ0Y0SmRHZC9GaWtRMW0ycVJpYzhMcVNZTWlMUXN6ZWxLdTZESFRsと一意のID e。 g。 95648915125
  • 次の安全な通信でID 95648915125を使用するために、安静なWebサービスはこのランダムなotkを保存する必要があります
  • 新しいパスワードと古いパスワードをotk eで暗号化します。 g。 AES(セキュリティ上の理由から、古いパスワードと新しいパスワードには2つの別々のotksを使用する必要があります)
  • 暗号化されたパスワードをID 95648915125のパスワード変更リソースに送信します
  • 1つのotkとIDの組み合わせは1度しか機能しないため、パスワードを変更した後でその組み合わせを削除する必要があります
  • 可能なより良いオプション:Basic-Authで現在/古いパスワードを送信します。

注:両方のオプションでHTTPSが必要です!

4
maz258

セキュリティとは別に、これの問題は、それがあまりRESTfulなアプローチではないことです。

OLDPASSWDNEWPASSWDは、リソース階層の何も表さず、さらに悪いことに、操作はべき等ではありません。

したがって、動詞としてPOSTのみを使用でき、2つのパスワードをリソースパスに含めないでください。

4
biziclop

パスワードリセット操作の機能は何ですか?

  1. それは何かを変えます。
  2. 設定されている値があります。
  3. 一部の人だけがそれを行うことが許可されています(ユーザー、管理者、またはそのどちらか、おそらくどちらがそうすることができるかについて異なるルールを持っている)。

ここでのポイント1は、GETを使用できないことを意味します。POSTパスワードの変更操作を表すURIへのパスワード変更操作を表すもの、またはパスワードの変更を処理するリソースを表すもの、またはURIへの新しいパスワードを表すものをPUTする必要があります。パスワードを表す、またはそのパスワードが特徴である何か(たとえばユーザー)を表す。

一般的にはPOSTを行いますが、特に、後で取得できないものをPUTするのは面倒で、パスワードを取得できないためです。

したがって、ポイント2は、POSTされたものの新しいパスワードを表すデータになります。

ポイント3は、リクエストを承認する必要があることを意味します。つまり、ユーザーが現在のユーザーである場合は、現在のパスワードを証明する必要があります(たとえば、ハッシュベースのチャレンジの場合、必ずしも現在のパスワードを受け取る必要はありません)送信せずに、その知識を証明するために使用されました)。

したがって、URIは<http://example.net/changeCurrentUserPassword>または<http://example.net/users/joe/changePassword>

POSTデータおよび使用されている一般的な認証メカニズムで、現在のパスワードを受け取りたいと思うかもしれません。

2
Jon Hanna