Достаточно ли проверять достоверность идентификатора $ _GET в базе данных?

У меня есть 2 страницы на веб-сайте, одна из них – index.php и индексная страница список всех сообщений, которые существуют в базе данных, а другая страница – post.php и post page display single post при нажатии на определенное сообщение на индексной странице.

Теперь код, который я использовал для перечисления всех сообщений в index.php:

$postslist = mysqli_query($db, "SELECT * FROM posts"); while ($post = mysqli_fetch_array($postlist)) { echo '<a href="' .SITEURL.'/post.php?p='.$post['postid'].'>'.$post['title'].'</a>'; } 

И это работает, и у меня есть все сообщения, отображаемые на моей странице index.php и ссылки для публикации на post.php странице.

И на странице post.php я использовал такой код:

 if(!isset($_GET['p'])){ echo 'Dont load this page directly'; } else { $id = $_GET['p']; $querypost = mysqli_query($conn, "SELECT * FROM posts WHERE postid='$id'"); $data = mysqli_fetch_array($querypost); echo '<h3>' . $data['title'] . '</h3>'; } 

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

 if(!isset($_GET['p'])){ echo 'Dont load this page directly'; } else { $id = $_GET['p']; $id = mysqli_real_escape_string($id); $querypost = mysqli_query($conn, "SELECT * FROM posts WHERE postid='$id'"); $data = mysqli_fetch_array($querypost); echo '<h3>' . $data['title'] . '</h3>'; } 

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

Часть вторая вопроса

Редактирование: Ну, я взял на себя поиск методов, опубликованных у вас, ребята, и через несколько часов я включил его в mysqli_prepare, но его использование в post.php довольно просто, поскольку оно только подключается к таблице сообщений и вытаскивает все данные из одной таблицы по сообщению id.

Но когда я пробовал такой же метод на другой странице, это стало довольно большим решением.

На второй странице мне приходится извлекать данные из 5 разных таблиц, которые объединяются с использованием LEFT JOIN во все соответствия определенного идентификатора из определенного столбца в таблице, и это то, что вышло только с использованием 3 таблиц.

 $stmt = mysqli_prepare($conn, "SELECT * FROM giveaways INNER JOIN members ON giveaways.creator = members.steamID INNER JOIN sc_steamgames ON giveaways.gameid = sc_steamgames.appid WHERE giveawayID=?"); mysqli_stmt_bind_param($stmt, "i", $id); mysqli_stmt_execute($stmt); mysqli_stmt_bind_result($stmt, $id, $creator, $comment, $tcreated, $tstarting, $tfinish, $provider, $type, $gameid, $memberid, $steamid, $username, $profileurl, $avatar, $avatarmed, $avatarbig, $steamgames, $regdate, $verified, $coins, $gold, $points, $appid, $title, $storeprice, $valuedprice, $pointsworth); mysqli_stmt_fetch($stmt); echo $creator .' - '. $comment . ' - '. $gameid . ' - ' .$title.' - '.($storeprice /100) ; mysqli_stmt_close($stmt); 

И это прекрасно работает, но вы можете видеть, насколько массивным это стало с 3 таблицами, и мне нужно вывести информацию из еще двух таблиц, поэтому мне было интересно, действительно ли это решение, которое вы бы использовали?

И еще один вопрос, если пользователь должен просматривать страницу со статическим значением, например

 index.php?go=upcoming 

Нужно ли мне также использовать некоторую дополнительную безопасность или использовать ее, как сейчас

 if(isset($_GET['go']) && $_GET['go'] == 'upcoming') 

достаточно безопасна? Поскольку существует известная ценность go и чего ожидать.

Это mysqli_real_escape_string ошибку, потому что mysqli_real_escape_string ожидает два аргумента, первым из которых является соединение $conn .

Если вы это сделаете, он должен быть достаточно безопасным , но лучше использовать параметризованный запрос. Например:

 $stmt = mysqli_prepare($conn, "SELECT cols FROM posts WHERE postid = ?"); mysqli_stmt_bind_param($stmt, 'i', $id); 

Проверка того, что id существует в базе данных, вовсе не защищен от инъекций, поскольку вам необходимо использовать потенциально вредоносный id в запросе, чтобы выполнить проверку в первую очередь.

Если ваш столбец id является целым числом, используйте следующее:

 $id = (int) $_GET['p']; 

Это будет безопасно, потому что принуждение типа (int) уничтожает любые незаконные символы.

Обеспечение безопасности SQL также может быть простым: всегда используйте параметры для динамических значений. Это работает для целых значений, строк и дат. Тогда вам не нужно беспокоиться о цитировании или выходе или фильтрации. @ExplosionPills показывает пример.