这段代码是反mysql注入的吗?

时间:2018-03-18 06:23:09

标签: php sql-injection

我从一个网站上得到了这个例子。我即将升级我的代码的安全性。所以,如果这个代码足够强大以防止注射,我可以得到你的意见吗?

[[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连接

2 个答案:

答案 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则不支持。