-4

ログイン スクリプトをクリーンアップして、データベースの安全性を確保したいと考えています。私は基本的なコーダーであり、チュートリアルから学んだことなので、スクリプトには何らかの保護が必要だと思います。何か提案はありますか?

<?php

session_start();

$email = strtolower( trim($_POST['email']));
$pass = $_POST['password'];

if ($email&&$pass){

require_once("dbconnect.php");

$query = mysql_query("SELECT * FROM users WHERE username='$email'");
$numrows = mysql_num_rows($query);
if ($numrows!=0){   
//code to login
    while ($row = mysql_fetch_assoc($query)){
        $dbusername = $row['username'];        //USERNAME IS NAME OF COLUMN IN DB
        $dbpassword = $row['password'];
        $activated = $row['activated'];

        if ($activated=='0')
            die("Your account has not been activated.(Remember to check in your email spam folder)");
    }

    //check to see if they match
    if ($email==$dbusername&&md5($pass)==$dbpassword){
        //echo "You have succesfully logged-in! <a href='start.php'>Click</a> here to enter." ;
        $_SESSION['username']=$email;
        header( 'Location: http://website' ) ;
    }
    else{
        echo "The password you entered is incorrect";   
    }
}
else
    die("Sorry, the email you have entered is incorrect");

}

else
    die("Please enter your email and password");


?>
4

2 に答える 2

2

見て、私はあなたのためにそれを書き直しました!これは PDO とプリペアド ステートメントを使用し、SQL インジェクションの脆弱性に可能な限り最も洗練された方法でパッチを適用します (つまりmysql_real_escape_string、 ではありません)。また、パスワードのハッシュに bcrypt を使用します。これは、salt のない 1 つの MD5 よりもはるかに優れています。

<?php
session_start();

if(isset($_POST['email']) && isset($_POST['password'])) {
    require_once 'dbconnect.php';

    $email = strtolower(trim($_POST['email']));
    $password = $_POST['password'];

    $query = $link->prepare('SELECT * FROM users WHERE username = :email LIMIT 1');
    $query->execute(array(':email' => $email));
    $row = $query->fetch();

    if($row) {
        if(!$row->activated) {
            die('Your account has not been activated. (Remember to check in your e-mail spam folder!)');
        }

        if($row->username === $email && crypt($password, $row->password) === $row->password) {
            $_SESSION['username'] = $email;
            header('Location: http://website'); # If this isn't a relative URL, try using one.
            exit();
        }
    }

    die('Invalid e-mail and/or password. Please try again.');
}
?>

ただし、データベース、登録コード、およびデータベース接続コードにいくつか変更を加える必要があります。

于 2012-09-12T04:09:47.887 に答える
0

まず、次のように変更して SQL インジェクションの脆弱性を修正します。

$email = strtolower( trim($_POST['email']));
$pass = $_POST['password'];

if ($email&&$pass){

    require_once("dbconnect.php");

require_once("dbconnect.php");

$email = mysql_real_escape_string(strtolower( trim($_POST['email'])));
$pass = $_POST['password'];

if ($email&&$pass){

次にできることは、変更して「セッションハイジャック」を防ぐことです

if ($email==$dbusername&&md5($pass)==$dbpassword){
    //echo "You have succesfully logged-in! <a href='start.php'>Click</a> here to enter." ;
    $_SESSION['username']=$email;

if ($email==$dbusername&&md5($pass)==$dbpassword){
    //echo "You have succesfully logged-in! <a href='start.php'>Click</a> here to enter." ;
    session_regenerate_id();
    $_SESSION['username']=$email;

このログイン スクリプトが使用されている場所 (内部または外部) はわかりませんが、外部で使用されている場合は、ユーザーの IP アドレスをセッション変数として追加し、ユーザーが戻るたびに確認できます。md5() はパスワードのハッシュには推奨されないため、md5() の代わりに crypt() 関数も使用します (これは、所有しているユーザーの数と、全員のパスワードをリセットするかどうかによって異なります)。私はPHPass クラスを使用してい ます セキュリティに加えて、非推奨であるため、元の MySQL コードの代わりに MySQLi (別名 MySQL の改良版) を使用できます。ただし、MySQLi への変更は、PHP が MySQLi をサポートしているかどうかによって異なります。

于 2012-09-12T04:07:33.773 に答える