0

ログインスクリプトについてサポートが必要です。壊れているようです。パスワードを入力しなくても、正しくログインできます。また、何も入力しない場合。しかし、間違ったユーザー名とパスワードを入力すると、ログイン資格情報が間違っていると表示されます。

<?php   
    $verbindung = mysql_connect("localhost", "root" , "")
    or die("Verbindung zur Datenbank konnte nicht hergestellt werden"); 
    mysql_select_db("v1nce_website") or die ("Datenbank konnte nicht ausgewählt werden"); 

    $username = $_POST["username"];
    $password = $_POST["password"];

    $abfrage = "SELECT username, password FROM logins WHERE username='$username' LIMIT 1"; 
    $ergebnis = mysql_query($abfrage);
    $row = mysql_fetch_object($ergebnis);

    if($row->password == $password) 
        {
        $_SESSION["username"] = $username; 
        echo "<p>Login erfolgreich.</p>"; 
        } 
    else 
        { 
        echo "<p>Benutzername oder Passwort waren falsch. <a href=\"index.php?p=login\">Login</a></p>"; 
        } 
?>

どんな助けでもいただければ幸いです。

4

4 に答える 4

3

このスクリプトでは、気になることがたくさんあります。

  1. あなたがここにいる実際の問題から始めましょう。クエリで一致する行が見つからない場合は、$rowと等しくなりfalseます。したがって、$rowはオブジェクトではないため、$row->passwordに評価されNULLます。そのため、$password空の文字列の場合は$row->password == $passwordtrue と評価されますNULL == ""

    ini_set( 'display_errors', true );たとえば、十分なエラー レポート レベルと組み合わせて、たとえば でエラーの表示をオンにしていれば、これについて通知されていたはずですerror_reporting( E_ALL );

    間違ったユーザー名と間違ったパスワードを入力すると、$row->password再び になりNULLますが、パスワードに空でない文字列を入力したため、今回$row->password == $passwordは false と評価されます。

    したがって、この問題を軽減するには、最初に評価するなどしてパスワードの比較を開始する前に、実際に一致する行があることを確認する必要がありますmysql_num_rows( $ergebnis )

  2. スクリプトはSQL インジェクションに対して脆弱です。これは、スクリプトのユーザーが SQL ハックを の値として入力すると、害を及ぼす可能性があることを意味します$_POST[ 'username' ]。たとえば' OR 1 = 1 --、SQL クエリを入力すると、次のようになります (表示用に書式設定されています)。

    SELECT username, password
    FROM logins
    WHERE username='' OR 1 = 1 --' LIMIT 1
    

    ...テーブルが空でない場合、WHERE username='' OR 1 = 1常にtrueと評価されるため、常に少なくとも1行になります(--SQLではコメントを意味するため、' LIMIT 1評価されることさえありません)。

    この問題を軽減するには、現在のセットアップで、次のように、入力値をmysql_real_escape_string()SQL クエリに渡す前に、まず でサニタイズする必要があります。

    $username = mysql_real_escape_string( $_POST["username"] );
    

    しかし、他の人もすでにアドバイスしているように、PDOMySQLiなどのパラメーター化されたクエリを使用して準備されたステートメントを提供する MySQL 準拠のライブラリの使用を開始する方が賢明ですmysql_*。 SQL インジェクションに対する防御手段。

  3. パスワードはデータベースにそのまま (プレーン テキストとして) 保存されます。これにより、アカウント (および場合によってはユーザー関連のアカウント) が危険にさらされるさまざまな潜在的なリスクが生じます。データベースにアクセスできる人は誰でも (直接アクセス、承認済み、アクセス、またはデータベースが侵害された場合)、クリア テキストでパスワードを表示できるため、これらを使用してサイトにログインしたり、潜在的なものとして使用したりすることができます。他のサイトやサービスへのログイン。結局のところ、人々が他のさまざまなサイトやサービスで同じユーザー名とパスワードの組み合わせを使用することは珍しくありません。

    この問題を軽減するには、パスワードをデータベースに保存する前にパスワードをハッシュ(一方向暗号化) し、ユーザーがログインするときに、保存されたハッシュ値とハッシュを比較することをお勧めします (同じハッシュを使用)。ユーザーが入力したパスワードの 追加のセキュリティ対策として、ユーザー パスワードごとに一意のソルトを使用することも強くお勧めします。これにより、レインボー テーブル攻撃と呼ばれるものから保護されます。

    使用するのに適したハッシュ アルゴリズムとその理由の詳細については、この質問に対するユーザー Andrew Moore の回答を参照してください。

于 2012-12-10T15:03:45.407 に答える
1
$abfrage = "SELECT username, password FROM logins WHERE username='$username' LIMIT 1"; 
    $ergebnis = mysql_query($abfrage);
if(mysql_num_rows($ergebnis) > 0) // you can check for one
{
    $row = mysql_fetch_object($ergebnis);
//rest code goes inside here
// redirect to any page or do whatever you like
}
于 2012-12-10T14:45:29.640 に答える
1

データベースからパスワードが正しく取得されていない可能性があります。print_r($row)すべてがそこにあることを確認するために使用します。

セキュリティを強化するために、salt を含む sha1 暗号化も使用します。また、次のことを行います。

$username = mysql_real_escape_string($_POST["username"]);
$password = mysql_real_escape_string($_POST["password"]);

注射を避けるために。

お役に立てれば。

于 2012-12-11T06:06:56.103 に答える
1

SQL インジェクションから保護するためにそのようにログインしていると思いますが、mysql_real_escape_string() はその問題をすぐに修正します。私はこのようなことをします:

 $login = mysql_query("SELECT id FROM users WHERE username='" . mysql_real_escape_string($username) . "' AND password='" . mysql_real_escape_string($password) . "' LIMIT 1");
 if ( mysql_num_rows($login) > 0 ) {
      $user = mysql_fetch_array($login);
      $_SESSION['userID'] = $user['id'];
      echo 'Login successful!';
 } else { // login failed
      echo 'Login failed.';
 }

ユーザー名ではなくユーザー ID をセッションに保存していることに注意してください。テキストのユーザー名ではなく、一意の auto_increment インデックス値に基づいてユーザー アクティビティを管理する方がはるかに簡単であるため、通常はこれが適切な方法です。ほとんどのサイトではそうではありませんが、この方法を使用すると、必要に応じて複数のユーザーが同じユーザー名を持つことができます。ただし、これを行う場合は、ユーザー名ではなくメールアドレスに基づいてログインしていることを確認してください。同じユーザー名を共有しているために誰かが他の誰かとしてログインしたくないためです。

また、パスワードを暗号化する必要があります。MD5 は単純なソリューションであり、次のように実装できます。

 $password = md5($_POST['password']);

パスワード入力を md5 する場合、スラッシュについても心配する必要はありません。それが役立つことを願っています。

于 2012-12-10T14:52:19.210 に答える