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';
}
Не могу проверить это сейчас, но это должно быть что-то вроде этого...