我从一个网站得到了这个例子。我要升级我的代码的安全性。那么,我可以有你的意见,如果这种代码足够强大,以防止注入?
$sql = sprintf(
"
INSERT INTO `members`
(`id`, `username`, `password`, `first_name`, `last_name`)
VALUES
('', '%s', '%s', '%s', '%s')
",
mysql_real_escape_string($con,$_POST['username']), // %s #1
mysql_real_escape_string($con,$_POST['password']), // %s #2
mysql_real_escape_string($con,$_POST['first_name']), // %s #3
mysql_real_escape_string($con,$_POST['last_name']) // %s #4
);$con来自mysql连接。
发布于 2018-03-18 07:03:26
不,那个代码不足以防止注入。它有很多地方不对劲。首先,从PHP5.5.0开始就不再推荐mysql_*函数了。总是使用mysqli_扩展的等效函数。我觉得奇怪的是,您知道如何转义字符串,但是在将密码插入到表中之前,您不知道如何使用hash()密码。不要将用户的密码以纯文本形式存储在数据库中。您希望将准备好的陈述用于防止SQL注入的最有效方法。试试这样的东西。
$q = "INSERT INTO `members` (`id`, `username`, `password`, `first_name`, `last_name`) VALUES ('', ?, ?, ?, ?)";
$stmt = mysqli_prepare($con, $q);
mysqli_stmt_bind_param($stmt, "ssss", $p_user, $p_pass, $p_first, $p_last);
$p_user = $_POST['username'];
$p_pass = hash("sha256", $_POST['password']);
$p_first = $_POST['first_name'];
$p_last = $_POST['last_name'];
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt);请参见,在初始查询字符串中,您希望使用VALUES ('', ?, ?, ?, ?)。问号是使用变量绑定的参数的占位符。
mysqli::prepare来了解准备好的语句是如何工作的。这些东西对于保护你的网站和保护用户的信息是非常重要的。在使用准备语句时没有必要使用mysqli_real_escape_string(),因为参数已经转义了。
另外要注意的是:当你破解你的密码时,不要回到常用的md5()上,因为这是非常不安全的,而且按照今天的标准很容易破解。使用更安全的算法,比如sha256。
发布于 2018-03-18 17:36:44
对于已知字符串() ()失败的一些情况,您应该阅读mysql_real_escape_string()。
在您显示的特定代码中,假设您也可以控制字符集,那么您应该是安全的。但是总的来说,mysql_real_escape_string()并不是一个可靠或安全的SQL注入保护解决方案。
mysql_real_escape_string()也是冗长乏味的类型。因此,一些开发人员在试图快速完成代码时跳过安全编码。“我刚开始运行这段代码,稍后我会增加安全性。”的坏主意.
查询参数不会失败,而且它们实际上很容易使用,因此,一旦养成了这种习惯,就更有可能从一开始就使用它们编写安全代码。
@TannerBabcock提供了一个mysqli示例,但我更喜欢PDO,因为它更容易:
$sql = "
INSERT INTO `members`
(`username`, `password`, `first_name`, `last_name`)
VALUES (?, ?, ?, ?)
",
$params = [
$_POST['username'],
password_hash($_POST['password'], PASSWORD_DEFAULT),
$_POST['first_name'],
$_POST['last_name']
];
$stmt = $pdo->prepare($sql);
$stmt->execute($params);在PDO中,您可以简单地向execute()传递一个参数数组,我认为这比将变量参数列表传递给mysqli_stmt_bind_param()的mysqli方法更容易。
PDO也支持命名参数,而mysqli不支持。
https://stackoverflow.com/questions/49345061
复制相似问题