我有问题,我的登录表单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.";
}
}
这里是usertool
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;
}
}
这不是典型的SQL注入,而是错误的SQL逻辑。
你需要给你的查询添加大括号:
SELECT * FROM tbl_user
WHERE (uname = '$username' OR eemail = '$username')
AND password = '$hashedPassword'"
在原始查询中,如果输入的用户名或电子邮件匹配,并且甚至没有检查密码,则整个语句的计算结果为true
关于SQL注入,一般来说,为了使查询安全,您必须根据这些规则格式化查询部分
- 格式必须完整。mysql_real_escape_string单独进行不完全格式化:您应该在使用此函数转义的任何数据周围添加撇号。
- 格式必须足够,这意味着你不能用字符串格式格式化数字或标识符。每个SQL文字都需要自己独特的格式。
- 格式化必须尽可能接近查询执行。
遵循这些规则,您将非常安全的从注入。使用预处理语句是遵循它们的最简单的方法。
不需要mysqli和PDO来使用原生准备语句——你可以创建自己的变体。但是,您必须将mysql_real_escape_string移到离查询执行越近的地方,并始终在结果周围添加撇号。