|
Страница 1 из 4 Небрежность и невнимательность, вот две причины написания кода, уязвимого для SQL инъекций. Третья причина - незнание, должна бы побуждать программиста к углублению своих знаний или даже изменения профессии. SQL инъекция (SQL injection) - уязвимость которая возникает при недостаточной проверке и обработке данных, которые передаются от пользователя, и позволяет модифицировать и выполнять непредвиденные кодом программы SQL запросы. Инъекция SQL является широко распространенным дефектом безопасности в Internet, что легко используется без специальных программ и не требует глубоких технических знаний. Использование этой уязвимости дает путь к большим возможностям: как то кража, подмена или уничтожение данных, отказ в обслуживании, и т.д. В этой статье я попробую объяснить основные риски, которые возникают при взаимодействии междуPHP и базой данных MySQL.
Для наглядности приведу пример простой структуры базы данных, которая является типичной для большинства проектов: CREATE DATABASE `news`; USE `news`; # # таблица новостей # CREATE TABLE `news` ( `id` int(11) NOT NULL auto_increment, `title` varchar(50) default NULL, `date` datetime default NULL, `text` text, PRIMARY KEY (`id`) ) TYPE=MyISAM; # #добавляем некоторые данные # INSERT INTO `news` (`id`,`title`,`date`,`text`) VALUES (1,'first news','2005-06-25 16:50:20','news text'); INSERT INTO `news` (`id`,`title`,`date`,`text`) VALUES (2,'second news','2005-06-24 12:12:33','test news'); # # таблица пользователей # CREATE TABLE `users` ( `id` int(11) NOT NULL auto_increment, `login` varchar(50) default NULL, `password` varchar(50) default NULL, `admin` int(1) NULL DEFAULT '0', PRIMARY KEY (`id`) ) TYPE=MyISAM; # # добавляем несколько пользователей, одного с правами админа, другого простого # INSERT INTO `users` (`id`,`login`,`password`,`admin`) VALUES (1,'admin','qwerty',1); INSERT INTO `users` (`id`,`login`,`password`,`admin`) VALUES (2,'user','1111',0); А теперь образец PHP кода: $link=mysql_connect("localhost","user","password"); mysql_select_db("sqltest",$link); if (!empty($_GET["id"])) { $query="SELECT * FROM `news` WHERE `id`=".$_GET["id"]; $res=mysql_query($query,$link) or die(mysql_error($link)); } ?> Видим, что запрос формируется в зависимости от значения $_GET["id"]. Для проверки наличия уязвимости достаточно изменить его на значение, которое может вызвать ошибку в выполнении SQL запроса. Конечно, вывода ошибок может и не быть, но это не означает, что ошибки нет. http://test.com/index.php?id=1 как результат "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1" или http://test.com/index.php?id=1qwerty результат "Unknown column '1qwerty' in 'where clause'" запрос http://test.com/index.php?id=2-1 при наличии уязвимости должен выдать результат, аналогичный http://test.com/index.php?id=1 Подобные уязвимости позволяют модифицировать запрос в части параметра WHERE. Первое, что сделает злоумышленник при обнаружении такой уязвимости - исследует, какое количество полей используется в запросе. Для этого задается заведомо неверный id, чтобы исключить вывод реальной информации и объединяется с запросом с одинаковым количеством пустых полей. http://test.com/index.php?id=-1+UNION+SELECT+null,null,null,null количество "null" должно соответствовать количеству полей, которые используются в запросе. Если запрос выдает ошибку, добавляется еще одно пустое значение, до тех пор пока не исчезнет ошибка и не будет получен результат с пустыми данными. Далее объединенные поля заменяются на значения, которые можно визуально наблюдать на странице.
|