Насколько опасен этот PHP-код?
-
03-07-2019 - |
Вопрос
Насколько опасен этот php-код?Что можно с этим сделать?
$name = $_POST["user"];
$pwd = $_POST["pwd"];
$query = "SELECT name,pwd FROM users WHERE name = '$name' AND pwd = '$pwd'";
Решение
Возможные проблемы:
- SQL-инъекция
- Внедрение XSS (если бы этот код был запросом insert, это было бы определенной проблемой)
- Обычный Текстовый Пароль
Ваш оператор SQL может быть проблематичным.Оставлять себя открытым для SQL-инъекции - плохая практика.
SQL-инъекция - это плохо.Поверь мне.
Если вы хотите отобразить $user на HTML-странице, то, возможно, вы не захотите включать возможность для людей "взломать" ваш макет, введя команды типа
<H1>HI MOM</H1>
или куча javascript.
Кроме того, никогда не храните свой пароль в виде обычного текста (удачной уловки cagcowboy!).Это дает слишком много полномочий людям, управляющим (или взламывающим) вашу базу данных.Вам никогда не понадобится знать чей-либо пароль.
Попробуйте такую тактику, как эта:
// mostly pulled from http://snippets.dzone.com/posts/show/2738
function MakeSafe($unsafestring)
{
$unsafestring= htmlentities($unsafestring, ENT_QUOTES);
if (get_magic_quotes_gpc())
{
$unsafestring= stripslashes($unsafestring);
}
$unsafestring= mysql_real_escape_string(trim($unsafestring));
$unsafestring= strip_tags($unsafestring);
$unsafestring= str_replace("\r\n", "", $unsafestring);
return $unsafestring;
}
// Call a function to make sure the variables you are
// pulling in are not able to inject sql into your
// sql statement causing massive doom and destruction.
$name = MakeSafe( $_POST["user"] );
$pwd = MakeSafe( $_POST["pwd"] );
// As suggested by cagcowboy:
// You should NEVER store passwords decrypted.
// Ever.
// sha1 creates a hash of your password
// pack helps to shrink your hash
// base64_encode turns it into base64
$pwd = base64_encode(pack("H*",sha1($pwd)))
Другие советы
Это опасно:
Помимо SQL-инъекций, похоже, что ваши пароли могут храниться в виде обычного текста, что не очень хорошо.
Этот код очень безопасен, если вы никогда не передадите $ query в базу данных SQL.
Если кто-то должен был опубликовать 0';drop table users;--
имя
ваша команда в конечном итоге окажется
select name, pwd form users where name='0';
drop table users; --'and pwd = '[VALUE OF PWD]'
Итак, сначала он получит ваши данные, затем уничтожит вашу таблицу пользователей и ничего не сделает с остальными, поскольку это комментарий.
Некоторые команды mysql в php будут выполнять несколько запросов при передаче sql, лучший способ избежать этого - параметризованные запросы.
Я использую PDO для доступа к БД и очень рекомендую его. У меня нет ссылок на макушку головы, но я помню учебники, которые я использовал в топе Google.
Это не только подвержено SQL-инъекциям, но и приведет к сбою в тех случаях, когда инъекция даже не предназначена:
Например, пользователю нужно имя "Гийом Франсуа Антуан, маркиз де Л'Госпиталь".Поскольку имя пользователя содержит цитату, и вы не экранируете ее, ваш запрос завершится ошибкой, хотя пользователь никогда не хотел взламывать систему!
Либо использовать PDO или сделайте это таким образом:
$query = sprintf(
"SELECT 1 FROM users WHERE name = '%s' AND password = '%s'",
mysql_real_escape_string($_POST['name']),
mysql_real_escape_string(md5($_POST['password']))
);
Верьте или нет, это безопасно ... если magic_quotes_gpc
включено. Которого никогда не будет в PHP6, поэтому исправление до этого является хорошей идеей.
$_POST['user'] = "' or 1=1; --";
Любой получает мгновенный доступ к вашему приложению
<Литий> <р> $_POST['user'] = "'; DROP TABLE user; --";
Поцелуй свой (платный?) Список пользователей на прощание
Если вы позже отобразите $ name в своем выводе, это может привести к атаке с внедрением XSS
: O никогда не делай этого, Это может вызвать атаку SQLInjection. Если, например, пользовательский ввод каким-либо образом: 'удалить пользователей из таблицы - в качестве ввода в $ username; этот код будет связан с вашим оригинальным кодом и отбросит вашу таблицу. Хакеры могут сделать больше и взломать ваш сайт.
Это обычно очень опасно. В некоторых случаях это может быть смягчено разрешениями базы данных.
Вы не проверяете ввод ($ name и $ pwd). Пользователь может отправить SQL в одном или обоих из этих полей. SQL может удалить или изменить другие данные в вашей базе данных.
Очень и очень опасно. Хорошей идеей для паролей является преобразование пароля в хеш-код MD5 и сохранение его в качестве «пароля» пользователя.
1) защищает пользователей от кражи их паролей
2) если пользователь пишет вредоносную строку, он может уничтожить вашу запись / таблицу / базу данных
Также вы должны выполнить некоторое базовое выражение регулярного выражения для имени, чтобы убедиться, что оно использует только символы A-Za-z0-9 и, возможно, несколько акцентированных символов (без специальных символов, *, < 's & в частности).
Когда пользовательские данные активируются в запросе SQL, всегда выполняйте санитарную обработку данных с помощью mysql_real_escape_string
. р>
Кроме того, вы должны хранить только соленый хеш пароля вместо самого пароля. Вы можете использовать следующую функцию для генерации и проверки соленого хэша со случайным значением соли:
function saltedHash($data, $hash=null)
{
if (is_null($hash)) {
$salt = substr(md5(uniqid(rand())), 0, 8);
} else {
$salt = substr($hash, 0, 8);
}
$h = $salt.md5($salt.$data);
if (!is_null($hash)) {
return $h === $hash;
}
return $h;
}
Все вместе:
$query = 'SELECT pwd FROM users WHERE name = "'.mysql_real_escape_string($_POST['user']).'"';
$res = mysql_query($query);
if (mysql_num_rows($res)) {
$row = mysql_fetch_assoc($res);
if (saltedHash($_POST["pwd"], $row['pwd'])) {
// authentic
} else {
// incorrect password
}
} else {
// incorrect username
}
Это небезопасно, вы можете посмотреть что-то вроде PDO. PHP PDO