Должен ли я mysql_real_escape_string все файлы cookie, которые я получаю от пользователя, чтобы избежать внедрения MySQL в php?

StackOverflow https://stackoverflow.com/questions/90517

  •  01-07-2019
  •  | 
  •  

Вопрос

Когда пользователь заходит на мой сайт, мой скрипт проверяет наличие двух файлов cookie, в которых хранится идентификатор пользователя + часть пароля, чтобы автоматически войти в систему.

Содержимое файлов cookie можно редактировать с помощью редактора файлов cookie, так что, полагаю, можно добавить вредоносный контент в записанный файл cookie?

Должен ли я добавить mysql_real_escape_string (или что-то еще) для всех моих вызовов файлов cookie, или есть какая-то встроенная процедура, которая не позволит этому произойти?

Это было полезно?

Решение

Что ты Действительно что нужно сделать, это не отправлять эти значения файлов cookie, которые можно взломать.Вместо этого, почему бы не хешировать имя пользователя и пароль, а также (секретную) соль и установить это как значение файла cookie?то есть:

define('COOKIE_SALT', 'secretblahblahlkdsfklj');
$cookie_value = sha1($username.$password.COOKIE_SALT);

Тогда вы знаете, что значение файла cookie всегда будет представлять собой 40-значную шестнадцатеричную строку и сможете сравнить значение, которое пользователь отправляет обратно, с тем, что находится в базе данных, чтобы решить, действительны они или нет:

if ($user_cookie_value == sha1($username_from_db.$password_drom_db.COOKIE_SALT)) {
  # valid
} else {
  #not valid
}

mysql_real_escape_string кстати, делает дополнительный удар по базе данных (многие люди не осознают, что для этого требуется соединение с БД и запросы к MySQL).

Лучший способ сделать то, что вы хотите, если вы не можете изменить свое приложение и настаиваете на использовании взломанных значений файлов cookie, — это использовать подготовленные операторы со связанными параметрами.

Другие советы

Смысл mysql_real_escape_string заключается не в защите от атак путем внедрения, а в обеспечении точного хранения ваших данных в базе данных.Таким образом, его следует вызывать для ЛЮБОЙ строки, поступающей в базу данных, независимо от ее источника.

Однако вам следует также используйте параметризованные запросы (через mysqli или PDO), чтобы защитить себя от SQL-инъекций.В противном случае вы рискуете закончить как школа маленького Бобби Тейблса.

Я использую mysql_real_escape_string только перед вставкой переменных в оператор SQL.Вы просто запутаетесь, если некоторые из ваших переменных будут уже сбежал, а затем снова убегаешь от них.Это классическая ошибка, которую вы видите в веб-приложениях блогов для новичков:

Когда кто-то пишет апостроф, он продолжает добавлять косые черты, портя страницы блога.

Значение переменной само по себе не опасно:только когда вы надеваете его на веревку или что-то подобное, вы начинаете забредать в опасные воды.

Конечно, никогда не доверяйте ничему, что исходит от клиента.

Подготовленные операторы и привязка параметров — это всегда хороший способ.

PEAR::MDB2 поддерживает подготовленные операторы, например:

$db = MDB2::factory( $dsn );

$types = array( 'integer', 'text' );
$sth = $db->prepare( "INSERT INTO table (ID,Text) (?,?)", $types );
if( PEAR::isError( $sth ) ) die( $sth->getMessage() );

$data = array( 5, 'some text' );
$result = $sth->execute( $data );
$sth->free();
if( PEAR::isError( $result ) ) die( $result->getMessage() );

Это позволит попасть в базу данных только нужным данным и заранее установленному количеству переменных.

Прежде чем зайти так далеко, вам, конечно, следует проверить данные, но подготовка утверждений — это последняя проверка, которую следует выполнить.

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

Я согласен с вами.Можно изменить файлы cookie и отправить вредоносные данные.

Я считаю, что хорошей практикой является фильтрация значений, которые вы получаете от файлов cookie, прежде чем использовать их.Как правило, я фильтрую любые другие входные данные, которые могут быть подделаны.

Егор, вы можете сохранять хэш при создании/обновлении учетной записи пользователя, а затем при каждом запуске входа в систему вы хэшируете данные, отправленные на сервер, и сравниваете их с тем, что было сохранено в базе данных для этого имени пользователя.

(С самого начала в свободном php - рассматривайте как псевдокод):

$usernameFromPostDbsafe = LimitToAlphaNumUnderscore($usernameFromPost);
$result = Query("SELECT hash FROM userTable WHERE username='$usernameFromPostDbsafe' LIMIT 1;");
$hashFromDb = $result['hash'];
if( (sha1($usernameFromPost.$passwordFromPost.SALT)) == $hashFromDb ){
    //Auth Success
}else{
   //Auth Failure
}

После успешной аутентификации вы можете сохранить хеш в $_SESSION или в таблице базы данных кэшированных аутентифицированных имен пользователей/хэшей.Затем отправьте хэш обратно в браузер (например, в файле cookie), чтобы последующие загрузки страниц отправили хэш обратно на сервер для сравнения с хешем, хранящимся в выбранном вами хранилище сеанса.

mysql_real_escape_string настолько устарел...В наши дни вам действительно следует использовать привязку параметров.

Я уточню, упомянув, что я имел в виду подготовленные заявления и предоставьте ссылку на статью, демонстрирующую, что иногда mysl_real_escape_string недостаточно: http://www.webappsec.org/projects/articles/091007.txt

Я бы рекомендовал использовать htmlentities($input, ENT_QUOTES) вместо mysql_real_escape_string, поскольку это также предотвратит любой случайный вывод фактического HTML-кода.Конечно, вы могли бы использовать mysql_real_escape_string и htmlentities, но зачем?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top