从表单中注入SQL

时间:2012-02-25 14:45:20

标签: php sql-injection user-registration

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

网址编码的POST输入邮件设置为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注入攻击

@Pekka

 $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; }?>

如果没有错误

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

编辑//

所以我们用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'];

1 个答案:

答案 0 :(得分:-1)

据我所知,你应该逃离这里的所有领域:

$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_real_escape_string()安全。

无论如何你也可以使用Prepared语句忘掉这一切!! http://php.net/manual/en/pdo.prepared-statements.php

修改 好吧,那里没有有效的用户名,对吗?那么这个怎么样:

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';
}

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