|
|
|
| Привет! Терзает вопрос по счет безопасности, как вы считаете достаточно ли такого кода чтобы он был безопасен при записи в MySql и построении запроса?
<?php
$email = stripslashes($_POST['email']);
$email = htmlspecialchars($email);
if ($email == '') {
$error .= 'E-Mail не может быть пустым<br>';
}
elseif (!preg_match("/^[-0-9a-z_\.]+@[-0-9a-z_^\.]+\.[-0-9a-z_]{2,6}$/i", $email)) {
$error .= 'Некорректно указан E-Mail.<br>';
}
$name = stripslashes($_POST['name']);
$name = htmlspecialchars($name);
if ($name == '') {
$error .= 'Имя не может быть пустым<br>';
}
elseif (preg_match ("/[^а-яA-Яa-zA-Z0-9\s]/", $name)) {
$error .= "Недопустимые символы в имени<br>";
}
$text = htmlspecialchars($_POST['text']);
if (!$error) {
$query = "INSERT INTO mytable (email, name, text) VALUES ('$email', '$name', '$text')");
}
?>
|
| |
|
|
|
|
|
|
|
для: tima2010
(19.12.2011 в 14:52)
| | Вообще говоря нет, не безопасно. Если не сложно объясните, для чего предназначено это регулярное выражение?
elseif (preg_match ("/[^а-яA-Яa-zA-Z0-9\s]/", $name)) {
$error .= "Недопустимые символы в имени<br>";
}
|
PS Основная притензия в том, что у вас отсутствует экранирование... Манипулируя $_POST['name'] и кавычками я могу в $text вставить что угодно, вплоть до паролей к системе администрирования сайта, если нащупаю (или буду знать заранее), где они у вас хранятся. Можно будет вывести туда стркутуру таблиц, посмотреть какие в них поля, нет ли где-то что-то напоминающего поля для хранения пароля... в общем код считайте взломан. | |
|
|
|
|
|
|
|
для: cheops
(19.12.2011 в 15:01)
| | РВ для имени пользователя, имя может состоять только из русских букв английских букв пробела и цифр (вроде как работает корректно)
stripslashes - поставил в связи с тем, что данные почему то записываются с экранированными кавычками... На сколько я знаю они используются только для запроса если активно get_magic_quotes_gpc то кавычки экранируются но отбрасываются при записи в базу... а у меня почему то нет :(
Если вам не сложно, покажите пожалуйста на примере как лучше обезопасить себя? Просто экранировать кавычки будет достаточно? | |
|
|
|
|
|
|
|
для: tima2010
(19.12.2011 в 15:08)
| | А у вас во-первых проверка допускает все, лишь бы первым не было указан пробел или буква алфавита, нет символа окончания строки $, нет отрицания как в email. Т.е. участок следует переписывать так
$name = stripslashes($_POST['name']);
$name = htmlspecialchars($name);
if ($name == '') {
$error .= 'Имя не может быть пустым<br>';
}
elseif (!preg_match ("/[^а-яA-Яa-zA-Z0-9\s]+$/", $name)) {
$error .= "Недопустимые символы в имени<br>";
}
|
| |
|
|
|
|
|
|
|
для: cheops
(19.12.2011 в 15:10)
| | Простите запутался,
если ставить !preg_match то ошибка будет при существовании этих символов...
если я ставлю без условия ! то тогда наоборот проверка работает нормально... | |
|
|
|
|
|
|
|
для: tima2010
(19.12.2011 в 15:18)
| | Наоборот, если все эти символы существуют от начала строки до конца и никаких других нет - это то, что нам нужно, двигаемся вперед. А вот если регулярное выражение возвращает false - значит среди них затесался какой-то символ им не удовлетворяющий, нужно превратить false в true при помощи отрицания, чтобы сообщить об ошибке. | |
|
|
|
|
|
|
|
для: cheops
(19.12.2011 в 16:19)
| | Спасибо! А по счет кавычек, так буде лучше и безопаснее?
<?php
if(get_magic_quotes_gpc()==1)
{
$text=stripslashes(trim($_POST["text"]));
}
else
{
$text=trim($_POST["text"]);
}
$text=mysql_real_escape_string($text);
?>
|
| |
|
|
|
|
|
|
|
для: tima2010
(19.12.2011 в 16:24)
| | Вы знаете, лучше не использовать ==1, просто пишите get_magic_quotes_gpc() - так универсальнее будет. Нет, все что у вас написано, все правильно, это чисто стилистическая правка - короче и более универсально, в том числе и для будущих изменений в языке. | |
|
|
|
|
|
|
|
для: cheops
(19.12.2011 в 16:19)
| | немного подумав про возможными способами защиты решил написать такую функцию, что вы можете сказать на ее счет?
<?php
function security_Check($str='', $number='', $type='') {
if(get_magic_quotes_gpc() == '1') {
$str = stripslashes(trim($str));
} else {
$str = trim($str);
}
$str = mysql_real_escape_string($str);
$stt = htmlspecialchars($stt);
if(isset($number)) {
$strlen = strlen($str);
if ($strlen > $number) {
$error .= "Слишком много букв.";
}
}
if(!isset($str)) {
$error .= "Поле не должно быть пустым<br>";
}
if($type == 'text') {
if(!preg_match ("/[^а-яA-Яa-zA-Z0-9\s-]+$/", $str) {
$error .= "Использовать можно только: Русские буквы, Английские буквы, Цифры, Пробел и Тере.<br>";
}
}
if($type == 'email') {
if(!preg_match ("/^[-0-9a-z_\.]+@[-0-9a-z_^\.]+\.[-0-9a-z_]{2,6}$/i", $str) {
$error .= "Неверный E-Mail<br>";
}
}
if($type == 'number') {
if(!preg_match ("/[^0-9-+\s()]+$/", $str) {
$error .= "Использовать можно только: Цифры, Пробел, Тере и Скобки.<br>";
}
}
return $error;
}
?>
|
| |
|
|
|
|
|
|
|
для: tima2010
(19.12.2011 в 16:54)
| | Все хорошо.
PS Единственное, что я бы не стал использовать htmlspecialchars() до вставки в базу данных, только при выводе на страницу. Если будете использовать эту функцию до вставки - рано или поздно пожалеете об этом решении. Ну и скажем так, ваш код не будет считать профессиональным. Любой профессионал читая его, будет морщиться и думать примерно так: ну вот человек не был уверен в своих силах в области безопасности и перестраховывался, а мне теперь что с его кодом делать (теперь придется иметь в виду целый дополнительный класс ошибок)? | |
|
|
|
|
|
|
|
для: cheops
(19.12.2011 в 17:30)
| | а какой бы вариант решения задачи Вы предложили бы? | |
|
|
|
|
|
|
|
для: Slo_Nik
(20.12.2011 в 12:30)
| | Близкий к тому, что предложен выше (если требования действительно такие жесткие и есть необходимость использовать регулярные выражения), за минусом функции htmlspecialchars(), которую бы использовал при выводе информации из базы данных. В противном случае при редактировании данных можно получить множество проблем (причем практически неразрешимых).
Такую избыточную конструкцию
if(get_magic_quotes_gpc() == '1') {
$str = stripslashes(trim($str));
} else {
$str = trim($str);
}
$str = mysql_real_escape_string($str);
| обычно не используют, когда режутся слеши и тут же вставляются. В этом теряется преимущество позднего экранирования. Когда слеши режут, то экранирование производят уже не посредственно около SQL-запроса (всех данных без разбора откуда они поступили). Если экранирование переносится к получению внешних данных, то применяют конструкцию вида
if(!get_magic_quotes_gpc()) {
$str = mysql_real_escape_string($str);
}
|
| |
|
|
|
|
|
|
|
для: cheops
(19.12.2011 в 16:19)
| |
cheops:
Наоборот, если все эти символы существуют от начала строки до конца и никаких других нет -
это то, что нам нужно, двигаемся вперед. А вот если регулярное выражение возвращает false -
значит среди них затесался какой-то символ им не удовлетворяющий, нужно превратить false в
true при помощи отрицания, чтобы сообщить об ошибке.
|
По счет РВ, я все понимаю, но с какого то перепугу происходит следующие...
При таком условии возвращает OK
<?php
$test = "аАaZ0- Ё@"; // присутствует недопустимый символ @
if(!preg_match ("/[^а-яA-Яa-zA-Z0-9\s-]+$/", $test)) { // с !
echo "Не соответствует шаблону.";
} else {
echo "ok";
}
?>
|
При таком условии возвращает Не соответствует шаблону...
<?php
$test = "аАaZ0- Ё@"; // присутствует недопустимый символ @
if(preg_match ("/[^а-яA-Яa-zA-Z0-9\s-]+$/", $test)) { // без !
echo "Не соответствует шаблону.";
} else {
echo "ok";
}
?>
|
Но опираясь на Ваши слова выше должно же быть наоборот? Почему так? | |
|
|
|
|
|
|
|
для: tima2010
(19.12.2011 в 21:06)
| | >При таком условии возвращает OK
Да, я ошибся положением символа ^ (отладить не было возможности), вместо
нужно писать
| |
|
|
|
|
|
|
|
для: cheops
(19.12.2011 в 21:12)
| | Большое спасибо! обезопасился :) | |
|
|
|