Является ли использование функции MD5 уровня базы данных большей угрозой безопасности, чем функция уровня приложения? - PullRequest
2 голосов
/ 29 января 2010

У меня есть кусок кода, который проверяет имя пользователя и пароль пользователя, который выглядит примерно так:

$sql = "SELECT * 
FROM user 
WHERE 
    username='{$_POST['username']}' AND 
    password=MD5('{SALT}{$_POST['password']}')";

Является ли это более / менее безопасным, чем делать это так?

$sql = "SELECT * 
FROM user 
WHERE 
    username='{$_POST['username']}' AND 
    password='".md5(SALT.$_POST['password'])."'";

Независимо от того, где / если выполняется экранирование, является ли первый метод уязвимым для атак инъекций sql? Будет ли ответ такой же для других механизмов баз данных, кроме MySQL?

Ответы [ 5 ]

3 голосов
/ 29 января 2010

Вы должны использовать вместо подготовленных утверждений и взгляните на этот вопрос .

2 голосов
/ 29 января 2010

Говоря о внедрении, оба способа безопасны, если вы правильно экранируете переменные.

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

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

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

Надеюсь, это имеет смысл.

1 голос
/ 29 января 2010

Запуск с MD5 запрещает быть небезопасным алгоритмом и никогда не должен использоваться для паролей. Вы должны использовать устаревший sha256, и большинство баз данных не имеют этого вызова функции. Но даже если база данных, я думаю, это плохая идея. Не очень плохая идея, но лучше хранить как можно меньше копий пароля. Часто база данных может находиться на совершенно другом компьютере, и если этот компьютер был взломан, злоумышленник может получить пароли в виде открытого текста, посмотрев на запросы. С точки зрения SQL-инъекций, нет никакой разницы в безопасности, и, судя по вашим запросам, вы должны больше беспокоиться о SQL-инъекциях.

1 голос
/ 29 января 2010

О, боже, пожалуйста, скажите мне, что вы делаете какой-то тип mysql_escape_string или mysql_real_escape_string или, по крайней мере, addslashes или addcslashes для любых $_POST переменных до того, как вы вставите их в необработанный оператор MySQL?

Я думаю, что самый безопасный способ сделать это:

a) используйте filter_var или preg_replace, чтобы избавиться от посторонних символов из $ _POST ['username']

b) SELECT строка по имени пользователя из MySQL (также захватывает переваренный пароль)

в) сравните версию пароля, переваренного в сообщении от $_POST, с паролем извлеченной строки (при условии, что вы не оставляете открытый текст пароля) в коде своего приложения, а не в операторе SQL

Если вы делаете это таким образом, есть только 1 возможное место для инъекции (имя пользователя), и это довольно невозможно, когда вы делаете preg_replace( '/\W/', '', $_POST['username'] ), который удаляет все, что не A-Za-z0-9_- (или изменяется на ваш белый список символов имени пользователя).

Тем не менее, если вы проводите тщательную надлежащую санитарную обработку, на самом деле не имеет значения, где вы проводите сравнение. Тем не менее, теоретически я бы позволил наименьшее возможное взаимодействие с пользовательским вводом и необработанными операторами SQL (т. Е. Только SELECT по имени пользователя и сравнению за пределами вашей БД).

0 голосов
/ 29 января 2010

Независимо от того, где / если выполняется экранирование, является ли первый метод уязвимым для атак инъекций sql?

Внедрение SQL не произойдет, если произойдет надлежащее экранирование и очистка

Будет ли ответ тем же для других механизмов баз данных, кроме MySQL?

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

...