скрипт аутентификации php - PullRequest
       13

скрипт аутентификации php

0 голосов
/ 09 сентября 2009

Мне нужен следующий скрипт аутентификации. Я слаб в php / pdo, поэтому я не знаю, как запросить количество строк, равное единице, а затем установить идентификаторы сеанса из результатов запроса. Мне нужно не только установить $ _SESSION ['userid'], но также ['company'] и ['security_id'], а также результаты.

вот что у меня есть:

$userid   = $_POST['userid'];
$password = $_POST['pass'];
if ( $userid != "" || $password != "" )
{
  $sql = "SELECT * FROM contractors WHERE userid = '" . $userid . "' AND password = '" . $password . "'";
  $result = $dbh->query( $sql );
} else
{
  echo "login failed. Your fingers are too big";
}

Дополнительная информация: Браузер: Firefox

Ответы [ 2 ]

4 голосов
/ 10 сентября 2009

НИКОГДА НЕ ИСПОЛЬЗУЙТЕ ЭТОТ КОД!

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

user'; UPDATE contractors SET password = '1337'

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

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

Насколько я знаю, вам нужно использовать функцию PDO quote для правильной очистки строки. (В mysql это будет сделано с mysql_real_escape_string().) Я не эксперт по PDO, заметьте, кто-нибудь, пожалуйста, исправьте, если я ошибаюсь.

Кроме того, вам, вероятно, не следует хранить какие-либо пароли непосредственно в базе данных, а использовать хеш-функцию для создания маскированного пароля, а также создавать хеш из предоставленного пользователем пароля и сопоставлять хеш-коды. Для этого вы можете использовать функцию PHP hash.

Что касается других вопросов, я не знаю, является ли подход, который вы используете в SQL SELECT, лучшим подходом. Я бы просто выбрал соответствующий пароль пользователя и попытался сопоставить его с программой. Я не думаю, что есть какой-то сбой в методе, который вы используете, но он просто не выглядит таким логичным, и, таким образом, есть большая вероятность, что me пропустит какую-то ошибку - что в случае паролей и логины создадут окно для эксплойтов.

Чтобы сделать это по-своему, вы должны заметить, что результат, который вы получаете от PDO query, равен PDOStatement, что похоже, нет надежной функции для прямого подсчета количества строк результата. Вам нужно использовать fetchAll, который возвращает массив строк и считает это. Однако, как я уже сказал, мне все кажется, что он открыт для сбоев, поэтому я чувствовал бы себя безопаснее, проверяя пароль в коде. На мой вкус, слишком большое расстояние от фактического сопоставления паролей, на мой вкус.

Таким образом, чтобы получить полученный пароль для идентификатора пользователя, вы можете использовать PDOStatement fetch(), который возвращает содержимое столбца из результата. Используйте, например, PDO::FETCH_ASSOC, чтобы получить их в ассоциативном массиве на основе имен столбцов.

Вот как это исправить:

$userid_dirty   = $_POST['userid'];
$password_dirty = $_POST['pass'];
$success = false; // This is to make it more clear what the result is at the end
if ($userid != "" || $password != "") {
  $userid = $dbh->quote($userid_dirty);
  $passwordhash = hash('sha256',$password_dirty);
  $sql = "SELECT userid, passwordhash, company, security_id FROM contractors WHERE userid = ".$userid;
  $result = $dbh->query( $sql );
  if ($result) { // Check if result not empty, that userid exists
    $result_array = $result->fetch(PDO::FETCH_ASSOC);
    if ($result_array['PASSWORDHASH'] == $passwordhash) {
       // login success
       $success = true;

       // do all the login stuff here...
       // such as saving $result_array['USERID'], $result_array['COMPANY'], $result_array['SECURITY_ID'] etc. 

    } // else fail, wrong password
  } // else fail, no such user
} else {
  // fail, userid or password missing
  echo ' please enter user id and password.';
}
if (!$success) {
  echo ' login failed.';
}

Конечно, код можно немного почистить, но это должно объяснить, что нужно сделать. Обратите внимание, что поскольку пароль хешируется и никогда не используется в SQL , он фактически не нуждается в очистке. Но я оставил его там на всякий случай, поскольку в исходном коде было использовано в запросе.

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

Кроме того, я предоставил код просто для образовательных целей - я просто подумал, что код - это самый простой способ объяснить, как это сделать. Так что не путайте этот сайт с сервисом запроса кода. :)

2 голосов
/ 10 сентября 2009

Руководство php является отличным ресурсом для изучения PHP. Похоже, вы немного знаете SQL и слышали о PDO, который является хорошим началом. Если вы поищите в Google «PDO» или поищите термин в руководстве по PHP, вы найдете раздел PDO руководства. Похоже, вы нашли функцию ->query, так что теперь вам нужно посмотреть, что это возвращает. Переходя к справочнику этой функции , мы видим, что она возвращает PDOStatement объект. Слово PDOStatement полезно связано с соответствующей страницей в руководстве, где перечислены методы, доступные для этого объекта. Существует метод rowCount(), который, вероятно, будет делать то, что вы хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...