ユーザーパスワードのクレンジング


98

ユーザー提供のパスワードをハッシュしてデータベースに保存する前に、どのようにエスケープまたはクレンジングする必要がありますか?

PHP開発者がセキュリティ上の目的でユーザーのパスワードをハッシュすることを検討するとき、開発者は多くの場合、他のユーザー提供のデータと同じようにそれらのパスワードを考える傾向があります。この問題は、パスワードの保存に関連するPHPの質問でよく出てきます。開発者は多くの場合のような機能を使用してパスワードを清めるために望んでいるescape_string()(様々な繰り返しで)、 、htmlspecialchars()addslashes()それをハッシュし、それをデータベースに格納する前に他の人。


1
u base64エンコードを使用できます
MSS

@MSSはありません。base64 は暗号化ハッシュではなく、エンコーディングであるため、使用しないでください。パスワードは常にハッシュ化する必要があります。
Jay Blanchard

1
私はハッシュの前を意味します;)
MSS 2017年

ハッシュする前に、そうする必要はありません。不要な追加コード@MSSを作成する必要があります
Jay Blanchard

回答:


99

password_hash()いくつかの理由から、PHPでハッシュ化するパスワードに対して他のクレンジングメカニズムをエスケープ、トリム、または使用しないでください。その最大の理由は、パスワードに追加のクレンジングを行うために不要な追加コードが必要になるためです。

私たちはすべてのユーザー入力をクレンジングする必要があり、ユーザーからユーザーが受け入れる他のすべての情報については正しいと主張します(そして、ユーザーデータがシステムでの使用が受け入れられるすべての投稿に表示されます)。パスワードが異なります。文字列はデータベースに格納される前にハッシュに変換されるため、ハッシュされたパスワードはSQLインジェクションの脅威を提供できません。

パスワードをハッシュすることは、パスワードをデータベースに安全に保存することです。ハッシュ関数はバイトに特別な意味を与えないので、セキュリティ上の理由で入力のクレンジングは必要ありません

ユーザーが希望するパスワード/フレーズの使用を許可し、パスワードを制限せず、長さ、スペースの数、および特殊文字のハッシュを許可するというマントラに従う場合は、パスワード/パスフレーズが何に含まれていても安全ですパスワード。現在、最も一般的なハッシュ(デフォルト)PASSWORD_BCRYPTは、パスワードを、ハッシュされたパスワード情報とコスト(ハッシュを作成するアルゴリズムのコスト)とともにランダムなソルトを含む60文字幅の文字列に変換します。

PASSWORD_BCRYPTは、CRYPT_BLOWFISHアルゴリズムを使用して新しいパスワードハッシュを作成するために使用されます。これにより、常に「$ 2y $」暗号形式を使用したハッシュが生成されます。これは、常に60文字幅です。

ハッシュを保存するためのスペース要件は、関数に異なるハッシュ方式が追加されると変更される可能性があるため、VARCHAR(255)またはなどの保存されたハッシュの列タイプを常に大きくすることをお勧めしますTEXT

完全なSQLクエリをパスワードとして使用すると、ハッシュされ、SQLエンジンで実行できなくなります。たとえば、

SELECT * FROM `users`;

ハッシュ化できる $2y$10$1tOKcWUWBW5gBka04tGMO.BH7gs/qjAHZsC5wyG0zmI2C.KgaqU5G

さまざまなサニタイズ方法がパスワードにどのように影響するか見てみましょう-

パスワードはI'm a "dessert topping" & a <floor wax>!(パスワードの最後に5つのスペースがあり、ここには表示されません。)

次のトリミング方法を適用すると、かなり異なる結果が得られます。

var_dump(trim($_POST['upassword']));
var_dump(htmlentities($_POST['upassword']));
var_dump(htmlspecialchars($_POST['upassword']));
var_dump(addslashes($_POST['upassword']));
var_dump(strip_tags($_POST['upassword']));

結果:

string(40) "I'm a "dessert topping" & a <floor wax>!" // spaces at the end are missing
string(65) "I'm a &quot;dessert topping&quot; &amp; a &lt;floor wax&gt;!     " // double quotes, ampersand and braces have been changed
string(65) "I'm a &quot;dessert topping&quot; &amp; a &lt;floor wax&gt;!     " // same here
string(48) "I\'m a \"dessert topping\" & a <floor wax>!     " // escape characters have been added
string(34) "I'm a "dessert topping" & a !     " // looks like we have something missing

これらを送信するとpassword_hash()どうなりますか?上記のクエリと同じように、すべてハッシュ化されます。パスワードを確認しようとすると、問題が発生します。これらの方法の1つ以上を採用する場合、と比較する前にそれらを再雇用する必要がありpassword_verify()ます。以下は失敗します:

password_verify($_POST['upassword'], $hashed_password); // where $hashed_password comes from a database query

パスワード検証でその結果を使用する前に、選択したクレンジング方法で投稿されたパスワードを実行する必要があります。これは不必要な一連のステップであり、ハッシュを改善しません。


5.5未満のPHPバージョンを使用していますか?password_hash() 互換パックを使用できます

MD5パスワードハッシュは使用しないでください。


13
いいえ。許可されている末尾のスペースを含むパスワードを作成した場合、ログイン時にそれらを使用する必要があります@DanBracuk
Jay Blanchard

12
どのように@DanBracuk?ユーザーが、先頭/末尾のスペースを含め、ユーザーが望むパスワードを設定できるようにする場合はどうでしょうか?
ジェイブランチャード

16
そのため、ほとんどの場合、選択したパスワードを2回入力する必要があります。ユーザーが誤ってスペースを追加した場合、さらに先に進む前にそれを理解します。ユーザーが意図的にそれを行った場合、それは問題ではありません。
クマを1回レスリングしました。

4
@MargaretBloom、経験則は単なるヒューリスティックです。私たちは時々、パスワードのように、まだ物事をじっくり考える必要があります。あなたは「将来的に物事がどのように変化するか誰も知らない」と言いますが、何かが変化するのであれば、それをデータベースに入れる前にデータをエスケープする方法であるように思われます。保存したものと一致します。パスワードハッシュをエスケープしない場合の危険とエスケープする危険の違いは何ですか?
DavidS

3
正確に言うと、もちろん、パラメータ化されたSQLクエリに正しく渡すという限られた意味で「ハッシュをエスケープする」ことになります。SQLコネクタの一部のコードでは、「エスケープ」に対応するコードで何もできない場合があります。 t知っていても構いません。これを達成するために特定のコードを記述する必要はありません。これは、以前に不適切な決定をしていない限り、すべてのSQLクエリに対して完全にルーチンであるためです。
Steve Jessop

36

パスワードをハッシュする前に、RFC 7613のセクション4で説明されているように、パスワードを正規化する必要があります。特に:

  1. 追加のマッピング規則:非ASCIIスペースのインスタンスは、ASCIIスペース(U + 0020)にマップする必要があります。非ASCIIスペースは、「Z」のユニコード一般カテゴリ(U + 0020を除く)を持つ任意のユニコードコードポイントです。

そして:

  1. 正規化ルール:Unicode正規化フォームC(NFC)をすべての文字に適用する必要があります。

これにより、ユーザーが同じパスワードを入力したが別の入力方法を使用した場合でも、パスワードが受け入れられるようになります。


3
@DavidS、非常に光沢のある北米のMacブック(Joeが出発する直前に使用したもの)と国際化が不十分な台湾のインターネットカフェコンピューター(Joeがダウンロードに使用しようとしているのは、フライトバックボーディングカードです)。
マーガレットブルーム

2
神話的に聞こえます。:-)感謝します。
DavidS

3
うーん。これを行う場合は、パスワードを検証して、まだ割り当てられていない文字を含むパスワードを拒否する必要もあります。ユーザーがNEWFANGLED SPACEを使用するのはひどいことです。これは、アプリが認識せず、そのままの状態でハッシュし、Unicode文字データベースをアップグレードすると、ハッシュの前に突然NEWFANGLED SPACEがSPACEにマッピングされ、(s)heアプリが古いハッシュにハッシュするパスワードを入力できなくなりました。
ruakh

4
@JayBlanchardあるマシンでスペースバーを押すと、別のマシンでそれを押すと、2つの異なるUnicodeコードポイントが取得される可能性があり、ユーザーが何も意識することなく、2つの異なるUTF-8エンコーディングが使用されます。これは無視したい問題であると主張することもできますが、RFC 7613はこのような現実の問題から生まれたものであり、実際の作業ではありません。
モニカの復活2016

1
@ruakh特定の方法でパスワードを処理することを決定したら、それらはその方法で処理されたままにする必要があります。そうしないと、既存のユースケースで問題が発生します。将来、前処理方法を変更する場合は、前処理され、ハッシュされたパスワードの表現に沿って保存する必要があります。このようにして、入力を受け取ったら、比較対象に基づいて前処理/ハッシュ方法を選択します。
モニカを
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.