Вопрос про безопасность. (PHP + Apache + MySQL)

markyzz

Есть сайт в денверовской связке PHP + Apache + MySQL
Пользователь сайта посылает запрос через форму. И, соответственно, получает ответ из базы данных. То есть без всяких наворотов реализован поиск по БД.
Вопрос: что нужно сделать, чтобы этот гнусный хацкер уважаемый клиент не качнул БД себе на комп?
(или успокойте меня фразой "качнуть напрямую твою БД невозможно!" :))

Dasar

Пользователь сайта посылает запрос через форму
в каком виде?

markyzz

в каком виде?

Ну, вот как-то так...
 <form action = "index.html" method = "post">
Введите VIN:
<input type = text name = vin>
<input type = submit value = "Послать запрос">
</form>

PooH

а серверную часть покажешь?
т.е. обработка запроса у тебя как происходит?
вообще гугли по sql injection

markyzz

Обработка вот примерно так:
 <?php
$val = $_POST[vin];$host = "localhost";$user = "*******";$pass = "********";$base = "*********";
mysql_connect($host,$user,$pass) OR DIE("Не могу создать соединение ");
mysql_select_db($base);

бла-бла-бла....

$query = "SELECT * FROM $tabl1 WHERE бла-бла-бла.... ";
$res = mysql_query($query) or die(mysql_error;

ну, дальше только оформление...
echo там всякие и т.п.

PooH

бла-бла-бла....
вот тут и будет самая важная часть
если не экранировать строки и напрямую подставлять в запрос, то можно будет сделать что-то такое:
SELECT * FROM `table` WHERE `col`=$var
$var = "24 OR 1=1"
=>
SELECT * FROM `table` WHERE `col`=$var OR 1=1
что вернет всю таблицу
заодно, чуть исхитрившись можно будет и другие таблицы вытащить

PooH

вообще защита от sql injection легко гуглится
основные приемы давно известны, как и способы защиты: экранирование, обрезание ( :) параметризация, фильтрация

markyzz

если не экранировать строки
хм.. ну, у меня, в общем, в этом бла-бла-бла следующее происходит:
строка запроса делится на две (ну, потому что так надо в базу в разные поля подставлять) первые 6 символов строки и следующие 8 символов строки
  
$a1 = substr($val,0,6);
$a2 = substr($val,6,8);

дальше запрос происходит в таком виде:
 
$query = "SELECT * FROM $tabl1 WHERE field1 = '$a1' AND field2 = '$a2' ";

я сейчас пытался приляпать к запросу логическую истину типа 1=1, но что-то не получилось таблицe полностью показать... а можешь пояснить про это экранирование?

doublemother

я сейчас пытался приляпать к запросу логическую истину типа 1=1, но что-то не получилось таблицe полностью показать... а можешь пояснить про это экранирование?
mysql_real_escape_string

ava3443

самое надёжное средство против sql injection - подставлять все параметры только через bind variables ("параметризованные запросы")
в случае php5+mysql для этого, судя по документации, нужно ботать в сторону mysqli_prepare, mysqli_stmt_bind_param, и mysqli_stmt_execute

tokuchu

$query = "SELECT * FROM $tabl1 WHERE field1 = '$a1' AND field2 = '$a2' ";
Тут в принципе можно injection сделать. Но у тебя правда строчка короткая вырезается и поэтому туда сложно что-то всунуть. Но лучше на это не полагаться. Проблема в том, что в $a1 и в $a2 могут быть закрывающие кавычки. Например если в $a2 = "'; delete from <table> where ''='", то будет нехорошо.

alexkravchuk

в простых случаях проще явно проверять на то, допустим ли ввод, или нет.
грубо говоря, сделать что-то вроде такого:
   if( !preg_match("|^[0-9a-zA-Z]+$|", $vin) )
     showFuckOffPage
При этом проверку лучше двойную сделать, одну (желательно) на уровне JS, от ошибочного ввода, вторую (обязательную) уже в PHP.

markyzz

ага - всем спасибо за советы - кажется все понял :)
Оставить комментарий
Имя или ник:
Комментарий: