Сайтостроительство (8)

PHP-кодинг (25)

Веб-дизайн (9)

DHTML/JavaScript (8)

Подкастинг (1)

Безопасность в PHP (3)

Секретный раздел

Карта блога

Регистрация пользователей на PHP+MySQL

Скрипт гостевой книги с красивым дизайном

Галерея на jQuery

Простая система регистрации пользователей на сессиях

Форма обратной связи с защитой типа капча

Галерея на php+jquery

Шаблоны запросов и placeholders

Быстрое перенаправление средствами php

Flash плеер для вашего сайта

Сортировка столбцов в таблице на php+mysql

Форматный вывод даты из базы

Передача переменных из JavaScript в РНР

Добавляем списки выбора в форму регистрации

Языки HTML и PHP (+ скачать учебники)

Создание документа при помощи JavaScript

За весь период

За 2010-11

За 2009-06

За 2009-05

За 2009-04

За 2009-03

За 2009-02

За 2008-08

Бегун контекстная реклама

Ruseller видеоуроки

Letitbit файлообменник

Tak.Ru $$$ вебмастеру

WMmail почтовые рассылки

WMlink продажа трафика

Sape.Ru продажа ссылок

Главная » Безопасность в PHP

MySQL и проблемы безопасности

Запросы, отправляемые серверу MySQL, представляют собой обыкновенные строки PHP. До сих пор мы писали команды вроде:


mysql_query("INSERT INTO table SET username='$username'");

и не задумывались о том, что в $username, вообще говоря, может храниться строка, содержащая апострофы. Давайте рассмотрим, какой запрос придет серверу MySQL, если $username равно "cat's":


INSERT INTO table SET username='cat's'

Отсюда видно, что данная команда синтаксически некорректна и породит ошибку во время выполнения.

Суть проблемы:
Кстати, может быть и хуже. Давайте рассмотрим такой запрос:


mysql_query("DELETE FROM table WHERE username='$username'");

Представьте, что параметр $username приходит из формы, и злоумышленник указал в нем следующую строку: "!' OR 1=1 OR '!". После подстановки получится такой запрос к базе данных:


DELETE FROM table WHERE username='!' OR 1=1 OR '!'

Видно, что он удаляет все записи из таблицы table, потому что выражение SQl 1=1 всегда истинно!

Экранирование символов.
Итак, прежде чем передавать значения переменных формы в SQL-запросы, необходимо специальным образом экранировать в них некоторые символы (в частности, апостроф) - поставить перед ними обратный слэш. Для вставки предназначена функция mysql_escape_string().

string mysql_escape_string(string $str)

Функция похожа на addslashes(), однако она добавляет слэши перед более полным набором специальных символов. По стандарту MySQL экранированию подвергаются символы, которые в PHP запишутся так: "\x00", "\n", "\r", "\\", "'" и "\x1A".

Воспринимайте экранирование символов лишь как способ записи корректных SQL-выражений, не более того. С данными "на самом деле" ничего не происходит, и они хранятся в базе без дополнительных слэшей - так, как выглядели изначально, еще до экранирования.

Итак, с использование mysql_escape_string() наш код может выглядеть так:


mysql_query("DELETE FROM table WHERE username='".mysql_escape_string($username)."'");

Иногда достаточно (если переменная не содержит апострофов) экранировать переменную просто как:
username='".username."'.
В качестве альтернативы вместо "кавычки с точкой" можно использовать фигурную скобку таким образом:
username='{$username}'

PS: Между тем, хорошее решение известно давно и применяется, например, в функции sprintf() языка C. Идея заключается в том, что вместо явного экранирования и вставки переменных в запрос на их место помещаются специальные маркеры, обычно выглядящие как ?. Те же значения, которые будут подставлены вместо них, передаются отдельно, дополнительными параметры. Однако в этой заметке я небуду вдаваться в подробности и рассказывать реализацию данных запросов. Ждите данную заметку в новом разделе Безопасность в PHP

А пока можете проверить все свои запросы в скриптах и переделать их вышесказанным способом, защитив не только свои скрипты, но и сайт в целом от потенциальных опасностей.

Бонус: Для ясности что к чему, покажу вам несколько запросов, которые нужно подправить в файле обработчика вывода комментариев, чтобы избежать ошибку во время выполнения запроса.


// занесение комментария зарегистрированного пользователя
$result2 = mysql_query ("INSERT INTO comments(post,author,text,date,time,ip) VALUES ('".$id."','".$_SESSION['username']."','".mysql_escape_string($text)."','".$date."','".$time."','".$_POST['ip']."')",$db);
// занесение комментария незарегистрированного пользователя
$result2 = mysql_query ("INSERT INTO comments (post,author,site,mail,text,date,time,ip) VALUES ('".$id."','Гость_".mysql_escape_string($author)."','".$_POST['site']."','".$_POST['mail']."','".mysql_escape_string($text)."','".$date."','".$time."','".$_POST['ip']."')",$db);
// запрос информ. о пользователе
$ava = mysql_query("SELECT site,city,sex,avatar,DATE_FORMAT(date,'%d.%m.%Y') AS date FROM users WHERE username='".mysql_escape_string($myrow3['author'])."'",$db);
// вывод комментариев
$mess = mysql_query("SELECT COUNT(id) FROM comments WHERE author='".mysql_escape_string($myrow3['author'])."'",$db);

Аналогичные запросы исправляем и в файле member.php


// выборка существующих юзеров для проверки совпадения имен
$result = mysql_query("SELECT * FROM users WHERE username='".mysql_escape_string($username)."'", $db);
// занесение информации зарегистрированного пользователя
$query = "INSERT INTO users (username,password,email,icq,site,city,birth,sex,avatar,date,ip)"."VALUES ('".mysql_escape_string($username)."','".$mdPassword."','".$emaila."','".$icq."','".$site."','".$city."','".$birth."','".$sex."','".$file_name."','".$date."','".$ip."')";

Вы видите, что в условии запроса значение поля "author" и "text" во всех случаях обрабатывается функцией mysql_escape_string(). Теперь, если пользователь или гость_сайта напишет в своем имени или в тексте сообщения апострофы, то запрос пройдет успешно, без ошибок и его комментарий успешно выведиться в комментариях.

Комментировать

Автор: admin | Добавлена: 11.05.2009 | Просмотров: 11836
Рейтинг: 47 | Голосов: 10

Оцените заметку: 1 2 3 4 5

Последние обновления в категории: Безопасность в PHP

Комментарии (0)

Комментариев пока нет!

Только авторизованные пользователи могут добавлять комментарии. Зарегистрироваться.

Логин:
Пароль:
 

Регистрация

: Тема:

Заметок в базе: 56
Комментариев: 0
Всего юзеров: 114
Сейчас онлайн: 1