Vulnerabilidade em formulário PHP

Muitas aplicações e a maioria dos sites, qualquer que seja a linguagem em que tenha sido desenvolvido, precisa enviar emails, seja para contato do visitante, para enviar o link para um amigo ou até mesmo como confirmação de um formulário qualquer. Neste pequeno artigo veremos como tornar nossos formulários mais seguros.

[ Hits: 19.515 ]

Por: Jason Bonatelli em 30/05/2007


Principais cuidados



Os cuidados que você precisa tomar no PHP pra não acabar com um problema desses é bem simples. Vamos ver passo a passo como normalmente é feito o envio de emails através do PHP e onde podemos melhorá-lo.

Um formulário típico de contato de algum site, poderia ter a forma abaixo:

<form action="envia.php" method="post">
Nome: <input type="text" name="nome" /><br />
Email: <input type="text" name="email" /><br />
Mensagem: <textarea name="mensagem"></textarea><br />
<input type="submit" />
</form>

Ou seja, com o formulário acima o usuário coloca seu nome, seu email e a mensagem que deseja enviar. Ao se clicar no botão de submit, os dados são passados para o script envia.php, que tem a tarefa de enviar um email com a mensagem do usuário.

Função mail() do PHP

<?php
$para = "equipe@site.com.br";
$assunto = "Contato do site";
$msg = $_POST['mensagem'];
$headers = "From: {$_POST['nome']} <{$_POST['email']}>";
mail($para, $assunto, $msg, $headers);
?>

Tudo muito bonito. O usuário envia seu nome, email e a mensagem e o script PHP manda um email para equipe@site.com.br com o conteúdo do email. Estaria perfeito se não fosse pela montagem do cabeçalho From. O grande problema está em não tratar esses dados que foram enviados pelo usuário. Se o usuário faz o envio normalmente, teríamos um email mais ou menos assim (estou ignorando alguns cabeçalhos para simplificar o exemplo):

From: Jason Bonatelli <jason@bonatelli.net>
To: equipe@site.com.br
Subject: Contato do site

Olá, aqui vai a minha mensagem.

Nesse caso postei meu nome, meu email e a mensagem acima é enviada para a equipe do site. Porém como o usuário tem o controle sobre o que entra no cabeçalho da mensagem, ele pode ser um pouco sacana e colocar uma quebra de linha no nome dele, com algumas coisas depois.

Quebra de linha

Por exemplo, se no lugar do meu nome eu coloco "Buy Viagra <xx@xx.com>\nBcc: <email1@dominio1.com>, <email2@dominio2.com>, <email3@dominio3.com>, " e na mensagem eu coloco algo sobre venda de viagra, teríamos o seguinte email montado:

From: Buy Viagra <xx@xx.com>
Bcc: <email1@dominio1.com>, <email2@dominio2.com>, <email3@dominio3.com>, <bruno@lustosa.net>
To: equipe@site.com.br
Subject: Contato do site

Compre Viagra, baratinho!!

Isso foi apenas um exemplo, mas dá pra combinar outras técnicas e conseguir por exemplo sobrescrever o assunto da mensagem. E hoje em dia já existem robôs vasculhando formulários de sites buscando por vulnerabilidades desse tipo.

Aconteceu em um código antigo da empresa onde estou trabalhando agora. Começamos a entrar em algumas listas negras e sem entender o porque. Quando fomos verificar a fila de emails esperando pra sair do servidor, eram mais de 30 mil spams sobre todo tipo de lixo. E vasculhando os logs do servidor web, chegamos ao script culpado.

É claro que isso NÃO É um problema do PHP. O PHP é tão seguro quanto uma pistola. Se o programador decide dar um tiro no próprio pé, não dá pra colocar a culpa na arma, não é? Esse é apenas mais um exemplo do tipo de problema que podemos enfrentar quando não validamos os dados enviados pelo usuário.

Sempre que qualquer informação for enviada de um lugar não confiável, essa informação deve ser checada. Uma simples verificação em $_POST['nome'], buscando por quebras de linha ou em $_POST['email'], verificando se se trata de um email válido, já resolveria esse problema.

A grande maioria dos problemas que vemos divulgados diariamente em todo tipo de script PHP se baseia no fato de que os programadores não tem o hábito de programar pensando em segurança e não fazem as checagens mais básicas, deixando os scripts vulneráveis a ataques como o descrito acima e outros.

   

Páginas do artigo
   1. Principais cuidados
Outros artigos deste autor
Nenhum artigo encontrado.
Leitura recomendada

Dados sensíveis em arquivos com extensão .inc

Pentesting on PHP apps: XSS

Introdução a manipulação de erros em PHP

Criptografando mensagens com PHP

Segurança: Autenticando o PHP com HTTP (Authentication Required)

  
Comentários
[1] Comentário enviado por jragomes em 30/05/2007 - 11:33h

Bom artigo!! Realmente, em geral nos preocupamos em fazer a coisa funcionar e não em segurança. Isso se deve aos prazos curtos, pressões, etc... a não ser em banco que segurança (ou falta dela) custa muito dinheiro.

Acho que o uso de frameworks para PHP tende a se popularizar e assim, teremos menos estes perigos.

Mas seu artigo fez uma ótima abordagem.

[2] Comentário enviado por leo_mineiro em 31/05/2007 - 08:20h

Excelente artigo, parabéns...

As vulnerabilidades em PHP, bem como em aplicações web em geral são muitas (quando não se programa voltado a segurança).

Para quem quiser se aprofundar em segurança em aplicações web, é interessante participar do projeto OWASP: http://www.owasp.org

O OWASP disponibiliza um guia com as Top 10 vulnerabilidades em aplicações web, um Guia Completo, Guia para Pentests, softwares para segurança, e mais.

[3] Comentário enviado por tchulanguero em 28/11/2008 - 15:19h

Este tipo de erro nem é de uma linguagem específica. A questão é que tratamento de dados deve ser feito sempre, independente de linguagem. Coisa que você resolver criando uma simples função de verificação, por exemplo.

[4] Comentário enviado por Lisandro em 10/07/2009 - 08:22h

Muito Bom. Valeu.

[5] Comentário enviado por filsoldier em 21/06/2010 - 16:07h

Muito bom artigo... Obrigado pela orientação...


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts