0

ユーザーにユーザー名/パスを入力してログインさせ、この情報をファイルに保存するWebサイトがあります。これが私の現在のコードです:

function getPassword( $user )
{
  $passwords= array 
       (
        'Admin' => '123456',
        'Moderator' => 'abcde'
       );
 eval(file_get_contents('./login.info'));  //<--- THIS is where usernames/passwords are stored  

    $password = $passwords[ $user ];
    if ( NULL == $password )
        return NULL;

    return array( $user, $password );
}

これは、新しいアカウントを作成するユーザー用のコードです。

<?php
if((isset($_POST['username']))and(isset($_POST['password']))){
 $file = "login.info";
 $fh = fopen($file, 'a');
//prevent sql injection
function check_field($fh)
{
  if(!preg_match("/[^a-zA-Z0-9\.\-\_\@\.\+\~]/",$fh))
  return TRUE;
  else
  return FALSE;
}
if(!check_field($_POST[username]))
{
  header("Location:illegalchars.html");
  break;
}
if(!check_field($_POST[password]))
{
  header("Location:illegalchars.html");
  break;
}
 fwrite($fh, '$passwords["'.$_POST['username'].'"]="'.$_POST['password'].'";');
 fclose($fh);
 header("Location:success.html");
 break;
}
?>

私のコードがきれいではなく、大きな問題があることはわかっています。
そのうちの 1 つ: 誰かがユーザー名 x でアカウントを作成した場合、誰もが新しいパスワードを使用して x を作成し、制御を得ることができます。
私が持っていた簡単な解決策eval(file_get_contents('./login.info'));は、管理者アカウントの上に移動し、新しいユーザー/パスのリストの一番上に新しいアカウントを追加することでした. ただし、配列の上に eval を配置しても機能しない理由がわかりません。また、コードをリストの一番上に追加する方法。どんな助けでも大歓迎です。

==編集== このコードには多くの批判があることは承知していますが、誰か質問に答えていただけませんか? 現時点では、セキュリティ/パフォーマンスを向上させようとしているわけではありません (これは概念実証ゲームのためのものであり、最終的には、とにかくこの全体を書き直す必要があります)。機能的なスクリプトが欲しいだけです。質問に答えてください。:]

4

3 に答える 3

2

率直に言って、ここには大きな問題があります。

ゼロ。プレーンテキストのパスワードを保存するべきではありません。これまで。sha1() (md5 ではない) などの一方向ハッシュとソルトを使用します。これについては、インターネット上にたくさんのマニュアルがあります。

1。eval() を使用することは、パフォーマンスとセキュリティの両方の観点から悪い習慣です。他のメカニズムを探してください。それらは常にそこにあります。

二。PHP ファイル以外の信頼できるデータ ストレージ メカニズムを使用する必要があります。ユーザーに対して重複したレコードが作成されないようにする手段を持つ mysql などの RDBMS を使用することをお勧めします。

三。ユーザー名に admin や mod などの特別な意味を持たせたり、パーミッションを特別なフィールドにしたり、役割ベースの承認の使用を検討したりしないでください。

四。適切なアーキテクチャがなければ、特定のユーザーに対して実行されるコードのセキュリティを制御することはできません。オブジェクトベースの MVC アプローチの使用を検討してください。これについても多くのマニュアルを見つけることができます。

これは批判的に聞こえて申し訳ありませんが、提示されたコードにパッチを公開するよりも、これがより良い答えであると真剣に信じています.

于 2011-01-18T05:26:01.197 に答える
1

ログインスクリプト

openid のようなものを実際に使用できない場合は、ここで私の改善されたスクリプトをログイン スクリプトに表示できます (最後の手段にする必要があります..)。

OpenId

念のため、独自のログイン システムを作成しないでください (パスワードを保存しないでください)。Lifehacker がどのようにハッキングされたかについては、Stackoverflow の著者によるこの記事をお読みください。私は特にこの引用が好きで、完全に同意します。

私はゴーカーを批判するためにここにいるわけではありません。それどころか、ウェブサイトのパスワードに関する汚れた真実を広く大胆に浮き彫りにしてくれたことに感謝したいと思います。Gawker スタイルのパスワード侵害のない将来の Web を見たい場合は、一意のユーザー名とパスワードですべてのランダムなインターネット サイトを信頼するのをやめてください。インターネットの運転免許証 (つまり、既存の Twitter、Facebook、Google、または OpenID 資格情報) を使用して Web サイトにログインすることを許可するよう要求します。

代わりに、たとえば openid( lightopenid ) を使用する必要があります。リンクを読んで、openid を Web サイトに簡単に統合できることを確認してください。

于 2011-01-18T09:00:03.393 に答える
1

ああ、神様!

これをDailywtfに投稿できますか。

eval データベースとプレーンテキスト データベースに本質的な問題はありませんが、問題を解決するためのより良い方法がない場合に限られます。それでも、入力をフィルタリングして広範囲に評価し、データベースの上で抽象化を使用する必要があります。

操作を実行するたびにデータベース全体を読み取るOTOHは、まったく間違っています。

暗号化されていないパスワードを保存するのは間違っています。

mysql は使えないとおっしゃいましたが、dbm はどうでしょうか。sqlite? ちょっとグーグルで調べてみると、プレーンテキストまたは CSV ファイルの上で実行されているフラットファイルの抽象化レイヤーがたくさんあることがわかります。

于 2011-01-18T12:40:21.337 に答える