0

このエラーが発生しましたが、その理由がよくわかりません。私はこれを何時間も調べてきましたが、調査で調べてみましたが、うまくいきませんでした。

PHP ログイン システムで、行が選択されているかどうかを確認します。

//Start session
    session_start();

    //Include database connection details
    require_once('config.php');

    //Array to store validation errors
    $errmsg_arr = array();

    //Validation error flag
    $errflag = false;

    //Connect to mysql server
    $link = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
    if(!$link) {
        die('Failed to connect to server: ' . mysql_error());
    }

    //Select database
    $db = mysql_select_db(DB_DATABASE);
    if(!$db) {
        die("Unable to select database");
    }

    //Prevent SQL injection.
    function clean($str) {
        $str = @trim($str);
        if(get_magic_quotes_gpc()) {
            $str = stripslashes($str);
        }
        return mysql_real_escape_string($str);
    }

    //Sanitize the POST values
    $login = clean($_POST['login']);
    $password = clean($_POST['password']);

    //Input Validations
    if($login == '') {
        $errmsg_arr[] = 'Login ID missing';
        $errflag = true;
    }
    if($password == '') {
        $errmsg_arr[] = 'Password missing';
        $errflag = true;
    }

    //If there are input validations, redirect back to the login form
    if($errflag) {
        $_SESSION['ERRMSG_ARR'] = $errmsg_arr;
        session_write_close();
        echo "input validation";
        exit();
    }

    //Create query
    $qry="SELECT * FROM details WHERE USERNAME='$login' AND PASSWORD='".md5($_POST['password'])."'";
    $result=mysql_query($qry);

    //Check whether the query was successful or not
    if($result) {
        if(mysql_num_rows($result) == 1) {
            //Login Successful
            session_regenerate_id();
            $member = mysql_fetch_assoc($result);
            $_SESSION['MEMBER_ID'] = $member['USERNAME'];


            session_write_close();
            header("location: client-index.php");
            exit();
        }else {
            //Login failed
            echo "login failed?";
            exit();
        }
    }else {
        die("Query failed");
    }
?>   

何らかの理由で「失敗しました」と表示されます。

4

3 に答える 3

1

私はこのサイトを初めて使用するため、コメントを追加できません。これはあまり役に立たないかもしれませんが、とにかく試してみてください

SQLクエリでは、変数 $login を変数値ではなくテキストとして渡しているようです

$qry="SELECT * FROM details WHERE USERNAME='$login' AND PASSWORD='".md5($_POST['password'])."'";

そしてそれはあるべきです

$qry="SELECT * FROM details WHERE USERNAME=".$login." AND PASSWORD='".md5($_POST['password'])."'";
于 2012-10-05T00:49:31.130 に答える
1

クエリが失敗したか、ログインが失敗しましたか?

とにかくクエリが失敗した場合:クエリをこれに変更してみてください:フィールドをバッククォートで囲みます(一重引用符ではありません)

$qry="SELECT * FROM details WHERE `USERNAME`='$login' AND `PASSWORD`='".md5($_POST['password'])."'";

ログインに失敗した場合:

if(mysql_num_rows($result) == 1) {
    //Login successful
}else {
    //Login failed
}

クエリの結果は 1 つしかありませんか? この条件では、results が 1 より大きい場合もログインに失敗するためです。

于 2012-10-05T01:36:25.710 に答える
1

エラーの内容を教えていただければ、質問への回答に役立つ場合があります。

しかし、いずれにせよ、これは明らかに間違った方法です。このシステムには多くの深刻な問題があります。

まず第一に、入力をサニタイズしていません。データとコマンドを混ぜ合わせているので、ユーザーがしなければならないことは、システムに入るために「x' または 1 = 1' --」 のユーザー名を入力することだけです。理由は次のとおりです。SQL サーバーが取得する唯一のコマンドは、「SELECT * FROM details WHERE USERNAME = 'x' or 1 = 1」です。つまり、ユーザー名が x または 1 = 1 (どちらも) の場合、SQL サーバーは肯定的な結果を返します。(「ユーザー名」の末尾にある 2 つのダッシュは、SQL のコメントを表すため、クエリ内のそれ以降はすべて無視されます)。

本当に悪意のある攻撃者は、ユーザー名「x'--; DROP TABLES;」を入力してシス​​テムに大混乱をもたらすことさえあり、データベース全体が失われます. (これを入手した場所については、このコミックを参照してください.)

実際、mysql_query をまったく使用するべきではありません。PHPのドキュメントによると:

この拡張機能の使用はお勧めできません。代わりに、MySQLi または PDO_MySQL 拡張機能を使用する必要があります。

私があなただったら、この件についてもう少し読んでみたいと思います。これが単なる練習用であっても、最初から正しく理解することが最善です。PDOを調べてください。習得するのはそれほど難しくありませんが、非常に便利です。その主な利点は、データとコマンドが混在しないことです。そのため、サニタイズされていない入力がデータベースを台無しにするという同じ問題は発生しません。

また、パスワードをハッシュ化しているのは良いことですが (よく知っているはずの企業の多くがそうしていないことに驚かれることでしょう)、MD5 はもはや暗号学的に安全であるとは見なされていません。2 つの異なる平文が同じハッシュを生成する「ハッシュ衝突」と呼ばれるものを比較的簡単に取得できます。ここで、SHA-256 は最低限使用する必要があります。

また、ハッシュに関しては、ソルトと呼ばれるものを追加する必要があります。ソルトは、プレーンテキストをさらに難読化するために追加するある種のランダム テキストです。その理由は、レインボー テーブルと呼ばれるものがあるからです。レインボー テーブルは、一般的なすべてのパスワードの事前計算されたハッシュのリストです。誰かがあなたのデータベースを入手した場合、すべてのパスワードをレインボー テーブルと比較して平文を見つけることができます。

最後に、ブルート フォース攻撃 (攻撃者がパスワードを取得するまですべての英数字の組み合わせを試す攻撃) を遅くするために、ハッシュ アルゴリズムが x 回 (通常は 1000 ~ 10000回。PHP のcryptはこれをうまく処理します。

ところで、気分を悪くしないでください。私も以前にこれらすべてのことをやったことがあります。だからこそ、やってはいけないことを知っています。心配しないでください。すぐに到着します。それを続けてください!

于 2012-10-05T00:25:59.467 に答える