Protegendo dados que vem do formulário
Bom, este é meu primeiro artigo no site. O objetivo do artigo é explicar um pouco sobre uma classe que fiz, chamada de "Input", de fácil utilização, porém de grande importância.
Durante um bom tempo, usava as funções htmlentities / mysql_escape_string / addslashes em todas as variáveis que iria salvar no banco de dados, o que gerava algumas repetições de códigos em todas as classes.
A solução que encontrei foi criar uma classe que tratasse todos os campos vindos de um formulário e após isso salvar no banco.
Classe Input:
Exemplo de utilização (Protegendo dados $_POST):
A classe da suporte a "post", "get" e "session".
Permitindo códigos HTML em determinado campo
Observação importante:
Ao pegar as informações do banco de dados, deve-se utilizar a função stripslashes($variavel) para remover as \ (contra barras)
Caso queira contribuir com críticas, sugestões ou até mesmo postanto uma atualização para esta classe, sinta-se a vontade.
Durante um bom tempo, usava as funções htmlentities / mysql_escape_string / addslashes em todas as variáveis que iria salvar no banco de dados, o que gerava algumas repetições de códigos em todas as classes.
A solução que encontrei foi criar uma classe que tratasse todos os campos vindos de um formulário e após isso salvar no banco.
Classe Input:
<?php /* * CLASSE DE PROTEÇÃO EM DADOS VINDOS DE FORMULÁRIO * Hudolf Jorge Hess < hudolf@gmail.com > * http://www.hudolfhess.com/ * * Proteger entradas INPUTS vindas de formulários tanto GET quanto POST. */ class Input { private $tmp = array(); private $html = array(); function __construct($type, $html = array()){ $this->html = $html; if ($type == "post"){ $this->tmp = $_POST; $this->protegendo(); $_POST = $this->tmp; } else if ($type == "get"){ $this->tmp = $_GET; $this->protegendo(); $_GET = $this->tmp; } else if ($type == "session"){ $this->tmp = $_SESSION; $this->protegendo(); $_SESSION = $this->tmp; } } private function protegendo(){ foreach ($this->tmp as $index=>$valor){ //SE FOR UMA ARRAY IRÁ ACESSAR TODOS OS OUTROS VALORES DELA if (is_array($valor)){ $this->tmp[$index] = $this->subProtegendo($valor); } else { //ESTA VERIFICAÇÃO SERVE PARA DADOS VINDOS ATRAVÉS DO jQuery Form Plugin if (mb_detect_encoding($valor) == "UTF-8"){ $xvalor = utf8_decode($valor); if (mb_detect_encoding($xvalor) == "UTF-8"){ $valor = $xvalor; } } if (in_array($index, $this->html)){ if (!get_magic_quotes_gpc()){ $this->tmp["$index"] = addslashes($valor); } else { $this->tmp["$index"] = $valor; } } else { if (!get_magic_quotes_gpc()){ $this->tmp["$index"] = htmlspecialchars(addslashes($valor)); } else { $this->tmp["$index"] = htmlspecialchars($valor); } } } } } private function subProtegendo($valor){ $xvalor = array(); foreach ($valor as $index=>$nvalor){ if (is_array($nvalor)){ $xvalor[$index] = $this->subProtegendo($nvalor); } else { //ESTA VERIFICAÇÃO SERVE PARA DADOS VINDOS ATRAVÉS DO jQuery Form Plugin if (mb_detect_encoding($nvalor) == "UTF-8"){ $xvalor = utf8_decode($nvalor); if (mb_detect_encoding($xvalor) == "UTF-8"){ $nvalor = $xvalor; } } if (in_array($index, $this->html)){ if (!get_magic_quotes_gpc()){ $xvalor["$index"] = addslashes($nvalor); } else { $xvalor["$index"] = $nvalor; } } else { if (!get_magic_quotes_gpc()){ $xvalor["$index"] = htmlspecialchars(addslashes($nvalor)); } else { $xvalor["$index"] = htmlspecialchars($nvalor); } } } } return $xvalor; } } ?>
Exemplo de utilização (Protegendo dados $_POST):
require_once "Input.class.php"; //Trata os dados vindo de um formulário usando o método POST $inputObj = new Input("post"); print_r($_POST);
A classe da suporte a "post", "get" e "session".
Permitindo códigos HTML em determinado campo
require_once "Input.class.php"; //Campos a serem permitidos HTML $html = array("Noticia", "Descricao"); //Trata os dados vindo de um formulário usando o método POST //Porém os campos contidos no array $html exibirão o HTML normalmente $inputObj = new Input("post", $html); print_r($_POST);
Observação importante:
Ao pegar as informações do banco de dados, deve-se utilizar a função stripslashes($variavel) para remover as \ (contra barras)
Caso queira contribuir com críticas, sugestões ou até mesmo postanto uma atualização para esta classe, sinta-se a vontade.
Carlos Eduardo Gomes Monteiro, cada caso o seu caso, neh?
Se quiser manter a impressão visual das entidades HTML é só fazer o seguinte:
Trocar:
FILTER_SANITIZE_STRING
por
FILTER_SANITIZE_SPECIAL_CHARS
Vai fazer as duas coisas, proteger e manter a impressão visual, no caso de:
"Oi, eStoU cOm <xAuDaDEs>"
O que vai ser obtido é:
"Oi, eStoU cOm <xAuDaDEs>"
Se quiser manter a impressão visual das entidades HTML é só fazer o seguinte:
Trocar:
FILTER_SANITIZE_STRING
por
FILTER_SANITIZE_SPECIAL_CHARS
Vai fazer as duas coisas, proteger e manter a impressão visual, no caso de:
"Oi, eStoU cOm <xAuDaDEs>"
O que vai ser obtido é:
"Oi, eStoU cOm <xAuDaDEs>"
22/07/2010 6:44pm
(~14 anos atrás)
Mas hein Hudolf
O seu código está correto!
O que estava falando que remove as tags é esta linha de código abaixo...
filter_var_array($var, FILTER_SANITIZE_STRING);
Esta sim remove as tags...
Mas o seu código não...
Foi mal, não fui muito claro...
O seu código está correto!
O que estava falando que remove as tags é esta linha de código abaixo...
filter_var_array($var, FILTER_SANITIZE_STRING);
Esta sim remove as tags...
Mas o seu código não...
Foi mal, não fui muito claro...
07/07/2010 7:00pm
(~14 anos atrás)
Carlos Eduardo, ele não removerá os códigos HTML, ele irá converte-los apenas.
< para < e assim por diante, no momento da exibição, não será reconhecido como um código HTML e sim como um texto normal.
< para < e assim por diante, no momento da exibição, não será reconhecido como um código HTML e sim como um texto normal.
30/06/2010 11:13am
(~14 anos atrás)
Bem...
O problema no código apresentado, é que ele vai remover as tags HTML.
Então, se o usuário que gosta de inventar moda, escrever um texto assim...
"Oi, eStoU cOm <xAuDaDEs>"
...
E quanto ao lance do reconhecimento de caracteres...
Bem, meus códigos nem preciso.
E acho que é isso que tem que ser feito.
Como disse, tem que ser tudo planejado e documentado.
E os programadores que vierem a trabalhar no sistema futuramente, tem que ver a documentação. É para isso que ela serve...
Na minha opnião, é até desnecessário o reconhecimento de caracteres num código daqueles.
Pra mim, isso é necessário quando se faz comunicação com entidades externas.
Aí sim, pois é algo que está fora da documentação, e que até certo ponto, não podemos prever ao certo o que é recebido da entidade externa.
O problema no código apresentado, é que ele vai remover as tags HTML.
Então, se o usuário que gosta de inventar moda, escrever um texto assim...
"Oi, eStoU cOm <xAuDaDEs>"
...
E quanto ao lance do reconhecimento de caracteres...
Bem, meus códigos nem preciso.
E acho que é isso que tem que ser feito.
Como disse, tem que ser tudo planejado e documentado.
E os programadores que vierem a trabalhar no sistema futuramente, tem que ver a documentação. É para isso que ela serve...
Na minha opnião, é até desnecessário o reconhecimento de caracteres num código daqueles.
Pra mim, isso é necessário quando se faz comunicação com entidades externas.
Aí sim, pois é algo que está fora da documentação, e que até certo ponto, não podemos prever ao certo o que é recebido da entidade externa.
30/06/2010 10:47am
(~14 anos atrás)
Hehe.
Então, Carlos Eduardo Gomes Monteiro,
Acho que você distorceu um pouco o que falei:
Veja o que eu disse:
>>E vale citar que o reconhecimento de caractere por multibytes não >>está habilitado por padrão no PHP, e não vai servir pra nada neste >>caso se estiver desabilitado!
E veja o que você respondeu:
>>Você falou sobre o reconhecimento de caracteres como se fosse algo >>que não devessemos usar.
Bom, de fato. Não disse que não era necessário usar! Se a empresa de hospedagem não habilitar esta extensão, vai acontecer o mesmo que aconteceu na empresa que trabalho e não tinha o php com esta extensão habilitada e o antigo programador jogou o codigo lá no servidor, ai as secretárias acessavam a página, geravam um cadastro e os caracteres iam convertidos errado, e depois os dados não eram achados numa busca qualquer.
Logo, a forma mais óbvia é gerar um controle direto no script em Ajax em questão com outra classe de manipulação de codificação de caracteres e só confiar neste recurso se tiver a certeza de está habilitado.
Outra coisa que você falou:
>> E quanto ao código que você mostrou, bem, acho que fugiu bastante da >> proposta do Hudolf...
Não sei onde que fugi bastante da proposta, pois, o que apresentei, faz basicamnete a mesma coisa e mais rápido.
Pra quem não sabe FILTER_SANITIZE_STRING converte para entidades HTML os caracteres que propiciariam uma INJEÇÃO SQL e logo, o uso de addslashes() é desnecessário, pois não há nada a se escapar!
E como os dados vão ser procurados por uma busca, e precisarão ser protegidos por esta mesma classe, então serão achados igualmente!
Onde fugi? a classe dele é para proteção, não para controle de bytecode!
Isto pode ser feito no script em ajax e não sobrecarregar a aplicação à toa!
Então, Carlos Eduardo Gomes Monteiro,
Acho que você distorceu um pouco o que falei:
Veja o que eu disse:
>>E vale citar que o reconhecimento de caractere por multibytes não >>está habilitado por padrão no PHP, e não vai servir pra nada neste >>caso se estiver desabilitado!
E veja o que você respondeu:
>>Você falou sobre o reconhecimento de caracteres como se fosse algo >>que não devessemos usar.
Bom, de fato. Não disse que não era necessário usar! Se a empresa de hospedagem não habilitar esta extensão, vai acontecer o mesmo que aconteceu na empresa que trabalho e não tinha o php com esta extensão habilitada e o antigo programador jogou o codigo lá no servidor, ai as secretárias acessavam a página, geravam um cadastro e os caracteres iam convertidos errado, e depois os dados não eram achados numa busca qualquer.
Logo, a forma mais óbvia é gerar um controle direto no script em Ajax em questão com outra classe de manipulação de codificação de caracteres e só confiar neste recurso se tiver a certeza de está habilitado.
Outra coisa que você falou:
>> E quanto ao código que você mostrou, bem, acho que fugiu bastante da >> proposta do Hudolf...
Não sei onde que fugi bastante da proposta, pois, o que apresentei, faz basicamnete a mesma coisa e mais rápido.
Pra quem não sabe FILTER_SANITIZE_STRING converte para entidades HTML os caracteres que propiciariam uma INJEÇÃO SQL e logo, o uso de addslashes() é desnecessário, pois não há nada a se escapar!
E como os dados vão ser procurados por uma busca, e precisarão ser protegidos por esta mesma classe, então serão achados igualmente!
Onde fugi? a classe dele é para proteção, não para controle de bytecode!
Isto pode ser feito no script em ajax e não sobrecarregar a aplicação à toa!
23/06/2010 1:01pm
(~14 anos atrás)
Gilberto e Carlos, agradeço aos comentários.
Realmente, costumo utilizar ISO como charset padrão, como utilizo servidores padrões, não tive problemas com esta classe.
Mas irei seguir os conselhos passados aqui e implementar a parte dos slashes, que realmente é interessante.
Assim que eu tiver tempo, irei alterar e colocar aqui novamente.
Agradeço aos comentários.
Realmente, costumo utilizar ISO como charset padrão, como utilizo servidores padrões, não tive problemas com esta classe.
Mas irei seguir os conselhos passados aqui e implementar a parte dos slashes, que realmente é interessante.
Assim que eu tiver tempo, irei alterar e colocar aqui novamente.
Agradeço aos comentários.
23/06/2010 12:06am
(~14 anos atrás)
Então Gilberto, você entrou em um assunto importante aí
Gostaria de mensionar dois pontos...
Você falou sobre o reconhecimento de caracteres como se fosse algo que não devessemos usar.
Mas, só pelo fato de não estar habilitado, não creio que isto seja inútil.
A maioria dos programadores utilizam um mesmo servidor para vários sistema (Exceto excessões).
Então acho válido adicionar às bibliotecas pessoais dos programadores códigos como este, uma vez que saibamos que o servidor está habilidade e que tenhamos consciência que se trocar de servidor, poderá haver problemas.
E quanto ao código que você mostrou, bem, acho que fugiu bastante da proposta do Hudolf...
Bem, cada um tem seu estilo não é...
E quando digo estilo. Me refiro desde algo que é muito esquecido na hora do planejamento que é o encode até a escrita do código.
Então tem programadores que preferem ISO, outro UTF8 e etc...
Pelo que eu ví no código, o Hudolf prefere ISO assim como eu...
Então por isso que derrepente ao ser ver, o código não é muito interessante, mas, ao meu ver, é uma boa sugestão.
E escrevendo este comentário me lembrei de algo interessante para este código...
Uma sugestão aí para o Hudolf...
Acho que seria interessante adicionar um parametro para os slashes...
Pois nem sempre precisamos adiciona-los, como por exemplo, um formulário de contato.
Basta receber os dados do formulário e enviar por e-mail.
Então acho que seria desvantajoso, utilizar esta classe para agilizar para o programador, mas, depois, ter que usar um stripslashes() só para corrigir algo que é simples de arrumar...
Gostaria de mensionar dois pontos...
Você falou sobre o reconhecimento de caracteres como se fosse algo que não devessemos usar.
Mas, só pelo fato de não estar habilitado, não creio que isto seja inútil.
A maioria dos programadores utilizam um mesmo servidor para vários sistema (Exceto excessões).
Então acho válido adicionar às bibliotecas pessoais dos programadores códigos como este, uma vez que saibamos que o servidor está habilidade e que tenhamos consciência que se trocar de servidor, poderá haver problemas.
E quanto ao código que você mostrou, bem, acho que fugiu bastante da proposta do Hudolf...
Bem, cada um tem seu estilo não é...
E quando digo estilo. Me refiro desde algo que é muito esquecido na hora do planejamento que é o encode até a escrita do código.
Então tem programadores que preferem ISO, outro UTF8 e etc...
Pelo que eu ví no código, o Hudolf prefere ISO assim como eu...
Então por isso que derrepente ao ser ver, o código não é muito interessante, mas, ao meu ver, é uma boa sugestão.
E escrevendo este comentário me lembrei de algo interessante para este código...
Uma sugestão aí para o Hudolf...
Acho que seria interessante adicionar um parametro para os slashes...
Pois nem sempre precisamos adiciona-los, como por exemplo, um formulário de contato.
Basta receber os dados do formulário e enviar por e-mail.
Então acho que seria desvantajoso, utilizar esta classe para agilizar para o programador, mas, depois, ter que usar um stripslashes() só para corrigir algo que é simples de arrumar...
22/06/2010 11:21pm
(~14 anos atrás)
<?php
/**
* Classe criada inspirada no script "Protegendo dados que vem do formulário", criado por Hudolf Hess em 10/04/2010 11:13pm e publicado em http://phpbrasil.com/artigo/E-0MqgwFW6Cw/protegendo-dados-que-vem-do-formulario e no post de Gilberto Albino feito em 19/06/2010 2:28pm.
* @author Josué Cintra josuecintra.desenvolvedor at gmail com
* @version 1.00 24-11-2010 15:50 Criação da classe
*
*/
/*
* Esta classe pode ser ampliada os filtros suportados, colocando outros cases de acordo do o $filterType recebido.
* - lista de filtros http://br.php.net/manual/pt_BR/intro.filter.php
* - exemplo de uso http://br.php.net/manual/pt_BR/function.filter-var-array.php
*/
/* acredito que este é um nome mais condizente pelo que a classe faz */
class FilterData
{
/**
* @param mixed $data array ou string a ser filtrada (dessa forma a classe não fica engessada às superglobais)
* @param string $filterType default: sanitize
*/
public function __construct( $data, $filterType='sanitize' )
{
if(empty($data)) return null;
switch($filterType)
{
case 'sanitize': { return self::SanitizeData($data); break; }
}
}
private static function SanitizeData($data)
{
if(is_array($data)) return filter_var_array($data, FILTER_SANITIZE_STRING);
elseif(is_string($data)) return filter_var($data, FILTER_SANITIZE_STRING);
return null; /* retorna nulo */
}
}
?>