我从一个网站上得到了这个例子。我即将升级我的代码的安全性。所以,如果这个代码足够强大以防止注射,我可以得到你的意见吗?
[[1, 'Jack', 'Fishing'], [2, 'Alice', 'Reading'], [3, 'Mun', 'Football']]
$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
);
来自mysql连接
答案 0 :(得分:2)
不,该代码不够强大,无法阻止注入。它有很多问题。首先,自PHP 5.5.0起,mysql_*
函数已弃用。 始终使用mysqli_
扩展程序的等效功能。我发现你知道要逃避字符串的特殊情况,但在将密码插入表格之前,你并不知道hash()
密码。永远不要存储用户'数据库中的纯文本密码。您希望使用 Prepared Statements 来防止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 ('', ?, ?, ?, ?)
。问号是参数的占位符,您可以使用变量进行绑定。
Have a look at the PHP.net manual on mysqli::prepare
了解预处理语句的工作原理。这些对于保护您的网站和保护用户非常重要。信息。在使用预准备语句时没有必要使用mysqli_real_escape_string()
,因为参数已经被转义。
还有一个注意事项:当您对密码进行哈希处理时,请不要再使用常用的md5()
,因为这是非常不安全且容易被当今标准破解的。使用更安全的算法,例如sha256
。
答案 1 :(得分:2)
对于某些已知mysql_real_escape_string()失败的情况,您应该阅读SQL injection that gets around mysql_real_escape_string()。
在您显示的特定代码中,假设您也可以控制字符集,那么您应该是安全的。但总的来说,mysql_real_escape_string()
不是SQL注入保护的可靠或安全的解决方案。
mysql_real_escape_string()输入也很繁琐。因此,一些开发人员在尝试快速完成代码时会跳过安全编码。 " 我只是让这个代码先运行,我以后会增加安全性。" BAD IDEA。
虽然查询参数不会失败,而且它们实际上非常容易使用,所以一旦养成习惯,就更有可能从一开始就使用它们来编写安全代码。
@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则不支持。