Нужно организовать защиту от SQL инъекций в адресную строку. Я так понимаю нужно обрабатывать регулярным выражением переменные, передаваемые через ГЕТ, на основе которых из базы выводится содержимое. Какие символы нужно нужно удалять помимо Код (Text): ' " \ / % ( ) * ? И если ссылок много, придётся искать каждую и приставлять к ней рег.выражение или можно это как-то упростить?
Есть ссылка вида http://newlenta.ru/comments.php?id=1 если сделать так http://newlenta.ru/comments.php?id=1' вылетают ошибки. Обрабатываю id: PHP: if (isset($_GET['id'])) $id = $_GET['id']; $id = mysql_real_escape_string($id); или так PHP: if (isset($_GET['id'])) $id = mysql_real_escape_string($_GET['id']); добавляю кавычку - опять ошибки... что деляю не так?
ok comments.php PHP: <?php error_reporting(E_ALL); include "config.php"; echo "<a href=index.php>На главную</a><br><hr color=maroon>"; if (isset($_GET['id'])) $id = $_GET['id']; $id = mysql_real_escape_string($id); $quer = "SELECT head,DATE_FORMAT(date,'%d-%m-%Y %H:%i') as date_reg, news FROM newslent WHERE id=$id"; $rs = mysql_query($quer); $rw = mysql_fetch_array($rs); ?> <table> <tr><?echo $rw['head']?></tr> <br> <tr><?echo $rw['date_reg']?></tr> <br> <tr><?echo nl2br($rw['news'])?></tr> <hr color=maroon><br> </table> <? //Запрашиваем общее кол-во КОММЕНТОВ $q = "SELECT COUNT(*) FROM comments WHERE id_news=$id"; $tot = mysql_query($q); $f = mysql_fetch_row($tot); $total_rows = $f[0]; //Количество комментов $num_pages = ceil($total_rows/$pnumber); //Количество страниц $page = !empty($_GET['page']) ? intval($_GET['page']) : 1; if ($page<1) $page = 1; if ($page>$num_pages) $page = $num_pages; //Запрашиваем сами КОММЕНТЫ $q = "SELECT id, id_news, DATE_FORMAT(date_com,'%d-%m-%Y %H:%i')as date_reg, name_com, comm, new FROM comments WHERE id_news=$id ORDER BY id DESC LIMIT ".($page - 1)*$pnumber.",".$pnumber.""; $res=mysql_query($q); //Выводим комментарии while (@$row = mysql_fetch_array($res)) { echo $row['name_com'];echo " "; echo $row['date_reg']; echo"<br>"; echo nl2br($row['comm']); echo"<br><hr>"; } //ПОСТРАНИЧНАЯ НАВИГАЦИЯ if ($total_rows > $pnumber) { for($i=1;$i<=$num_pages; $i++) { if ($i==$page) echo $i; else echo '<a href="'.$_SERVER['PHP_SELF'].'?page='.$i.'&id='.$id.'"> '.$i."</a>\n"; } } ?> <script> function splash(f) { if (f.name_com.value =='') { alert ("Укажите ваше имя"); return false; } if (f.comm.value =='') { alert ("Заполните текст комментария!"); return false; } if (f.comm.value.length < 5) { alert ("Сообщение слишком короткое"); return false; } if (f.comm.value.length > 1000) { alert ("Сообщение слишком длинное"); return false; } return true; } </script> <H2>Добавить комментарий:</H2> <table> <form name="myForm" method='POST' action="addcomment.php" onSubmit="return splash(this);"> <tr> <td><input type="text" name="name_com"></td> </tr> <tr> <td><textarea name="comm" cols=50 rows=10></textarea></td> </tr> <tr> <td><input type="submit" value="Добавить"></td> <td><input type="hidden" name="id" value="<?echo $id;?>"></td> <input type="hidden" name="addaction" value=""> </tr> </form> </table> index.php PHP: <?php //ссылка на комментарии echo "<center><a href=comments.php?id=".$row['id']."> Комментировать ($total_com_rows) </a></center>";
Текст ошибки нужно писать, чтобы мы сами не выясняли. $id чем ожидается? Числом. Когда приходит число, то запрос преобразовывается в WHERE id=2. Когда Вы добавляете кавычку, то приходит строка 5\' Строка в запросе воспринимается как переменная или оператор, но так как она содержит недопустимые символы, да и нет таких операторов, вылетает ошибка. Поэтому строки нужно брать в кавычки (когда ожидается строка). В данном случае два выхода: 1. Приведение id к числу, посредством (int)$id или intval($id) (одно и то же). 2. Проверка $id функцией is_numeric, которая вернет false, в случае, когда $Id - строка. Тогда можно выдать предупреждение пользователю. $_GET['id'] есть, у $id есть значение. $_GET['id'] нет, $id не существует. А дальше в коде идет к ней обращение, которое вызывает Notice. Название темы прикольное.
Kreker, доходчиво, спасибо. А по названию - читал что символы нужно резать регуляркой - отсюда и название. Я так понял mysql_real_escape_string нужно использовать для значений, которые будут заноситься в БД - все опасные символы экранируются и как следствие SQL инъекции нам не страшны? И по ходу рег. выражения для обработки гет и пост переменных вообще не нужны.
Ей экранируются данные применяемые в запросе, и только для прохождения запроса. Будут они заноситься в базу или нет, и берутся они из post или get - не важно (в самой базе будет исходный текст). Для POST может и не нужны, а вот для GET было бы неплохо, но против другой штуки - XSS.
?? В POST могут тоже ерунду прислать. И escaping, в первую очередь, не от XSS. Он ведь для экранирования. Не страшны. Ошибки могут генерировать не только SQL-инъекции. Как видно из Вашего примера, функция mysql_real... не помогла из-за неверного подхода.