2

だから私は、高セキュリティの php ユーザー システムを設計しようとしています。ログイン/セッションの終わりから始めることにしました。誰かに私の計画を見てもらい、抜け穴やセキュリティ上の欠陥を教えてもらいたいです。

このようなレベルでシステムを作成しようとするのはこれが初めてです。問題が見つかった場合は、それを修正するのに役立つリソースを送っていただけますか.

データベースへの接続 *ここでは MYSQL を使用するので、標準のデータベース接続はサイトのルート外のファイルに保存されます。

登録 *登録は簡単なフォームです。外部ファイルに保存されている関数を使用して、入力をサニタイズし、SQL インジェクションから保護しています。

// A function to sanitize input for data being input into a database
function sanitizeinput($rawinput) {
$sanitizedinput = mysql_real_escape_string($rawinput);
return $sanitizedinput;
}

この機能をこれ以上保護するために必要なものはありますか?

パスワードは、SHA-512 または BCrypyt のいずれかを使用してハッシュ化されます。少し調査したところ、MD5 はもはや十分に安全ではないと多くの人が言っているのを見てきました。可能な限り最高のセキュリティを確保したいので、何を使用すればよいでしょうか。パスワードをハッシュします。

また、次のスニペットを使用してランダムに生成されたソルトを追加しました。これは、ハッシュされたパスワードの前に追加されてから再ハッシュされました。その後、ソルトはプレーンテキスト形式でデータベースに保存されます。セキュリティを強化するためにこれを暗号化することを考えるべきですか?

ユーザーがログインすると、入力したパスワードがハッシュされ、データベースからのソルトが追加されて再ハッシュされ、データベースに保存されているパスワードと比較されます。

パスワードが一致すると、単一の IP アドレスとユーザー エージェントにロックされるセッションが作成されます。その後、セッションは短時間で期限切れになります。セッションはログイントークンを保存するためにのみ使用され、ユーザー名とパスワードはもちろんセッションに保存されません。

ユーザーがログインすると、ユーザー名が割り当てられたトークンがデータベースに保存されるため、トークンを使用してデータベースからユーザーの詳細を安全に取得できます。セッションに保存するリスクはありません。

パスワードが正しくない場合、ユーザーはログインできません...当然、これにもブルートフォース保護を適用します。3回試行すると、ユーザーのIPとユーザーエージェントが15分間ロックアウトされ、10回失敗するとブロックされますファイアウォールで。

何かを忘れているように感じますが、直接指を当てることはできません。

ヘルプやアドバイスをいただければ幸いです。

4

4 に答える 4

2

私は決してこれの専門家ではありませんが、最初に mySQL に接続するために PDO に切り替えます。少し難しいように思えますが、適切に使用すれば、SQL インジェクションを行おうとする人から 100% 保護されます。暗号化のために、これを使用してユーザーごとにランダムなソルトを生成しました。

    function generateSalt($length, $chars)
{
  $randString = '';
  $charLength = strlen($chars);
  for($count = 0; $count < $length; $count++)
  {
    $randString .= substr($chars, mt_Rand(0, ($charLength-1)), 1);
  }
  return $randString;
} 

文字列をフィードすると、その文字列の文字から指定された長さのソルトが吐き出されます。それから、割れにくいという事実から、フグを使用したと思います。

XSS の脆弱性を考慮しましたか? 私はまだそれを行っておらず、それに取り組む必要があります。後でページのどこかに表示される可能性のある html または javascript コードをユーザーがデータベースに挿入していないことを確認してください。

幸運を。

編集:「ハッシュ」に使用するものは次のとおりです

$cryptOptions = '$2y$10$' . $salt . '$';
$hashedPassword = crypt($password1, $cryptOptions);
于 2012-11-12T18:26:26.823 に答える
0

データベース内にソルトを保存するのはなぜですか? 誰かがあなたのデータベースにアクセスしたとしましょう - 彼はパスワードとソルトを持っています。ソルトをハードコーディングした場合、または別の場所に置いた場合、彼はハッシュ化されたパスワードを持っているだけです。攻撃者がシステムへのフル アクセスを取得した場合、これはまったく問題になりません。

また、ログイン手続きに https を使用しますか?

複数のデータベース接続があり、エンコーディングが異なると仮定すると、正しいリンクをサニタイザー関数に渡す必要があります。ところで、mysql_real_escape_string を、何かを追加しない (実際には実際の関数を制限する) 別の関数でラップする利点は何ですか? PDO を使用することをお勧めします。

于 2012-11-12T18:28:59.397 に答える
0

数か月前に Java で同様のプロトタイプを実装しました。

私が見る限り、それは私が持っていたものと非常によく似ているように見えます。私が行った(または少なくとも行う予定の)いくつかのことは、あなたの説明からはわかりません

  1. 明らかに TLS を使用して HTTP チャネルを保護します。そうしないと、パスワードをプレーンテキストで送信することになります。
  2. http://en.wikipedia.org/wiki/PBKDF2などのいくつかの重要なストレッチ関数を使用して、ブルート フォース攻撃がさらに計算集約的になるようにします。
  3. ハッシュを数回適用しました。(私は 1024 回の反復を使用しました)、これもブルート フォース攻撃から保護するためです。もう一度やり直す必要がある場合は、2 の実装に時間を費やしたいと思います。
  4. セッションは、最終アクセス時間ベースで期限切れになる必要があります。

追加のアイデアが得られることを願っています。

于 2012-11-12T18:33:39.287 に答える
0

申し訳ありませんが、m02ph3u5 の投稿にコメントできないため、別の回答を投稿する必要があります。データベースへのソルトの保存は完全に標準です。ソルトが存在する理由は、レインボー テーブルでのブルート フォーシングを防ぐためです。レインボー テーブルは事前に計算されたハッシュであり、データベース内のすべてのパスワードをすばやくクラックできます。ソルトを使用すると、攻撃者に知られているものであっても、レインボー テーブルを事前に計算することはできません。これは、人々が各パスワードをブルート フォースする必要があることを意味します。これは良いことです。なぜなら、blowfish のようなアルゴリズムを使用すると、何百ものパスワードを解読するのが現実的でなくなるからです。

パスワードをクラックできないようにする方法ではありません。これは、すべてのパスワードをクラックすることを非現実的にする方法です。

編集: 彼らがあなたのデータベースにアクセスした場合、彼らはあなたのハッシュ化されたパスワードとソルトしか持っていません. 平文のパスワードは引き続き必要です。

EDIT2: つまり、彼らはサイトにアクセスできるので、その時点でやりたいことはパスワードを保護することだけです。通常、人々はパスワードを再利用します。ハッシュは、まさにそのような人々を保護するためのものです。

于 2012-11-12T18:37:22.040 に答える