Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Substituindo funções mysql_* por PDO e instruções preparadas


Obrigado pela pergunta interessante. Aqui você vai:

Ele escapa de personagens perigosos,

Seu conceito está totalmente errado.
Na verdade, "caracteres perigosos" é um mito, não há nenhum. E mysql_real_escape_string escapando, mas apenas um delimitadores de string . A partir desta definição, você pode concluir suas limitações - funciona apenas para strings .

no entanto, ainda é vulnerável a outros ataques que podem conter caracteres seguros, mas podem ser prejudiciais à exibição de dados ou, em alguns casos, à modificação ou exclusão de dados maliciosamente.

Você está misturando tudo aqui.
Falando em banco de dados,
  • para as strings, NÃO é vulnerável. Contanto que suas strings sejam citadas e escapadas, elas não podem "modificar ou excluir dados maliciosamente".*
  • para os outros tipos de dados - sim, é inútil . Mas não porque é um pouco "inseguro", mas apenas por causa do uso indevido.

Quanto aos dados de exibição, suponho que seja offtopic na pergunta relacionada ao PDO, pois o PDO também não tem nada a ver com a exibição de dados.

escapando da entrada do usuário

^^^ Outra ilusão a ser notada!

  • uma entrada de usuário não tem absolutamente nada a ver com escape . Como você pode aprender com a definição anterior, você precisa escapar de strings, não qualquer "entrada do usuário". Então novamente:
    • você tem strings de escape, independentemente de sua origem
    • é inútil escapar de outros tipos de dados, independentemente da fonte.

Entendeu?
Agora, espero que você entenda as limitações de escapar, bem como o equívoco de "personagens perigosos".

É do meu entendimento que usar PDO/declarações preparadas é muito mais seguro

Na verdade, não.
Na verdade, existem quatro diferentes partes de consulta que podemos adicionar dinamicamente:
  • uma sequência
  • um número
  • um identificador
  • uma palavra-chave de sintaxe.

então, você pode ver que o escape cobre apenas um problema. (mas é claro, se você tratar números como strings (colocando-os entre aspas), quando aplicável , você pode torná-los seguros também)

enquanto as declarações preparadas cobrem - ugh - 2 questões inteiras! Um grande negócio;-)

Para os outros 2 problemas, veja minha resposta anterior, No PHP, ao enviar strings para o banco de dados, devo cuidar de caracteres ilegais usando htmlspecialchars() ou usar uma expressão regular?

Agora, os nomes das funções são diferentes, então não funcionarão mais mysql_query, mysql_fetch_array, mysql_num_rows etc.

Essa é outra, grave ilusão dos usuários PHP , um desastre natural, uma catástrofe:

Mesmo ao utilizar o driver mysql antigo, nunca se deve usar funções de API simples em seu código! É preciso colocá-los em alguma função de biblioteca para o uso diário! (Não como um rito mágico, mas apenas para tornar o código mais curto, menos repetitivo, à prova de erros, mais consistente e legível).

O mesmo vale para o PDO!

Agora com sua pergunta novamente.

mas ao usá-los isso elimina a necessidade de usar algo como mysql_real_escape_string?

SIM.

Mas acho que essa é mais ou menos a ideia do que deve ser feito para buscar um usuário de um banco de dados

Não para buscar, mas para adicionar qualquer dado à consulta !

você tem que dar um comprimento depois de PDO:PARAM_STR se não me engano

Você pode, mas não precisa.

Agora, tudo isso é seguro?

Em termos de segurança de banco de dados, simplesmente não há pontos fracos neste código. Nada para garantir aqui.

para a segurança de exibição - basta pesquisar neste site pelo XSS palavra-chave.

Espero ter lançado alguma luz sobre o assunto.

BTW, para as inserções longas, você pode fazer algum uso da função que escrevi algum dia, Inserir/atualizar função auxiliar usando PDO

No entanto, não estou usando declarações preparadas no momento, pois prefiro meus marcadores caseiros a eles, utilizando uma biblioteca mencionei acima. Então, para contrariar o código postado pela riha abaixo, seria tão curto quanto essas 2 linhas:
$sql  = 'SELECT * FROM `users` WHERE `name`=?s AND `type`=?s AND `active`=?i';
$data = $db->getRow($sql,$_GET['name'],'admin',1);

Mas é claro que você também pode ter o mesmo código usando instruções preparadas.

* (yes I am aware of the Schiflett's scaring tales)