这段代码是反 mysql 注入吗?
Is this code anti mysql injection?
我从一个网站上得到了这个例子。我即将升级我的代码的安全性。如果这种代码足够强大以防止注入,请问您有什么意见?
$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 连接
不,该代码不够强大,无法防止注入。它有很多问题。首先,自 PHP 5.5.0 以来,mysql_*
函数已被 弃用 。 始终 使用 mysqli_
扩展的等效功能。我发现你知道转义字符串很奇怪,但你不知道 hash()
your password before inserting it into the table. Never store users' passwords in plain text in your database. You want to use 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()
,因为参数已经转义。
附带说明:当您对密码进行哈希处理时,不要退回到 commonly-used md5()
,因为这是非常不安全的,而且按照今天的标准 easily-crackable。使用更安全的算法,例如 sha256
.
对于已知 mysql_real_escape_string() 失败的某些情况,您应该阅读 SQL injection that gets around 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 不支持。
我从一个网站上得到了这个例子。我即将升级我的代码的安全性。如果这种代码足够强大以防止注入,请问您有什么意见?
$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 连接
不,该代码不够强大,无法防止注入。它有很多问题。首先,自 PHP 5.5.0 以来,mysql_*
函数已被 弃用 。 始终 使用 mysqli_
扩展的等效功能。我发现你知道转义字符串很奇怪,但你不知道 hash()
your password before inserting it into the table. Never store users' passwords in plain text in your database. You want to use 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()
,因为参数已经转义。
附带说明:当您对密码进行哈希处理时,不要退回到 commonly-used md5()
,因为这是非常不安全的,而且按照今天的标准 easily-crackable。使用更安全的算法,例如 sha256
.
对于已知 mysql_real_escape_string() 失败的某些情况,您应该阅读 SQL injection that gets around 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 不支持。