Sql инъекция из формы

Я тестирую свой сайт с помощью Acunetix Web Vulnerability Scanner 8 и мне говорят, что у меня есть 2 sql инъекций на моей странице регистрации

Зашифрованный URL-адрес входного POST-адреса URL был установлен на 1##xa7## Зашифрованный входной POST-адрес URL-адреса был установлен на 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 '='

Это то, что показывает Acunetix, когда я нажимаю на Запустить атаку с HTTP Editor. И имя пользователя, используемое программой 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 ответ

Из того, что я могу сказать, вы должны экранировать все поля здесь:

$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']));

Вы должны иметь то же самое для $ пароля, $ активации и $ даты... Не уверен, если вы делаете

В любом случае я использую обычно использовать это:

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().

В любом случае вы также можете использовать Подготовленные заявления и забыть все об этом! 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';
}

Не могу проверить это сейчас, но это должно быть что-то вроде этого...

Другие вопросы по тегам