Pare!
Você está cometendo um erro aqui. Ah, não, você escolheu as funções PHP corretas para tornar seus dados um pouco mais seguros. Isso é bom. Seu erro está na ordem das operações , e como e onde usar essas funções.
É importante entender a diferença entre higienizar e validar dados do usuário, escapar dados para armazenamento e escapar dados para apresentação.
Sanitizando e validando dados do usuário
Quando os usuários enviam dados, você precisa garantir que eles tenham fornecido o que você espera.
Sanitização e Filtragem
Por exemplo, se você espera um número, verifique se os dados enviados são um número . Você também pode converter dados do usuário em outros tipos. Tudo o que é enviado é tratado inicialmente como uma string, forçando os dados numéricos conhecidos a serem um número inteiro ou flutuante, tornando a higienização rápida e sem problemas.
E os campos de texto de forma livre e as áreas de texto? Você precisa garantir que não haja nada inesperado nesses campos. Principalmente, você precisa garantir que os campos que não deveriam ter conteúdo HTML não contenham HTML. Existem duas maneiras de lidar com esse problema.
Primeiro, você pode tentar escapar da entrada HTML com htmlspecialchars
. Você não deve usar htmlentities
para neutralizar o HTML, pois ele também executará a codificação de caracteres acentuados e outros que acha que também precisam ser codificados.
Segundo, você pode tentar remover qualquer HTML possível. strip_tags
é rápido e fácil, mas também desleixado. O Purificador de HTML faz um trabalho muito mais completo, removendo todo o HTML e também permitindo uma lista de permissões seletiva de tags e atributos.
As versões modernas do PHP são fornecidas com a extensão de filtro , que fornece uma maneira abrangente de higienizar a entrada do usuário.
Validação
Garantir que os dados enviados estejam livres de conteúdo inesperado é apenas metade do trabalho. Você também precisa tentar garantir que os dados enviados contenham valores com os quais você possa trabalhar.
Se você espera um número entre 1 e 10, precisa verificar esse valor. Se você estiver usando uma dessas novas entradas numéricas da era HTML5 sofisticadas com um girador e etapas, verifique se os dados enviados estão alinhados com a etapa.
Se esses dados vieram do que deveria ser um menu suspenso, verifique se o valor enviado é aquele que apareceu no menu.
E as entradas de texto que atendem a outras necessidades? Por exemplo, as entradas de data devem ser validadas por meio strtotime
da classe DateTime . A data especificada deve estar entre os intervalos esperados. E os endereços de email? A extensão de filtro mencionada anteriormente pode verificar se um endereço está bem formado, embora eu seja fã da biblioteca is_email .
O mesmo vale para todos os outros controles de formulário. Possui botões de opção? Valide com relação à lista. Tem caixas de seleção? Valide com relação à lista. Tem um upload de arquivo? Verifique se o arquivo é do tipo esperado e trate o nome do arquivo como dados não filtrados do usuário.
Todo navegador moderno vem com um conjunto completo de ferramentas de desenvolvedor integradas, o que torna trivial para qualquer um manipular seu formulário. Seu código deve assumir que o usuário removeu completamente todas as restrições do lado do cliente no conteúdo do formulário !
Escapando Dados para Armazenamento
Agora que você certificou-se de que seus dados estão no formato esperado e contém apenas valores esperados, é necessário se preocupar em manter esses dados no armazenamento.
Todo mecanismo de armazenamento de dados possui uma maneira específica de garantir que os dados sejam escapados e codificados corretamente. Se você estiver criando SQL, a maneira aceita de passar dados nas consultas é através de instruções preparadas com espaços reservados .
Uma das melhores maneiras de trabalhar com a maioria dos bancos de dados SQL no PHP é a extensão PDO . Ele segue o padrão comum de preparar uma instrução , vinculando variáveis à instrução e enviando a instrução e as variáveis ao servidor . Se você não trabalhou com o PDO antes, aqui está um bom tutorial orientado ao MySQL .
Alguns bancos de dados SQL têm suas próprias extensões especializadas em PHP, incluindo SQL Server , PostgreSQL e SQLite 3 . Cada uma dessas extensões preparou o suporte à instrução que opera da mesma maneira que a DOP. Às vezes, pode ser necessário usar essas extensões em vez do PDO para oferecer suporte a recursos ou comportamentos não padrão.
O MySQL também possui suas próprias extensões PHP. Dois deles, de fato. Você só quer usar o chamado mysqli . A antiga extensão "mysql" foi descontinuada e não é segura ou sã para uso na era moderna.
Eu pessoalmente não sou fã de mysqli. A maneira como ele executa a ligação variável nas instruções preparadas é inflexível e pode ser uma tarefa difícil de usar. Em caso de dúvida, use o DOP.
Se você não estiver usando um banco de dados SQL para armazenar seus dados, verifique a documentação da interface do banco de dados que está usando para determinar como passar dados com segurança por ele.
Quando possível, verifique se o seu banco de dados armazena seus dados em um formato apropriado. Armazene números em campos numéricos. Armazene as datas nos campos de data. Armazene dinheiro em um campo decimal, não em um campo de ponto flutuante. Revise a documentação fornecida pelo seu banco de dados sobre como armazenar corretamente diferentes tipos de dados.
Escapando dados para apresentação
Toda vez que você mostra dados aos usuários, você deve garantir que os dados sejam escapados com segurança, a menos que você saiba que não deve ser escapado.
Ao emitir HTML, você quase sempre deve passar os dados originalmente fornecidos pelo usuário htmlspecialchars
. Na verdade, a única vez que você não deve fazer isso é quando você sabe que o usuário forneceu HTML, e que você sabe que ele já foi higienizado-lo usando uma whitelist.
Às vezes você precisa gerar algum Javascript usando PHP. Javascript não tem as mesmas regras de escape que HTML! É uma maneira segura de fornecer valores fornecidos pelo usuário ao Javascript via PHP json_encode
.
E mais
Existem muito mais nuances na validação de dados.
Por exemplo, a codificação do conjunto de caracteres pode ser uma grande armadilha . Seu aplicativo deve seguir as práticas descritas em " UTF-8 o tempo todo ". Existem ataques hipotéticos que podem ocorrer quando você trata os dados da string como o conjunto de caracteres errado.
Mencionei anteriormente as ferramentas de depuração do navegador. Essas ferramentas também podem ser usadas para manipular dados de cookies. Os cookies devem ser tratados como entrada não confiável do usuário .
A validação e escape de dados são apenas um aspecto da segurança de aplicativos da web. Você deve conhecer as metodologias de ataque de aplicativos da Web para poder criar defesas contra elas.