A validação de $ _GET id na base de dados é suficientemente segura?

Eu tenho 2 páginas no site, uma é index.php e lista de página de índice todas as postagens que existem no database, e outra página é post.php e a publicação da página exibe uma publicação única quando clicada na publicação específica na página de índice.

Agora, o código que eu costumava listar todas as postagens no index.php é:

$postslist = mysqli_query($db, "SELECT * FROM posts"); while ($post = mysqli_fetch_array($postlist)) { echo ''.$post['title'].''; } 

E isso funciona e eu tenho todos os posts exibidos na página index.php e link de links para postar na página post.php.

E na página post.php usei um código como este:

 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 '

' . $data['title'] . '

'; }

E isso funciona bem e recupera a postagem com esse id, mas eu tenho lido alguns tutoriais e publicações aqui no stackoverflow e isso pode ser pouco inseguro e foi sugerido usar código como esse apenas para garantir que ele seja seguro para o uso do database

 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 '

' . $data['title'] . '

'; }

Mas isso lança um erro, por isso é seguro o suficiente, basta verificar contra o database se postid existe e como faço para protegê-lo se isso não for suficientemente seguro?

Parte 2 da pergunta

Edit: Bem, eu peguei na pesquisa sobre os methods publicados de vocês e depois de algumas horas eu fiz isso funcionar com o mysqli_prepare, mas usá-lo no post.php é bastante fácil, pois ele só se conecta à tabela de postagens e puxa todos os dados de uma tabela baseada no ID da postagem.

Mas quando experimentei o mesmo método na página diferente, isso se tornou uma solução bastante grande.

Na segunda página, eu tenho que puxar dados de 5 tabelas diferentes que são juntas usando LEFT JOIN para todas as combinações de id específico a partir de coluna específica na tabela, e isso é o que saiu usando somente 3 tabelas.

 $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); 

E isso funciona bem, mas você pode ver o quão maciço se torna com 3 mesas e eu preciso tirar informações de mais 2 mesas, então eu queria saber se esta é realmente a solução que você usaria?

E outra pergunta, se o usuário tiver que procurar uma página com valor estático como

 index.php?go=upcoming 

Preciso usar também mais segurança ou usá-la agora

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

é seguro o suficiente? Uma vez que existe um valor conhecido de ir e o que esperar.

Está jogando um erro porque mysqli_real_escape_string espera dois argumentos, o primeiro dos quais é a conexão $conn .

Se você fizer isso, deve ser seguro o suficiente , mas seria melhor usar uma consulta parametrizada. Por exemplo:

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

Verificando se o id existe no database não é seguro contra a injeção, pois você precisa usar um id potencialmente mal-intencionado na consulta para fazer o cheque em primeiro lugar.

Se a sua coluna de id for um número inteiro, use isso:

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

Isso será seguro, porque a coerção do tipo (int) remove todos os caracteres ilícitos.

Fazer o SQL seguro também pode ser tão simples quanto: use sempre parâmetros para valores dynamics. Isso funciona para valores inteiros e strings e datas. Então você não precisa se preocupar em citar ou escaping ou filtrar. @ExplosionPills mostra um exemplo.