<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>PublicWeb.ru &#187; MySQL</title>
	<atom:link href="http://publicweb.ru/category/mysql/feed" rel="self" type="application/rss+xml" />
	<link>http://publicweb.ru</link>
	<description>Слегка айтишный взгляд на различные жизненные аспекты</description>
	<lastBuildDate>Fri, 09 Jul 2010 20:18:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>SQL injection. Объясняем на пальцах</title>
		<link>http://publicweb.ru/2008/06/25/221</link>
		<comments>http://publicweb.ru/2008/06/25/221#comments</comments>
		<pubDate>Wed, 25 Jun 2008 13:31:53 +0000</pubDate>
		<dc:creator>Milax</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[injection]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[взлом]]></category>

		<guid isPermaLink="false">http://publicweb.ru/2008/06/25/221</guid>
		<description><![CDATA[В этом посте немножко коснусь темы безопасности сайтов. Думаю, каждый, кто интересовался темой хака инет-ресурсов, слышал о таком понятии, как SQL-инъекции. Фактически любой сайт, разработчики которого не уделяют должного внимания вопросу безопасного программирования, может быть легко &#8220;взломан&#8221; этим видом атаки. Чтобы понять, что и к чему в этом посте, необходимо обладать техническим минимумом, в частности, [...]]]></description>
			<content:encoded><![CDATA[<p>В этом посте немножко коснусь темы безопасности сайтов. Думаю, каждый, кто интересовался темой хака инет-ресурсов, слышал о таком понятии, как SQL-инъекции. Фактически любой сайт, разработчики которого не уделяют должного внимания вопросу безопасного программирования, может быть легко &#8220;взломан&#8221; этим видом атаки. Чтобы понять, что и к чему в этом посте, необходимо обладать техническим минимумом, в частности, иметь представление о том, что такое PHP и MySQL.</p>
<p>Итак, что же из себя представляют эти &#8220;инъекции&#8221;, да еще и SQL? </p>
<h4>0. Сначала было слово</h4>
<p>SQL injection — одна из самых опасных уязвимостей вэб-приложений. Позволяет злоумышленнику выполнять запросы в БД сайта, а в некоторых случаях писать/читать файловую систему с правами сервера баз данных. Уязвимость возникает в большинстве случаев из-за недостаточной фильтрации данных при построении запроса.</p>
<h4>1. Немного теории</h4>
<p>Любой запрос SQL состоит из нескольких предложений.</p>
<div class="codecolorer-container mysql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="mysql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #990099; font-weight: bold;">SELECT</span> <span style="color: #CC0099;">*</span> <br />
<span style="color: #990099; font-weight: bold;">FROM</span> base_user</div></div>
<p>Это пример самого простого запроса, который состоит из двух предложений: предложение SELECT и предложение FROM. Для выбора по условию к запросу добавляется предложение WHERE. В нем обычно и скрываются неприятности.</p>
<div class="codecolorer-container mysql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="mysql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #990099; font-weight: bold;">SELECT</span> <span style="color: #CC0099;">*</span> <br />
<span style="color: #990099; font-weight: bold;">FROM</span> base_user <br />
<span style="color: #990099; font-weight: bold;">WHERE</span> id<span style="color: #CC0099;">=</span><span style="color: #008080;">1</span></div></div>
<p>В MySQL литеральные строки заключаются в двойные или одинарные кавычки. Комментарии пишутся после <font color="blue">&#8211;</font> или <font color="blue">/*</font>. Первый вид комментария — комментарий до конца строки, второй — до символов <font color="blue">*/</font>, по аналогии с С++ или до конца многострочного запроса.</p>
<p>Также стоит упомянуть про объединение результатов запроса с использованием оператора UNION.</p>
<div class="codecolorer-container mysql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="mysql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #990099; font-weight: bold;">SELECT</span> name <br />
<span style="color: #990099; font-weight: bold;">FROM</span> A <br />
<span style="color: #990099; font-weight: bold;">WHERE</span> id<span style="color: #CC0099;">=</span><span style="color: #008080;">1</span> <br />
<span style="color: #990099; font-weight: bold;">UNION</span> <br />
<span style="color: #990099; font-weight: bold;">SELECT</span> name <br />
<span style="color: #990099; font-weight: bold;">FROM</span> B <br />
<span style="color: #990099; font-weight: bold;">WHERE</span> id<span style="color: #CC0099;">=</span><span style="color: #008080;">2</span></div></div>
<p>Оператор UNION эквивалентен теоретико-множественному оператору объединения множеств. Работает только с запросами на выборку, необходимо одинаковое количество выбираемых полей в предложении SELECT для обоих объединяемых запросов.</p>
<p>Начиная с 5-й версии, MySQL поддерживает написание подзапросов, которые заключаются в круглые скобки ().</p>
<h4>2. От слов к примерам</h4>
<p>
<strong>Целые числа</strong></p>
<div class="codecolorer-container mysql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="mysql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$id <span style="color: #CC0099;">=</span> $_GET<span style="color: #FF00FF;">&#91;</span><span style="color: #008000;">'id'</span><span style="color: #FF00FF;">&#93;</span><span style="color: #000033;">;</span> <br />
mysql_query<span style="color: #FF00FF;">&#40;</span><span style="color: #008000;">&quot;SELECT * FROM base<span style="color: #008080; font-weight: bold;">_</span>user WHERE id=&quot;</span> . $id<span style="color: #FF00FF;">&#41;</span><span style="color: #000033;">;</span></div></div>
<p>Данный пример собирает запрос, подобное можно встретить во множестве сайтов. Как видно, в запрос просто подставляется значение ячейки суперглобального массива $_GET.</p>
<p>Что можно сделать? Мы видим, что переменная id никак не фильтруется, тоесть в GET-запрос мы можем вписать все что угодно. </p>
<p>Сначала узнаем количество полей возвращаемых запросом, для этого начинаем угадывать количество столбцов.</p>
<div class="codecolorer-container html4strict default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">http://test.com/test.php?id=1+UNION+SELECT+1+/* <br />
http://test.com/test.php?id=1+UNION+SELECT+1,2+/* <br />
http://test.com/test.php?id=1+UNION+SELECT+1,2,3+/*</div></div>
<p>и т.д., при несовпадении количества столбцов сервер будет отвечать ошибкой MySQL. Стоит заметить, в запросах используется <font color="blue">/*</font> для комментирования оставшегося запроса, мало ли что там девелопер еще написал&#8230; </p>
<p>После определения количества столбцов можно узнать, например, версию сервера. Cоставляем запрос вида:</p>
<div class="codecolorer-container html4strict default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">http://test.com/test.php?id=1+UNION+SELECT+VERSION()+/*</div></div>
<p>Дальше, покопавшись в документации MySQL, можно набрести на системные таблицы INFORMATION_SCHEMA и на БД mysql. Если сервер настроен плохо, то можно надеятся на права чтения этих таблиц и баз данных. Для выполнения запроса к другой базе данных достаточно поставить ее имя перед именем таблицы и поставить &#8220;.&#8221;(точка) между именем БД и таблицей. Пример:</p>
<div class="codecolorer-container mysql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="mysql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">mysql.<span style="color: #000099;">user</span></div></div>
<p>Имея доступ к INFORMATION_SCHEMA, злоумышленник легко узнает количество, имена и структуры всех таблиц БД. </p>
<p>Продолжим о вкусностях. Сервер MySQL имеет очень удобное предложение запроса на выборку INTO OUTFILE.</p>
<div class="codecolorer-container html4strict default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">http://test.com/test.php?id=1+UNION+SELECT+1+INTO+OUTFILE+'/tmp/1.txt'</div></div>
<p>Запрос такого вида позволит записать результат запроса в файл. Хоть эта возможность встречается не так часто, но с ее помощью на сервер можно загружать любые файлы. </p>
<p>Приступим к чтению файловой системы.</p>
<div class="codecolorer-container mysql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="mysql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #990099; font-weight: bold;">LOAD</span> <span style="color: #990099; font-weight: bold;">DATA</span> <span style="color: #990099; font-weight: bold;">INFILE</span> <span style="color: #008000;">'/tmp/test.txt'</span> <span style="color: #990099; font-weight: bold;">INTO</span> <span style="color: #990099; font-weight: bold;">TABLE</span> test</div></div>
<p>Запрос загружает содержимое фала в таблицу базы данных. С этим типом запросов возникают некоторые трудности при его инъекции в другие запросы, но в этом случае можно извратиться построением подзапросов.</p>
<p><strong>Литералы</strong></p>
<div class="codecolorer-container mysql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="mysql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$name <span style="color: #CC0099;">=</span> $_GET<span style="color: #FF00FF;">&#91;</span><span style="color: #008000;">'name'</span><span style="color: #FF00FF;">&#93;</span><span style="color: #000033;">;</span> <br />
mysql_query<span style="color: #FF00FF;">&#40;</span><span style="color: #008000;">&quot;SELECT * FROM base<span style="color: #008080; font-weight: bold;">_</span>user WHERE name='&quot;</span> . &nbsp;$name &nbsp;. <span style="color: #008000;">&quot;'&quot;</span><span style="color: #FF00FF;">&#41;</span><span style="color: #000033;">;</span></div></div>
<p>Этот код безопаснее предыдущего, но только в том случае, если в настройках PHP включены magic_quotes. При включении magic_quotes во всем вводе экранируются кавычки. Если же &#8220;волшебные кавычки&#8221; отключены, то запрос строится по принципу как и с целочисленными данными, только закрывается открытая кавычка</p>
<div class="codecolorer-container html4strict default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">http://test.com/test.php?name=TEST'+UNION+SELECT+1,2,3+/*</div></div>
<p>В итоге, вместо</p>
<div class="codecolorer-container mysql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="mysql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #990099; font-weight: bold;">SELECT</span> <span style="color: #CC0099;">*</span> <span style="color: #990099; font-weight: bold;">FROM</span> base_user <span style="color: #990099; font-weight: bold;">WHERE</span> name<span style="color: #CC0099;">=</span><span style="color: #008000;">'TEST'</span></div></div>
<p>получаем</p>
<div class="codecolorer-container mysql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="mysql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #990099; font-weight: bold;">SELECT</span> <span style="color: #CC0099;">*</span> <span style="color: #990099; font-weight: bold;">FROM</span> base_user <span style="color: #990099; font-weight: bold;">WHERE</span> name<span style="color: #CC0099;">=</span><span style="color: #008000;">'TEST'</span> <span style="color: #990099; font-weight: bold;">UNION</span> <span style="color: #990099; font-weight: bold;">SELECT</span> <span style="color: #008080;">1</span><span style="color: #000033;">,</span><span style="color: #008080;">2</span><span style="color: #000033;">,</span><span style="color: #008080;">3</span><span style="color: #808000; font-style: italic;">/*</span></div></div>
<p></p>
<h4>3. Как защититься</h4>
<p>Существуют разные способы защиты от инъекции, но в основе каждого лежит правильная и хорошая фильтрация пользовательского ввода. Данные к вэб-приложении поступают из массивов GET, POST и из COOKIE. Любой из массивов может быть преднамеренно изменен. Необходимо контролировать типы входящих значений. Например, попробуйте <a href="http://vkontakte.ru">ВКонтакте</a> в комментарий написать union или какой-то запрос. </p>
<p>Нужно численные значения преобразовывать к численным посредством intval(), floatval() и тп.</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$a</span> <span style="color: #339933;">=</span> <span style="color: #990000;">intval</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'a'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>Это уже не позволит вместо $а вписать какой-то запрос. Следует отметить, что intval() нельзя использовать при проверке число или нет в переменной. Intval() возвращает 1 при непустых значениях параметра любого не числового типа. Для проверки на число лучше использовать is_numeric(). </p>
<p>Для строковых значений следует использовать addslashes(), которая экранирует все кавычки символом \. А еще лучше html_entities() для кодирования символов сущностями html(&amp;quot; и т.п.).</p>
<h4>4. The End</h4>
<p>Как видно, доступ к чтению БД очень опасен. Если кому-то кажется, что md5 хеши (да и вообще любые другие) паролей довольно безопасны, хочу огорчить — существует множество онлайн баз данных хешей, которые за несколько секунд позволяют его вскрыть. Также недавно натолкнулся на программку, которая, по заявлению разработчика, способна на GeForce 9600 вскрыть любой md5 хэш за полдня. </p>
<p>При использовании сырого PHP и глобальных массивов стоит быть очень осторожным. Последствия могут быть плачевными. Следует с ответственностью относится к настройке прав пользователей базы, запрещать чтение INFORMATION_SCHEMA и базу данных mysql. Необходимо фильтровать все входные данные. На живых сайтах стоит отключать error_reporting и дамп ошибок БД в браузер.</p>
<p>Спасибо за написание статьи моему другу <strong>Bolshevik&#8217;у</strong>, а мне спасибо за то, что опубликовал :-)<br />
_____<br />
<strong>Рекомендую:</strong><br />
- <a href="http://selivanov.com.ua/">Продвижение сайтов</a> в Украине<br />
- <a href="http://www.love2fly.ru/archives/95">Пока звезды Реала рубятся на Евро-08, мы проникли в раздевалку великого клуба</a><br />
- <a href="http://www.epochta.ru/">Программное обеспечение для создания собственных безопасных e-mail рассылок</a><br />
- <a href="http://magazineseo.com/post_1210321963.html">Как заработать в интернете НЕ продавая информацию</a></p>
]]></content:encoded>
			<wfw:commentRss>http://publicweb.ru/2008/06/25/221/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>
