Php 来自表单的Sql注入

Php 来自表单的Sql注入,php,sql-injection,user-registration,Php,Sql Injection,User Registration,我用Acunetix Web漏洞扫描程序8测试我的站点,它说我的注册页面中有2个sql注入 URL编码的邮件输入设置为1##xa7## URL编码的POST输入用户名设置为1##xa7## 发现错误消息:提供的参数不是有效的MySQL结果 这两个函数的Php代码 $username = mysql_real_escape_string(trim($_POST['username'])); $email = mysql_real_escape_string(trim($_POST['email

我用Acunetix Web漏洞扫描程序8测试我的站点,它说我的注册页面中有2个sql注入

URL编码的邮件输入设置为1##xa7## URL编码的POST输入用户名设置为1##xa7##

发现错误消息:提供的参数不是有效的MySQL结果

这两个函数的Php代码

 $username = mysql_real_escape_string(trim($_POST['username']));
 $email = mysql_real_escape_string(trim($_POST['email']));

        if ($username==!preg_match('/^[a-zA-Z0-9._]+$/', $username)){
         $error_stat = 1; 
              $message_error .= 'Error:invalid username.';
        }
         elseif (!filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL)) {
            $error_stat = 11; 
              $message_error .= 'Error:invalid email.';

          }
那么,这如何容易受到sql注入的攻击呢

@佩卡

 $checkusername = mysql_query("SELECT Username FROM users WHERE Username = '$username'");
    $checkemail = mysql_query("SELECT EmailAddress FROM users WHERE EmailAddress = '$email'");

    $username_exist = mysql_num_rows($checkusername);
    $email_exist = mysql_num_rows($checkemail);
如果其中一个存在以显示错误:

<?php if ($error_stat > 0){ echo $message_error; }?>
编辑//

伙计们,我用PDO创建了另一个页面,新的错误是:

SQLSTATE[HY000]: General error: 1267 Illegal mix of collations (cp1251_general_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation '='
这是我单击“使用HTTP编辑器启动攻击”时Acunetix显示的。程序使用的用户名是
1%c0%00xa7%c0a2

PDO

通过程序,用户名为=1%c0%00xa7%c0a2,错误在第32行

 line 30 $getMail = $dbh->prepare("SELECT EmailAddress FROM users WHERE username = :username");
    line 31 $getMail->bindParam(':username', $username);
    line 32 $getMail->execute();
    line 33 $rowMail = $getMail->fetch();
    line 34 $email = $rowMail['emailaddress'];

根据我所能告诉你的,你应该避开这里的所有字段:

$registerquery = mysql_query("INSERT INTO users (Username, password, EmailAddress,Activation,registered) VALUES('".$username."', '".$password."', '".$email."','".$activation."','".$date."')");
你有:

$username = mysql_real_escape_string(trim($_POST['username']));
 $email = mysql_real_escape_string(trim($_POST['email']));
对于$password、$activation和$date,您应该有相同的密码。。。我不知道你是否知道

不管怎样,我通常使用这个:

function getPost($s) {
        if (array_key_exists($s, $_POST))
            return mysql_real_escape_string(htmlspecialchars($_POST[$s]));
        else return false;
    }


    function getGet($s) {
        if (array_key_exists($s, $_GET))
            return mysql_real_escape_string(htmlspecialchars($_GET[$s]));
        else return false;
    }
但这也是为了防止XSS的攻击。。。我认为使用mysql\u real\u escape\u string()应该是安全的

无论如何,你也可以使用事先准备好的语句,忘掉这一切

编辑 嗯,那里没有有效的用户名,对吗?那么这个呢:

try{
$getMail = $dbh->prepare("SELECT EmailAddress FROM users WHERE username = :username");
$getMail->bindParam(':username', $username);
$getMail->execute();
$rowMail = $getMail->fetch();
$email = $rowMail['emailaddress'];
}
catch( PDOException $Exception ) {
echo 'Authentication Failed';
}

现在无法测试它,但它应该是围绕这行的…

您可以显示您正在使用的数据库代码吗?您需要发布更多代码。设置$error\u stat后,我无法判断您是否正在查看它。(I)preg\u match返回布尔值,因此我不知道
$username
应该包含什么内容(ii)您可以发布用于生成查询的代码吗?I检查现有的acc和邮件,如果没有错误,请显示完整的代码,包括你在哪里做mysql\u real\u escape\u string()?我确实有,但是Acunetix只显示用户名和电子邮件的错误,这就是为什么我只显示它们你的getPost/get函数是非常无用的。不要质疑这一点,但是,你能详细说明一下吗?我想了解:)“预处理语句的参数不需要引用;驱动程序会自动处理此问题。如果应用程序专门使用预处理语句,开发人员可以确保不会发生SQL注入(但是,如果查询的其他部分是使用未经转换的输入构建的,那么SQL注入仍然是可能的)。”
try{
$getMail = $dbh->prepare("SELECT EmailAddress FROM users WHERE username = :username");
$getMail->bindParam(':username', $username);
$getMail->execute();
$rowMail = $getMail->fetch();
$email = $rowMail['emailaddress'];
}
catch( PDOException $Exception ) {
echo 'Authentication Failed';
}