В порядке,
Итак, я немного не уверен в этом.
У меня есть имя пользователя параметра url.
и у меня есть это утверждение
SELECT * FROM users WHERE user_hash = md5($_GET['username'])
Это безопасно?
При создании учетной записи сохраняется хешированная версия имени пользователя и пароль.
Я запутался, поскольку это кажется таким простым, если md5 останавливает SQL-инъекцию, почему не имя пользователя и пароль всегда сохраняются в хэш-форме?
Да, это позволит избежать SQL-инъекции, потому что md5()
всегда возвращает строку шестнадцатеричного кода.
Но это не общее решение SQL-инъекции. Вам нужно будет кодировать почти все данные в ваших таблицах в формате MD5. Например,
$sql = "UPDATE users SET fullname = '" . md5($_GET['fullname']) . "' WHERE id = '" . md5($_GET['id']) . "'";
Но MD5 является односторонним хешем, поэтому не было бы способа отображения полного имени, которое было сохранено таким образом.
Короткий ответ – нет, MD5 не предотвращает SQL-инъекцию. Правильное кодирование – лучший способ справиться с этим.
Причина в этом случае заключается в том, что ваш параметр строки запроса позволяет получить прямой доступ к sql. Например, что, если пользователь отправит вам:
?username=%27a%27);DROP%20TABLE%20users;%20--
Это подделывает функцию MD5 и отбрасывает таблицу пользователей. Конечно, они должны знать что-то о вашей базе данных, чтобы это сделать. Правильный способ справиться с этим был бы MD5 значением до того, как он войдет в SQL. В PHP это будет примерно так:
$username = $GET['username']; $hashed_username = md5($username); $sql = "SELECT * FROM users WHERE user_hash = '$hashed_username'"
Или лучшим решением будет использование связанных переменных в запросах, где вы позволяете библиотекам SQL обрабатывать перевод. Если вы используете PHP, загляните в PDO bindParam, http://php.net/manual/en/pdostatement.bindparam.php
BTW, ваш SQL не будет работать, потому что вам нужно будет указать (') переменную get в SQL.
Я запутался, поскольку это кажется таким простым, если md5 останавливает SQL-инъекцию, почему не имя пользователя и пароль всегда сохраняются в хэш-форме?
Причина в том, что простые операции, такие как поиск пользователя с определенным именем, были бы невозможны.
SELECT * FROM users where user LIKE '%cat%'
Вы найдете всех пользователей со словом cat внутри него.
Также простое администрирование было бы невозможным, вы даже не можете просмотреть список всех пользователей.