• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

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

    Запись на курс до 25 апреля. Получить промодоступ ...

Работа с Mysql. Sql-инъекция.

  • Автор темы Vadik(R)
  • Дата начала
V

Vadik(R)

Недавно стал изучать MySQL. Стал создавать БД, таблицы и т.д. думал очень удобно пользоваться этим при создании сайта. Но где-то читал о том, что могут быть SQL-инъекции и вообщем использование БД будет небезопасно. Честно говоря, так и не понял как хакеры все это взламывают, но вот хотел спросить: Будет ли безопасно, если я заменю код с проверкой на код без проверки?
Код с проверкой:[codebox]function letterexist($letter) {
return ($letter=="0" || $letter=="A" || $letter=="B" || $letter=="C" || $letter=="D" || $letter=="E" ||
$letter=="F" || $letter=="G" || $letter=="H" || $letter=="I" || $letter=="J" || $letter=="K" ||
$letter=="L" || $letter=="M" || $letter=="N" || $letter=="O" || $letter=="P" || $letter=="Q" ||
$letter=="R" || $letter=="S" || $letter=="T" || $letter=="U" || $letter=="V" || $letter=="W" ||
$letter=="X" || $letter=="Y" || $letter=="Z" || $letter=="А" || $letter=="Б" || $letter=="В" ||
$letter=="Г" || $letter=="Д" || $letter=="Е" || $letter=="Ж" || $letter=="З" || $letter=="И" ||
$letter=="К" || $letter=="Л" || $letter=="М" || $letter=="Н" || $letter=="О" || $letter=="П" ||
$letter=="Р" || $letter=="С" || $letter=="Т" || $letter=="У" || $letter=="Ф" || $letter=="Х" ||
$letter=="Ц" || $letter=="Ч" || $letter=="Ш" || $letter=="Щ" || $letter=="Э" || $letter=="Ю" ||
$letter=="Я");
}
function pageexist($letter, $page) {
$res=mysql_query("SELECT * FROM Additional WHERE aKey='".$letter."'");
while($row=mysql_fetch_array($res)) {
$count=$row[count];
}
for ($i=1; $i<=$count; $i++) {
if (($i-1-($i-1)%10)/10+1==$page) {
return true;
}
}
return false;
}
?>
<?php
if (letterexist($_GET['letter']) && pageexist($_GET['letter'], $_GET['page'])) {
$letter=$_GET['letter'];
$x=$_GET['page'];
$res=mysql_query("SELECT * FROM Additional WHERE aKey='".$letter."'");
while($row=mysql_fetch_array($res)) {
$n=$row[count];
}
$res=mysql_query("SELECT * FROM Clips WHERE aKey='".$letter."' AND desyat='".$x."'");
while($row=mysql_fetch_array($res)) {
$author=$row[author];
$track=$row[track];
$size=$row[size];
$extension=$row[extension];
$resolution=$row[resolution];
$duration=$row[duration];
$link=$row[link];
$imgsrc=$row[imgsrc];
if (!$flag) {
$flag=1;
} else {
echo "<hr>\n";
}
writeContent($author, $track, $size, $extension, $resolution, $duration, $link, $imgsrc);
}
}
?>[/codebox]
Код без проверки: [codebox]$letter=$_GET['letter'];
$x=$_GET['page'];
$res=mysql_query("SELECT * FROM Additional WHERE aKey='".$letter."'");
while($row=mysql_fetch_array($res)) {
$n=$row[count];
}
$res=mysql_query("SELECT * FROM Clips WHERE aKey='".$letter."' AND desyat='".$x."'");
while($row=mysql_fetch_array($res)) {
$author=$row[author];
$track=$row[track];
$size=$row[size];
$extension=$row[extension];
$resolution=$row[resolution];
$duration=$row[duration];
$link=$row[link];
$imgsrc=$row[imgsrc];
if (!$flag) {
$flag=1;
} else {
echo "<hr>\n";
}
writeContent($author, $track, $size, $extension, $resolution, $duration, $link, $imgsrc);
}[/codebox]?
Или хакер как-то может использовать то, что я уберу проверку и послать значение одной из переменных с кавычками, что приведет к неправильным выполнениям SQL-запросов?
 
V

Vadik(R)

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

Ockonal

Нет, не все.

Вообще, где-то видел( та и сам использую ).. Фильтрация переменной:
function filterVar( $var ) {
ereg_replace( "insert", "insert", $var );
ereg_replace( "update", "update", $var );
//... И так далее, все запросы.
return $var;
};
Суть в том, что
ereg_replace( "insert", "insert", $var );
во первом параметре ф-ции 4-я буква - e (en) , а во втором, русская Е
 
V

Vadik(R)

Может я несовсем понял суть фильтрации переменной, но, например, пусть у меня в таблице встретится слово с английской e. Допустим слово insert. Так вот, если ПОЛЬЗОВАТЕЛЬ (не хакер) захочет воспользоваться поиском и наберет в нем слово insert. Я через фильтрацию переменной заменю букву e латинскую на е русскую. Далее будет идти строчка.
$res=mysql_query("SELECT * FROM Tablica1 WHERE pole1='".$filtrovannayaperemennaya."'");
Но поиск будет с русской буквой е. И не будет ни одного результата. Тогда как мне быть в такой ситуации? Заменить в таблице все insert'ы с английской e на русскую е? Как-то это кажется немного некорректно... А вдруг у меня в таблице (просто, размышляя теоритечески) будут встречаться insert'ы и русской и с английской е? Вот тут-то и некорректно будет это использование. Хотя, как написал в первом предложении, возможно я не осознал всю полезность вашей функции filterVar().
P. S. С размышлением теоретически вспомнил одну темку про Делфи. Лучше всего там ответил Morpheus.
 
V

Vadik(R)

Я же говорю, что РАЗМЫШЛЯЯ ТЕОРЕТИЧЕСКИ
insert
insеrt
Вот два слова. Но форум их никак не экранирует, одно из них содержит русскою Е, а другое - английскую. А как я уже писал filterVar что, всегда будет сохранять ТОЛЬКО ЛИБО с РУССКОЙ ЛИБО с АНГЛИЙСКОЙ. А мне охота по-нормальному, ведь в мире возможно все!
 
V

Vadik(R)

Есть идея, конечно, тоже не наилучшая, но все же она позволяет добиться этого, правда объем БД вырастет в 2 раза. Сделать как в языках программирования, например, перед каждым символом ставить слеш.
 
G

GOsha

ЧЕ-та вы, ребята, паранойей страдаете. ))) достаточно escape_string`a и еще небольшого количества мелочей. Наденьте голову на плечи и почитайте про иньекции. Вы поймете, что не нужно так маньячить. с insert`ом вообще посмеяли старого. Я надеюсь никто запросы не формирует из GET, у всех отключены register_globals, error_reporting стоит на 15 и в адресной строке никто не гоняет: index.php?authorized=yes&login=Vasya&pass=123... ))))
 
O

Ockonal

GOsha,
Никто ничем не страдает :)
Эти хацкеры такое выдумывают ;) Например, используя комментирование.
А на счет поста №2 - это я решал свою проблему, где у меня WYSIWYG-редактор, который генерирует html-строчку, где я не могу экранизировать кавычки и заменить `<`, `>` на их аналоги.
 
G

GOsha

А что за редактор? Просто html-код не позволит взломать сайт - это всего-лишь язык форматирования. Он ничего не прочитает из базы и не запишет. Аесли юзер по каким-то причинам захочет написать "<" или ">" или даже "<?" То нормальный редактор вернет "<""&rt;" и "<?" Что по сути своей везвредно.... Insert в инсерт запросе не выполнится, если вы в самом запросе заключили переменную в кавычки: " Insert *bla-bla-bla* \"$text\"". Он так и воткнет в базу эту строчку... НИЧЕГО СТРАШНОГО!
 
O

Ockonal

>Просто html-код не позволит взломать сайт - это всего-лишь язык форматирования.
XSS никто не отменял :)
На счет всего, что дальше - верно, но это опен сурсный :) Что там может быть нормального( в основном ), а самому времени писать нету.
 
V

Vadik(R)

Пришел к выводу, что стоит полученные данные заключать в кавычки, но перед этим сделать mysql_real_escape_string. Это если данные не числовые. У меня как раз этот вариант.
А при выдаче результатов преобразовать последовательности в нормальные кавычки. Вот вроде и все! :)
----
Хотя нет, не все. У меня тогда возникает вопрос: а как записать в таблицу строку, содержащую и одинарные и двойные кавычки? Только я хочу записать кавычки в нормальном виде, а не какими-либо последовательностями.
 
G

GOsha

Код:
/*
mysql_real_escape_string
(только PHP 4 CVS)

mysql_real_escape_string - мнемонизирует специальные символы в строке для использования в операторе SQL с учётом текущего набора символов/charset соединения.

Описание
string mysql_real_escape_string (string unescaped_string [, resource link_identifier])

Эта функция мнемонизирует/escape специальные символы в строке unescaped_string, учитывая текущий charset соединения, чтобы эту строку можно было направить в mysql_query().

Примечание: mysql_real_escape_string() не мнемонизирует % и _.
*/
//Пример 1. mysql_real_escape_string()
<?php
$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
$item = "Zak's and Derick's Laptop";
$escaped_item = mysql_real_escape_string($item);
printf ("Escaped string: %s\n", $escaped_item);
?>
//На выводе:Escaped string: Zak\'s and Derick\'s Laptop
//См. также mysql_escape_string(), mysql_character_set_name().

Эскейп стринг сделает все за тебя. + Еще есть такой html-символ " - он же кавычки )))
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!