Evitar Mail Injection em PHP

May 26th, 2007

Bom pessoal, eu vou falar sobre um assunto que não é muito discutido e que muitos programadores até ignoram. O Mail Injection, que é uma forma de burlar um sistema de envio de e-mails em PHP, normalmente enviando spans a partir do servidor no qual o sistema esteja instalado. Isto pode denegrir a imagem de uma empresa, dentre outros problemas. Para saber mais, visite esta wiki que explica melhor.

Para começar vamos explicar o funcionamento da função mail(), a qual é nativa do php. Ela tem cinco parâmetros:

  • to > Endereço que irá receber o e-mail;
  • subject > Assunto da mensagem;
  • message > O corpo da mensagem;
  • additional_header > cabeçalhos adicionais(Com Cópia, Cópia Oculta, dentre outros cabeçalhos);
  • additional_parameters > usado para passar parametros para o programa que gerencia os e-mails.

Dentre estes campos, nós vamos nos preocupar com o to, o subject e o additional_header. Visto que os três são usados para incluir dados ao cabeçalho do e-mail.

Vamos a um exemplo, onde será mostrada a mensagem produzida pela execução da função mail:

mail('meiocodigo@gmail.com',$_GET['subject'],$_GET['message'],"From: ".$_GET['from']);

A função acima é largamente utilizada, visto que ele pega de um formulário o assunto, a mensagem e o remetente e envia por e-mail para um endereço fixo definido pelo progrador. Vamos supor que os valores de $_GET sejam como abaixo:

$_GET['subject'] = 'Post sobre Mail Injection';
$_GET['message'] = 'Pode tirar uma dúvida sobre o post sobre mail injection...';
$_GET['from'] = 'alguem@algumemail.com';

A mensagem produzida pela função supra-citada seria:

To: meiocodigo@gmail.com
Subject: Post sobre Mail Injection
From: alguem@algumemail.com

Pode tirar uma dúvida sobre o post sobre mail injection…
Note que o formato gerado é:

To: $to
Subject: $subject
$additional_headers

$message

Até aqui está tudo certo, nenhum problema com o nosso código. Mas imagine se alguem insere o seguinte valor para Subject: ‘Assunto%0ACc: outro@email.com%0ABcc: maisoutro@email.com’. Essa String tem o mesmo valor que:


Assunto
Cc: outro@email.com
Bcc: maisoutro@email.com

Colocando isso no texto criado pela função mail nós temos:


To: meiocodigo@gmail.com
Subject: Assunto
Cc: outro@email.com
Bcc: maisoutro@email.com
From: alguem@algumemail.com

Pode tirar uma dúvida sobre o post sobre mail injection…
Note que o arquivo gerado tem mais 2 itens no cabeçalho: um email para ser enviado como cópia; e outro como cópia oculta. É dessa forma que o formulário de e-mail é usado para fazer ataques de span. O detalhe é que o cabeçalho tem como separador a quebra de linha, ou seja, só é considerado um novo item do cabeçalho caso haja uma quebra de linha. Isso justifica o uso do %0A, que é o código hexadecimal da quebra de linha.

O que foi explicado acima se aplica a qualquer um dos três campos citados que fazem parte do cabeçalho.

Para resolver isso, eu criei uma função que checa se existem caracteres de quebra de linha nas strings de cabeçalho, retornando false, caso encontre:


function check_mail_injection($string){
if(strpos($string,'\n') !== false) return false;
if(strpos($string,'\r') !== false) return false;
if(strpos($string,'%') !== false) return false;
return true;
}

Quero dedicar os créditos dessa função ao meu amigo Edson Aníbal da Superintendência de Informática da UFRN, que foi quem fez o procedimento, eu apenas encapsulei em uma função.

Vamos entender a função, ela pega uma $string, e verifica a existência de um caractere ‘\n’, ‘\r’ ou ‘%’. Os dois primeiros representam quebra de linha. E o ‘%’ pode ser usado para representar o código hexadecimal da quebra de linha.

Só mais um detalhe, não é recomendável aplicar essa função ao corpo da mensagem, visto que a mesma pode conter quebras de linha.

Espero ter sido claro. Qualquer dúvida coloca nos comentários.

Biblioteca AJAX

May 23rd, 2007

Bem… Começarei os posts sobre AJAX com esse “esqueleto” de uma biblioteca, orientada a objeto, para aplicações em AJAX.
O código abaixo deve ser colocado em um arquivo “max_ajax.js” ou outro nome de sua escolha. Mas no final desse comentário eu anexei os 3 arquivos citados aqui neste post.

/**
 * @author Fábio Miranda Costa - www.meiocodigo.com
 * @version 0.26
 * Pequena biblioteca para uso geral em Ajax.
 * bugs conhecidos: Não conversa muito bem com tabelas.
 * Testado com IE 6 e firefox 2.
 * Qualquer dúvida mande e-mail para meiocodigo@gmail.com ou simplesmente comente.
 */

if(typeof window.max === "undefined") var max = new Object();

Esse inicio apenas verifica a existência do objeto max antes de criá-lo para ser possível acrescentar mais de uma das bibliotecas max.
Aos poucos eu irei postando outras bibliotecas que eu fiz para não ficar com muito conteúdo em um só post.

Métodos

Construtor

/**
 * Construtor da classe max.Ajax
 *
 * @param {String} url - a url do arquivo que receberá a chamada ajax
 * @param {Object} options - um objeto que conterá as possíveis opções, entre elas estão:
 * update (opcional) - um id de um nó DOM que receberá a resposta do servidor.
 * onComplete (opcional) - função que será executada logo após o servidor ter respondido ao pedido.
 *
 */
max.Ajax = function(url,options){

Este é o método construtor da classe max.Ajax. Como ele podemos inicializar as variáveis usadas internamente em um objeto desta classe.
Se você quizer aprender alguma coisa sobre Javascript e orientação a objeto vá para o site www.w3schools.com que é um site excelente para iniciantes, aprendi muita coisa lá no inicio.

Bem voltando ao código inicialmente temos a declaração do construtor como sendo uma função que faz as seguintes coisas:

this.xmlHttp = this.createXMLHttp();//criação do objeto que tratará da nossa requisição ao servidor

Cria um XMLHttpObject para fazer as requisições assincronamente ao servidor.

this.url = url;

Inicializa a variável url pertencente a classe com o primeiro valor passado por parâmetro na inicialização do objeto. Este valor deve ser a url para o arquivo que deve ser enviada a requisição Ajax.

this.update = options.update || null;//se não for definida um id para fazer o update, this.update = null, caso contrário this.update = options.update

Inicializa a variável update pertencente a classe com o valor de options.update se esta for declarada ou inicializa ela com null se não tiver sido declarada. Este valor deve ser o id de algum nó DOM no seu HTML, este nó receberá o conteúdo que foi retornado pelo arquivo que recebeu a requisição Ajax. (complicado? :S)

this.onComplete = options.onComplete || function(){};//se tiver sido definida uma função para ser executado ao final da requisição então this.onComplete = options.onComplete senão this.onComplete = null;
};

Inicializa a variável onComplete pertencente a classe com o valor de option.onComplete, que deve ser sempre uma função. A função que for passada por parâmetro nesse caso será executada logo após a requisição Ajax ser finalizada.

Requisição Ajax por GET

max.Ajax.prototype = Object({
	/**
	 * Método para enviar pedido get.
	 */
	get:
		function(){

Este é o método de envio de uma requisição Ajax usando GET.

var thisObj = this;//fazendo referência a este objeto

Inicializamos a variável thisObj com o valor “this”.
Você deve estar pensando: “que babaca… pra que isso?”. Calma eu vou explicar depois por que inicializei essa variável dessa forma.

this.xmlHttp.onreadystatechange = function(){thisObj.updateFunc();};//esta linha define qual será a função que será executada quando nosso objeto xmlHttp tiver seu estado modificado, no caso updateFunc()

Aqui nós definimos um método ( “updateFunc()” ) que será executado toda vez que o estado do nosso XMLHttpObject mudar. Existem no máximo 5 possíveis valores para o estado, dependendo do browser.

  • Estado 0 - A requisição assíncrona com o servidor não foi iniciada
  • Estado 1 - A requisição foi inicializada
  • Estado 2 - A requisição foi enviada
  • Estado 3 - A requisição está sendo processsada
  • Estado 4 - A requisição foi completada, com sucesso ou não.

Agora vem a explicação do por que inicializar a variável thisObj com “this”. Se eu tivesse feito essa mesma linha dessa forma:

this.xmlHttp.onreadystatechange = function(){this.updateFunc();};

vocês acham que funcionaria?
A resposta é não, por que o “this” neste caso está se referindo ao “this.xmlHttp” por estar dentro de seu escopo, por isso eu fiz uma atribuição ao max.Ajax (var thisObj = this;) e usei ele dentro do escopo do “this.xmlHttp”.

this.url += (this.url.indexOf("?") === -1)?"?":"&";
this.url += "ridwes="+Math.random();//adicionando uma variável randomica ao nosso get para que resolva um problema de cache que acredito que só aconteça no IE, chamei de ridwes por que acredito que ninguem teria uma variavel com esse nome, mas se for o caso...modifique hehe

Essas duas linhas acrescentam uma variável “ridwes” à nossa requisição. Esse nome eu escolhi arbitrariamente achando que ninguem escolheria tal nome para uma variável mas se você tiver escolhido então modifique o nome de sua variável ou modifique o código.
O objetivo de adicionar essa variável com valor randômico é de evitar problemas de cache que acontecem freqüentemente no IE.

this.xmlHttp.open("get",this.url,true);//define que o método usado para a nossa requisição será o 'get', a url do arquivo que receberá a requisição e o true indica que a chamada será assincrona.

Aqui temos, como o nome diz, a abertura de uma conexão com o servidor. O primeiro parâmetro da função open é o método utilizado para a comunicação (”get” ou “post”), o segundo é a url para o arquivo que receberá a chamada do browser, podem ser incluidas variáveis juntamente com ela, e o terceiro é um valor booleano que indica se a chamada será assíncrona (true) ou síncrona (false).

this.xmlHttp.send(null);//finalmente envia nosso pedido
},

E finalmente enviamos a chamada ao servidor, passando null como parametro. Veremos futuramente que se tivessemos usando o método “post” as variáveis seriam passadas por parâmetro ao invez do null.

Update nó DOM

	/**
	 * Método executado toda vez que o xmlHttp mudar de estado.
	 */
	updateFunc:
		function(){

Esta função, como já foi visto neste mesmo post, é executada no evento “readystatechange” do nosso objeto xmlHttp.

if (this.xmlHttp.readyState==4 || this.xmlHttp.readyState=="complete"){//verifica se o estado do xmlHttp é de completo, ou seja se a resposta do servidor já está "em mãos"
	if (this.xmlHttp.status == 200){//verifica se o estatus do objeto é de sucesso, caso contrario o ideal seria mostrar um erro, mostrarei isso no futuro
		if (this.update){
			document.getElementById(this.update).innerHTML = this.xmlHttp.responseText;//joga o texto de resposta do servidor dentro do nó DOM especificado na opção update, se ela existir
		}
		this.onComplete(this.xmlHttp.responseText,this.xmlHttp.responseXML);//executa a função ao final da chamada ajax, também chamada de callback
	}
}
},

Resolvi comentar todas essas linhas juntas porque são muitos “ifs”, um dentro do outro, pode acabar confundindo alguem.
A primeira linha é uma condição que verifica se a propriedade “readyState” do objeto xmlHttp está em seu estado final, ou seja, que a requisição ao servidor já retornou.
A segunda linha verifica se a propriedade estatus, do mesmo objeto xmlHttp, indica sucesso (o número 200 quer dizer que o servidor não retornou nenhuma mensagem de erro, no futuro veremos outros números e o que cada um deles representa).
A terceira linha verifica se foi passado por parâmetro algum id ao se criar um objeto max.Ajax, se tiver passado, na quarta linha o nó DOM com esse id receberá o responseText, ou seja, o texto de resposta do arquivo que chamamos em nossa requisição Ajax.
E finalmente na sexta linha temos a execução do método que foi passado por parâmetro no onComplete.
Se você não estiver entendendo muito bem veja o exemplo logo no final desse post que irá esclarecer melhor como essa biblioteca funciona.

Criação de objeto XMLHttp

	/**
	 * Copiado na cara de pau, peguei de um artigo no Wrox.
	 * Método usado para a criação do objeto XMLHttp, peça chave para o ajax.
	 * Não explicarei em detalhes.
	 */
	createXMLHttp:
		function(){
			if(typeof XMLHttpRequest != "undefined")//entra em todos os navegadores menos o IE
		        return new XMLHttpRequest();
			else if (window.ActiveXObject) {//no caso do IE
		      var aVersions = [ "MSXML2.XMLHttp.5.0","MSXML2.XMLHttp.4.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp","Microsoft.XMLHttp"];
		      //por cima, o que ela faz é verificar qual a versão mais recente do xmlHttp Object suportada pelo navegador e retorna o objeto
			  for (var i = 0; i < aVersions.length; i++) {
		        try{
		            var oXmlHttp = new ActiveXObject(aVersions[i]);
		            return oXmlHttp;
		        }catch (oError){}
		      }
		    }
			throw new Error("Objeto XMLHttp não pode ser criado.");
		}
});

Não falarei dessa função em detalhes, apenas coloquei alguns comentários aí no código. Mas basicamente essa função cria o objeto xmlHttp.

O código já está com comentários nas linhas mais importantes.
Criei um arquivo para testar a biblioteca com todas as opções possíveis.
Você pode copiar este texto em um arquivo HTML qualquer ou simplesmente baixar os arquivos anexados ao post.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type="text/javascript" src="max_ajax_ref_blog.js" ></script>
<script type="text/javascript">
function testeAjax(thisObj){

var url = "teste.php";//criando uma string cujo valor corresponde à url do arquivo que receberá a requisição Ajax
url += "?valor_teste="+thisObj.innerHTML;//adicionando a variável "valor_teste" à url

var maxAjaxObj = new max.Ajax(url,{update:"teste",onComplete:
function(texto,xml){
alert("O innerHTML é:"+texto);
}
});//aqui estamos criando um objeto max.Ajax passando ao construtor como parâmetros uma url e um objeto com uma propriedade "update"
//cujo valor é o id "teste" indicando que o nó com id="teste" receberá o texto de resposta do servidor, depois temos o onComplete
//que é uma função e será executada logo após a resposta com sucesso do servidor
maxAjaxObj.get();//execução do método get para a nossa chamada Ajax.
}
window.onload = function(){//as função que estão dentro desse escopo só são executadas após todo o carregamento do site
document.getElementById("link_teste").onclick = function(){
		testeAjax(this);
		return false;
	};//aqui nós estamos dizendo que o nó com id="link_teste" escutará esta função no evento "onclick"
}

</script>
</head>

<body>
<a id="link_teste" href="#">Texto para testar :D</a>
<div id="teste"></div>
</body>
</html>

O que esse código faz é enviar um pedido para o arquivo “teste.php” passando por get as variáveis ridwes com valor randomico (explicado no código) e a variável valor_teste que terá como valor a string “Texto para testar :D”.

meu arquivo teste.php ficou:

<?php
echo $_GET["valor_teste"];
?>

ou seja a resposta do servidor será exatamente o valor da variável “valor_teste” que é “Texto para testar :D”.

Traduzindo tudo, quando clicamos no link a requisição ao servidor é enviada quando o browser recebe a resposta da requisição um alerta é mostrado com o texto: “O innerHTML é: Texto para testar :D” e a div de id “teste” receberá também o mesmo texto de reposta do servidor (”Texto para testar :D”) por que eu coloquei como uma de minhas opções update:”teste”.

Espero ter sido claro =/

Qualquer dúvida comente por favor!! :D

Arquivos:

Pegar valor atual de uma sequência em PostgreSQL

May 20th, 2007

Neste post, vamos falar de como pegar o ultimo valor de uma sequência de PostgreSQL. Para entender melhor o que são sequências, veja uma aplicação delas no post Auto-incremento em PostgreSQL.

Uma das grandes aplicações do valor atual de uma sequência é a garantia de um banco relacional. Um registro que seja subdivido em várias entidades de um banco de dados precisa que a chave do registro seja passada com chave estrangeira para os diferentes registros nas diferentes entidades.

Para obter o valor atual de uma sequência(que teoricamente foi usado no ultimo registro, caso seja seguido o artigo citado acima) é usada a funcao currval. Como mostra o código abaixo:

SELECT currval('nome_da_sequencia');

Bem, é isso. Qualquer dúvida deixa como comentário.

Case-insensitive em PostgreSQL

May 19th, 2007

Hoje vamos falar de comparação de strings no PostgreSQL. Especificamente sobre a sensibilidade a caixa(maiúsculas e minúsculas), o que um grande empecilho à criação de sistemas de busca.

Este também foi outro grande problema que eu enfrentei. O operador LIKE é case-sensitive(sensivel a maiúsculas e minúsculas).

A solução foi simples e rápida. Existe um operador chamado ILIKE, o qual é case-insensitive.

Exemplo:

SELECT nome FROM empregado WHERE nome ILIKE ‘vinicius’;

O código acima retorna todos os registros onde o nome seja ‘vinicius’, ‘Vinicius’, ‘ViNiCiUs’, etc.

A sensibilidade à acentuação é um pouco mais complicada então vamos deixar para um próximo post.

Espero ter ajudado.

Auto-Incremento em PostgreSQL

May 18th, 2007

Neste post falarei a respeito de uma das dificuldades em se usar o gerenciador de banco de dados PostgreSQL. Uma das diferenças mais notáveis aos iniciantes no assunto: a falta da propriedade Auto-increment, a qual é largamente usada na criação de chaves primárias.

Para resolver esta falta, seguem abaixo duas formas de simular a mesma propriedade no PostgreSQL:

Para se criar um campo de uma tabela com valores sequenciais(adequado para chaves) existem duas formas. Uma delas leva a outra.

Vamos comecar pela mais simples, criar a sequencia no momento da criaçao da tabela através do tipo SERIAL:

CREATE TABLE pessoa
(id SERIAL PRIMARY KEY,
nome VARCHAR(100));

A forma acima simula o que eu vou exemplificar abaixo, a criação da sequencia manualmente:

CREATE SEQUENCE pessoa_id_seq;

CREATE TABLE pessoa
(id INTEGER PRIMARY KEY DEFAULT nextval(’pessoa_id_seq’),
nome VARCHAR(100));

Atente para a igualdade entre o nome da sequencia e o parametro passado para a função nextval.

Bem, é isso, espero ter ajudado.