quarta-feira, 16 de janeiro de 2008

Evitar injection em formulários web

Quando se fala em segurança, o que se deve ter em mente é a integridade dos dados no banco de dados e a possível utilização de formulários para fins não esperados.

A função abaixo em PHP é um exemplo simples - não totalmente abrangente e completo - para se evitar injeções de códigos em formulários de sites.

/**
* @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;
}


Para garantir que nenhum dado passado por formulário, seja ele GET ou POST, ou passado via URL (GET), contenha qualquer tipo de código malicioso, deve-se validar todos os valores que são passados. O código a seguir exemplifica como isto pode ser feito. No exemplo é abordado o vetor POST, mas o mesmo pode ser aplicado aos demais vetores, como GET, COOKIE, SESSION, etc.

UPDATE

Como formulários podem conter vetores dentro de vetores (p.e. vetor de checkbox dentro do POST, que é um vetor), adicionei mais uma função que faz essa verificação, ou seja, se existir um vetor dentro de um vetor, para cada valor existente é verificado os injections.

/**
* @abstract Antes de tratar os injections, verifica se é vetor ou não.
*/
function validaParametro($vetor)
{
if (is_array($vetor))
{
foreach ($vetor as $chave => $valor)
{
if (is_array($valor))
{
$vetor[$chave] = validaParametro($valor);
} else $vetor[$chave] = antiInjection($valor);
}
} else $vetor[$chave] = validaParametro($valor);
return $vetor;
}


Para chamar a função basta:
# Para cada entrada de POST, faz a verificação de possíveis injections.
$_POST = validaParametro($_POST);


Caso queira fazer um teste, basta criar um formulário com campos normais e vetores e, ao final dar um var_dump($_POST); para ver o resultado.

A dica de validar vetores internos foi do Anselmo Battisti, meu parceiro de faculdade!