2011-01-20 5 views
6

Я разрабатываю веб-сайт, и я пытаюсь защитить соединение.Защита от SQL-инъекции

Я использовал функцию addslashes на $login, чтобы остановить SQL-инъекцию, но некоторые друзья сказали мне, что недостаточно защиты. Однако они не показали мне, как использовать эту уязвимость.

Как я могу/нарушить этот код? Как я могу его защитить?

<?php 

    if (isset($_POST) && (!empty($_POST['login'])) && (!empty($_POST['password']))) 
    { 
     extract($_POST); 
     $sql = "SELECT pseudo, sex, city, pwd FROM auth WHERE pseudo = '".addslashes($login)."'"; 
     $req = mysql_query($sql) or die('Erreur SQL'); 
     if (mysql_num_rows($req) > 0) 
     { 
      $data = mysql_fetch_assoc($req); 
      if ($password == $data['pwd']) 
      { 
       $loginOK = true; 
      } 
     } 
    } 
    ?> 
+2

google addslashes VS mysql_real_escape_string: http://www.sitepoint.com/forums/showthread.php?t=337881 –

+0

Есть много устаревших учебных пособий, которые предлагают 'addslashes()' как механизм для удаления вещей в SQL-запросы. Если вы учитесь на одном из них, я предлагаю вам попробовать найти что-то более актуальное и точное. Кроме того, 'extract ($ _ POST)' является хорошим примером уязвимости; не делай этого! BTW, добро пожаловать в StackOverflow. –

+0

почти точный дубликат http://stackoverflow.com/questions/60174/best-way-to-stop-sql-injection-in-php – Puddingfox

ответ

14

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

На ссылочной странице PHP приведен пример внедрения sql в форме входа.

Лучшим решением было бы использовать подготовленные заявления, вы можете сделать это, используя PDO или mysqli.

+0

нормально, но не могли бы вы привести пример SQL-инъекции для этого кода? Я не понимаю, как я могу сломать этот код, тогда как я избегаю кавычек в нем. –

+0

@Tom: check [Эта статья на эту тему] (http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string) – ircmaxell

+0

Комментарий для этого downvote был бы приятным. – alexn

2

Использование:

mysql_real_escape_string($inputToClean); 
+0

Эта функция, которая вызывается сама по себе, может ничего не делать, кроме добавок. –

+1

@Col. Шрапнель: это эпсилон лучше, чем 'addlashes' (представления Unicode и еще много чего), но вы правы, что программист, использующий его как абракадабра-это-сейчас-защищенная магическая пыль, не безопаснее, чем с добавками. – Piskvor

2

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

Что произойдет, если я опубликую это?

$_POST { 
    'login' => 'Admin', 
    'loginOK' => 1 
} 

Угадайте, что, $ loginOK теперь == 1, и я войду в систему как администратор.

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

+0

Спасибо, чувак, вы нашли еще одну ошибку. Я этого не видел. =) –

+0

@ Tom-pouce: Добро пожаловать. Кстати, это ** eeexactly ** случай против 'extract' - он создает переменные« из воздуха »(я был укушен этим, и его действительно сложно отладить). – Piskvor

2

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

  • isset($_POST) всегда TRUE, если вы запустите его из командной строки. Вероятно, вы можете удалить его.
  • empty() очень сложно. Например, если $password = '0', то empty($password) - ИСТИНА.
  • Вы можете сделать это: if(isset($_POST['login']) && $_POST['login']!=''){}
  • extract($_POST) - огромная уязвимость: каждый может установить переменные в свой код извне.
  • $password == $data['pwd'] предполагает, что вы храните пароли открытого текста в своей базе данных. Это ужасная практика. Google для «соленого пароля».
  • Вы также можете сделать $loginOK = $password == $data['pwd'];. Вы понимаете, почему? ;-)
5

Вы храните свои пароли в открытом виде! Это серьезная проблема безопасности, если я когда-либо видел ее. Что делать с этим: по крайней мере, использовать (для каждого пользователя) соленый хэш пароля, как видно, например,here.

+0

(не стесняйтесь редактировать лучшее объяснение хэширования и соления, это тот, который я нашел, быстро поиская SO) – Piskvor

Смежные вопросы