Interações entre formulários web e usuários deixam uma porta aberta para inserção de qualquer tipo de dado. Essa possibilidade pode ser ao mesmo tempo o céu ou inferno de um desenvolvedor. Formulários que não possuem controle de dados de entrada correm o sério risco de serem manipulados indevidamente, prejudicando a segurança do sistema.
Injections são uma forma de manipulações mal intencionadas de formulários web e podem atingir desde funções em linguagem de programação até manipulações em banco de dados, correndo o risco de danificar o sistema ou expor dados privados.
Uma maneira de contornar este problema é tratar todos os dados de entrada, independente de qual tipo de componente de formulário ele teve origem.
Como as passagens de dados de uma página para outra é feita através de vetores (POST, GET, SESSION, COOKIE) todos estes vetores devem ser verificados antes dos seus dados serem utilizados.
O primeiro passo é definir uma função que elimine toda entrada de formulário considerada maliciosa, que de uma forma ou de outra poderia prejudicar o sistema. As entradas mais comuns são espaços vazios, configuração de cabeçalho de e-mail como Content-Type e bcc, tags HTML como os sinais de maior e menor, e aspas. Para contornar este problema criamos a seguinte função:
PHP
/**
* @abstract Tratamento de injections em formulários.
* @return string
*/
function antiInjection($str)
{
# Remove palavras suspeitas de injection.
$str =
preg_replace(sql_regcase("/(\n|\r|%0a|%0d|Content-Type:|bcc:|to:|cc:|Autoreply:|from|select|insert|delete|where|drop table|show tables|#|\*|--|\\\\)/"),
"",
$str);
$str =
trim($str);
# Remove espaços vazios. $str =
strip_tags($str);
# Remove tags HTML e PHP. $str =
addslashes($str);
# Adiciona barras invertidas à uma string. return $str;
}
Esta função remove possíveis entradas de dados maliciosas. Tem como parâmetro de entrada um vetor, podendo ser qualquer vetor, desde vetores criados pelo próprio desenvolvedor até vetores próprios da linguagem, como POST, GET, COOKIE e SESSION.
Com a função de tratamento de injection criada, caímos em outro problema: pode haver vetores dentro de vetores. Um exemplo disto seria um select multiple ou um vetor de checkbox. Para tratar isto criamos outra função:
PHP
/**
* @abstract Antes de tratar os injections, verifica se é vetor ou não.
*/
function validaParametro($vetor)
{
{
foreach ($vetor as $chave => $valor)
{
{
$vetor[$chave] = validaParametro($valor);
} else $vetor[$chave] = antiInjection($valor);
}
} else $vetor[$chave] = validaParametro($valor);
return $vetor;
}
Dessa forma, antes de tratar possíveis injections, verifica se o parâmetro passado é um vetor ou não, caso seja um vetor, a função validaParametro() é chamada recursivamente passando o novo vetor como parâmetro, caso não seja um vetor, chama a mesma função passando a string a ser tratada. A chamada à função ficaria da seguinte forma:
PHP
$_POST = validaParametro($_POST);
$_GET = validaParametro($_GET);
Lembrando que qualquer vetor pode ser verificado.