我希望系统只接受新的用户名,使我的注册过程更加安全。下面显示了我用于signup.php的代码。请帮我。
你认为这段代码的安全性足以进行SQL注入吗?如果没有,哪些代码可以安全,如何?
<?php
include"connection.php";
if (!isset($_POST['submit'])) //if the user clicks the submit button then the PHP code POST the details
{
$user_name = $_POST['username'];
$user_password = $_POST['password'];
$user_email = $_POST['email'];
if($user_name && $user_password && $user_email)
{
$query = mysql_query("INSERT INTO users (username, password, email, type)
VALUES ('$user_name', '$user_password', '$user_email', '0')");
mysql_query($query);
echo '<script type="text/javascript">alert("You have been registered");</script>';
}
else {
echo '<script type="text/javascript">alert("All fields required");</script>';
header("location:user_create.html");
}
}
&GT;
答案 0 :(得分:0)
首先,您应该更改以下内容:
if (!isset($_POST['submit'])) //if the user clicks the submit button then the PHP code POST the details
{
$user_name = $_POST['username'];
$user_password = $_POST['password'];
$user_email = $_POST['email'];
// ...
}
对此:
if (isset($_POST['submit'])) //if the user clicks the submit button then the PHP code POST the details
{
$user_name = mysql_real_escape_string($_POST['username']);
$user_password = mysql_real_escape_string($_POST['password']);
$user_email = mysql_real_escape_string(($_POST['email']);
// ...
}
然后在运行mysql_query($query);
之前,您应该通过使用select
语句在数据库中查询来检查用户是否存在,例如:
$query = sprintf("SELECT * FROM users WHERE email='%s' OR username='%s'", $user_email, $user_name);
$result = mysql_query($query);
if(!$result) {
$query = sprintf("INSERT INTO users (username, password, email, type) VALUES ('%s','%s','%s','%d')", $user_name, $user_password, $user_email, 0));
mysql_query($query);
if(mysql_affected_rows() > 0)
{
// inserted
}
else {
// not inserted
}
}
自PHP 5.5.0起,不推荐使用MySQL扩展,并将其删除 未来。相反,MySQLi或PDO_MySQL扩展名 应该使用。
答案 1 :(得分:0)
为了防止SQL注入,您必须预处理所有变量(SESSION,COOKIE,GET,POST和地址栏(又名$ _SERVER ['REQUEST_URI'])。
对于此方法,PHP有一个名为filter_vars和filter_var。
的命令大多数人会使用strip_slashes,或mysql_escape_string或mysql_real_escape_string。虽然那些确实符合他们的目的,但我建议运行那些AFTER filter_vars,并且为了更安全,如果您知道数据类型,请检查它。
请勿使用preg_match(),因为这可以执行$ haystack参数中的代码。
$filterd = filter_var($_POST['username'], FILTER_SANITIZE_STRIPPED);
if($filtered) {
$filtered = sprintf("%s", mysql_real_escape_string($filtered));
// Now it should be safe to use preg_replace()
} else {
echo 'Username is invalid';
exit(0);
}
// Your database code here
如果您知道要传递的数据类型以便进行检查,例如
,那么这也是一种很好的做法。is_int($filtered);
通过限制输入进一步验证,例如,如果你正在寻找一个范围内的数字,你会做这样的事情::
$filterd = filter_var($_POST['fieldnumber'], FILTER_SANITIZE_STRIPPED);
if($filtered && is_numeric($filtered)) {
$filtered = sprintf("%d", mysql_real_escape_string($filtered));
$filtered = intval($filtered);
// Constrain the integer value to a number between 0 and 255
$filtered = max(255, min(0, $adjust));
// Now it should be safe to use preg_replace()
} else {
echo 'Username is invalid';
exit(0);
}
// Your database code here
PHP是一种很棒的语言,因为它允许你用不同的方法做很多事情。因此,还有另一种方法是filter_var包装器,称为filter_input。
在这个链接的php.net官方网站上有很多文档和用法示例 http://ca3.php.net/manual/en/function.filter-input.php
简单解释一下,它允许你传递另一个参数来指定你想要过滤的输入类型(SESSION,COOKIE,GET,POST等),并且可以说比使用 filter_var
这是我提出的完整解决方案,其中包含使用mysqli连接的过滤器和预处理语句。准备好的语句消除了对数据进行任何转义的需要,因为它是自动处理的。还有其他检查可以帮助保护您免受SQL注入。
// Define database connection details
define('MYSQL_SERVER', 'localhost');
define('MYSQL_USER', 'root');
define('MYSQL_PASSWORD', '');
define('MYSQL_DATABASE', 'test');
// Define SQL query strings
define('SQL_USERCHECK', "SELECT email,username FROM users WHERE email=? OR username=?");
define('SQL_USERINSERT', "INSERT INTO users (username, password, email, type) VALUES (?, ?, ?, ?)";
if(isset($_POST['submit'])) {
// Sanitize Variables from POST
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRIPPED);
$password = filter_input(INPUT_POST, 'password', FILTER_SANITIZE_STRIPPED);
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
$user_added = false;
// Check if username, password, and email exist after sanitization.
if($username && $password && $email) {
// Call custom function below for inserting
if(insert_user($username, $password, $email)) {
$user_added = true;
echo '<script type="text/javascript">alert("You have been registered");</script>';
}
}
// If user was not added it means that the user exists,
// or the values for username,password,email were not valid
// after filtering.
if(!$user_added) {
// Added the redirect to Javascript for you.
echo '<script type="text/javascript">alert("All fields are required"); window.location.replace(\'user_create.html\')</script>';
}
}
function insert_user($username, $password, $email) {
$user_found = false;
$user_inserted = false;
$errors = 0;
$cn = new mysqli(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE);
if (mysqli_connect_errno()) {
printf("Connection failed: %s\n", mysqli_connect_error());
exit(0);
}
// Prepare the Username || Email check
if ($s = $mysqli->prepare(SQL_USERCHECK)) {
if(
// Bind paramaters
$s->bind_param("s", $username) &&
$s->bind_param("s", $email)
) {
$s->execute();
if($row = $stmt->fetch_row()) {
// User exists;
$user_found = true;
}
} else {
// One of the params did not bind
$errors++;
}
$s->close();
}
// If user not found, Insert record
if(!$user_found && $errors == 0) {
$type = 0; // You have "type='0'" in your SQL insert statement
if ($s = $mysqli->prepare(SQL_USERINSERT)) {
if(
// Bind paramaters
$s->bind_param("s", $username) &&
$s->bind_param("s", $password) &&
$s->bind_param("s", $email) &&
$s->bind_param("i", $type)
) {
$s->execute();
if($stmt->affected_rows > 0) {
// User was added to the database
$user_inserted = true;
}
} else {
// One of the params did not bind
$errors++;
}
$s->close();
}
}
$cn->close();
return $user_inserted;
}