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
(~15 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
(~15 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
(~15 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 */
}
}
?>