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

如果您告诉我们错误是什么,它可能会帮助我们更好地回答您的问题。

但无论如何,这显然是错误的做法。这个系统有很多严重的问题。

首先,你没有清理你的输入。由于您将数据和命令混合在一起,因此用户所要做的就是输入用户名“x' or 1 = 1' --”来进入系统。原因如下:SQL 服务器将获得的唯一命令是“SELECT * FROM details WHERE USERNAME = 'x' or 1 = 1”。换句话说,如果用户名是 x 或 1 = 1(它是),那么 SQL 服务器将响应一个肯定的结果。(“用户名”末尾的两个破折号表示 SQL 中的注释,因此查询中之后的所有内容都将被忽略)。

一个真正的恶意攻击者甚至可以通过输入用户名“x'--; DROP TABLES;' 对您的系统造成严重破坏,并且您的整个数据库都将消失。(请参阅此漫画了解我的来源。)

事实上,你甚至根本不应该真正使用 mysql_query。根据PHP 文档

不鼓励使用此扩展程序。相反,应该使用 MySQLi 或 PDO_MySQL 扩展。

如果我是你,我会更多地阅读这个主题。即使这只是为了练习,最好还是一开始就把事情做好。查看PDO:它并不难学,但非常有用。它的主要优点是它不会混合数据和命令,因此您不会遇到同样的问题,即未经处理的输入会弄乱您的数据库。

此外,虽然很高兴看到您正在对您的密码进行哈希处理——而且您会惊讶于有多少公司应该更清楚地不这样做——MD5 不再被认为是加密安全的。获得所谓的“哈希冲突”相对容易,其中两个不同的明文产生相同的哈希。现在,SHA-256 应该是您使用的最低要求。

此外,关于散列,你应该添加一些叫做盐的东西。盐是您添加到明文中以进一步混淆它的某种随机文本。原因是那里有所谓的彩虹表。彩虹表是所有常见密码的预先计算的哈希列表。如果有人要获取您的数据库,他们可以将所有密码与彩虹表进行比较以找到它们的明文。

最后,为了减缓蛮力攻击——攻击者尝试所有字母数字组合直到他们获得密码——你还应该使用一个循环,其中哈希算法被重新计算 x 次,通常在 1000 到10000 次。PHP 的crypt很好地做到了这一点。

顺便说一句:不要难过。我以前也做过所有这些事情。这就是为什么我知道你不应该这样做。别担心——你很快就会到达那里。坚持下去!

于 2012-10-05T00:25:59.467 回答
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 回答