-1

我的登录表单有问题 sql 注入正​​在处理它,所以如何停止它。

我正在使用mysql_real_escape_string但没有任何改变

if(isset($_POST['submit-login'])) { 

    $user = $_POST['username'];
    $pass = $_POST['password'];

    $username = mysql_real_escape_string($user);
    $password = mysql_real_escape_string($pass);

    $usertool = new Usertool();
    if($usertool->login($username, $password)){
        //successful login, redirect them to a page
        header("Location: index.php");
    }else{
        $error = "Incorrect username or password. Please try again.";
    }
}

这是用户工具

class usertool {
    public function login($username, $password) {
        $hashedPassword = md5($password);
        $result = mysql_query("SELECT * FROM tbl_user WHERE uname = '$username' OR eemail = '$username' AND password = '$hashedPassword'");
        if (mysql_num_rows($result) == 1) {
            $_SESSION["user"] = serialize(new User(mysql_fetch_assoc($result)));
            $_SESSION["login_time"] = time();
            $_SESSION["logged_in"] = 1;     
            return true;
        } else {
            return false;
        }
}
4

1 回答 1

4

在您的情况下,这不是经典的 SQL 注入,而是错误的 SQL 逻辑。

您需要在查询中添加大括号:

SELECT * FROM tbl_user 
   WHERE (uname = '$username' OR eemail = '$username') 
      AND password = '$hashedPassword'"

在您的原始查询中,如果输入的用户名或电子邮件匹配,则整个语句的计算结果为 true,甚至没有检查密码

关于一般的 SQL 注入,为了使您的查询安全,您必须根据这些规则格式化查询部分

  1. 格式化必须完整。mysql_real_escape_string 单独进行不完整的格式化:您应该在使用此函数转义的任何数据周围添加撇号。
  2. 格式必须足够,这意味着您不能使用字符串格式来格式化数字或标识符。每个 SQL 文字都需要它自己独特的格式。
  3. 格式化必须尽可能接近查询执行。

遵循这些规则,您将不会被注射。使用准备好的语句是遵循它们的最简单方法。

一个不需要 mysqli 也不需要 PDO 来使用本机准备语句 - 您可以创建自己的变体。但是,您必须将 mysql_real_escape_string 尽可能靠近查询执行,并始终在结果周围添加撇号。

于 2013-05-20T08:12:19.233 回答