<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ataraxia! &#187; segurança</title>
	<atom:link href="http://www.ataraxia.com.br/posts/category/seguranca/feed" rel="self" type="application/rss+xml" />
	<link>http://www.ataraxia.com.br</link>
	<description>O estado da arte em TI</description>
	<lastBuildDate>Sun, 17 Jul 2011 21:36:57 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Evitando SQL injection em PHP</title>
		<link>http://www.ataraxia.com.br/posts/evitando-sql-injection-em-php</link>
		<comments>http://www.ataraxia.com.br/posts/evitando-sql-injection-em-php#comments</comments>
		<pubDate>Thu, 23 Apr 2009 00:13:09 +0000</pubDate>
		<dc:creator>Bruno Lustosa</dc:creator>
				<category><![CDATA[programação]]></category>
		<category><![CDATA[segurança]]></category>
		<category><![CDATA[fieo]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[validação]]></category>

		<guid isPermaLink="false">http://www.ataraxia.com.br/?p=318</guid>
		<description><![CDATA[Em um mundo ideal, todos os desenvolvedores, ao programar seus aplicativos em qualquer linguagem, deveriam se preocupar com segurança, em especial com a validação dos dados. No PHP, isso não é diferente. Uma classe de problemas de segurança bem específica do ambiente web é a chamada SQL Injection, literalmente uma &#8220;Injeção de SQL&#8221;. E embora [...]]]></description>
			<content:encoded><![CDATA[<p>Em um mundo ideal, todos os desenvolvedores, ao programar seus aplicativos em qualquer linguagem, deveriam se preocupar com segurança, em especial com a <a href="http://www.ataraxia.com.br/posts/validacao-de-dados-em-php">validação dos dados</a>. No PHP, isso não é diferente.<br />
Uma classe de problemas de segurança bem específica do ambiente web é a chamada <em>SQL Injection</em>, literalmente uma &#8220;Injeção de SQL&#8221;. E embora a solução seja simples, é preciso que o programador preste atenção, pra evitar que seu aplicativo acabe sendo explorado por uma falha de segurança como esta.</p>
<h2>O problema</h2>
<p>Digamos que na página principal do nosso site, a gente tenha um formulário de login mais ou menos assim:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">form</span> <span style="color: #000066;">action</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;login.php&quot;</span> <span style="color: #000066;">method</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;post&quot;</span>&gt;</span>
Login: <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;login&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
Senha: <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;password&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;senha&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;submit&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">form</span>&gt;</span></pre></div></div>

<p>Um formulário bem simples. E para tratar este formulário, temos o login.php, que vai checar em um banco de dados se o login e a senha estão corretos, da seguinte forma (colocarei apenas o trecho com a consulta SQL relevante):</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$sql</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;SELECT * FROM usuarios WHERE login = '<span style="color: #006699; font-weight: bold;">{$_POST['login']}</span>' AND senha = '<span style="color: #006699; font-weight: bold;">{$_POST['senha']}</span>'&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$res</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sql</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">mysql_num_rows</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$res</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;Login OK&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;Login e senha não conferem&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Ou seja, verificamos na tabela <em>usuarios</em> se temos uma linha com o login e a senha fornecidos. Caso essa consulta retorne alguma coisa, significa que existe uma linha com o login e a senha fornecidos, caso contrário, não existe.<br />
Se no formulário eu preencho o login com &#8220;joe&#8221; e a senha com &#8220;xxxx&#8221;, a seguinte consulta SQL será montada e executada:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> usuarios <span style="color: #993333; font-weight: bold;">WHERE</span> login <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'joe'</span> <span style="color: #993333; font-weight: bold;">AND</span> senha <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'xxxx'</span></pre></div></div>

<p>Porém, o que acontece se eu preecher o formulário com o login = joe, e a senha com:  xxxx&#8217; OR true &#8211;<br />
Neste caso, teremos a seguinte consulta:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> usuarios <span style="color: #993333; font-weight: bold;">WHERE</span> login <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'joe'</span> <span style="color: #993333; font-weight: bold;">AND</span> senha <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'xxxx'</span> <span style="color: #993333; font-weight: bold;">OR</span> <span style="color: #993333; font-weight: bold;">TRUE</span> <span style="color: #808080; font-style: italic;">--'</span></pre></div></div>

<p>Essa consulta vai retornar todas as linhas do banco de dados (por causa do &#8220;OR true&#8221; no final), e como a checagem no código é se a consulta retornou mais de uma linha, estaremos logados.<br />
Existem formas mais sofisticadas de proceder com este tipo de ataque, mas o foco do artigo é na defesa.</p>
<h2>FIEO</h2>
<p><acronym title="Filter Input/Escape Output">FIEO</acronym> é uma técnica bastante usada para aumentar a segurança dos aplicativos web. Significa &#8220;Filter Input/Escape Output&#8221;, ou traduzindo, &#8220;Filtre a Entrada/Escape a Saída&#8221;.<br />
O primeiro passo é a filtragem da entrada, já que a regra número 1 da segurança em aplicativos web diz que não podemos jamais confiar em informações vindas de fontes externas. No nosso caso, poderíamos fazer a filtragem do login e da senha checando se eles possuem apenas caracteres permitidos. Por exemplo, o site poderia ter uma regra especificando que o login deve conter apenas letras e números. A filtragem então, poderia ser feita usando a função <a href="http://br2.php.net/ctype_alnum">ctype_alnum()</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">ctype_alnum</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'login'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;login possúi caracteres inválidos&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Se o <em>FI</em> do FIEO lida com a filtragem da entrada, o <em>EO</em> lida com a manutenção da saída no contexto em que for lida.<br />
Ou seja, <em>FI</em> garante que a nossa entrada é valida, e <em>EO</em> garante que quem quer que receba os nossos dados, irá interpretá-los da forma correta.<br />
No nosso caso, é importante que as aspas simples não sejam interpretadas como delimitadores na consulta SQL. E se eu quisesse ter uma senha que tivesse uma aspa simples no meio?<br />
Existem 3 formas clássicas de se resolver este problema.</p>
<h2>Forma 1: addslashes() no PHP</h2>
<p>É a forma mais simples (e ingênua) de se tratar o problema. Por exemplo, se queremos nos proteger das aspas simples, poderíamos simplesmente escapá-las no PHP da seguinte forma:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$login</span> <span style="color: #339933;">=</span> <span style="color: #990000;">addslashes</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'login'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$senha</span> <span style="color: #339933;">=</span> <span style="color: #990000;">addslashes</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'senha'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Dessa forma, caso uma aspa simples chegasse do usuário, seria devidamente <em>escapada</em> com uma &#8220;\&#8221; antes, e o servidor SQL não iria interpretá-la como um delimitador.<br />
Para o nosso exemplo de ataque, resolveria.<br />
O grande problema com esta solução é que ela só prevê ataques que usem aspas simples. Bancos de dados diferentes podem usar caracteres de controle diferentes, como aspas duplas, quebras de linha, ou outras coisas mais estranhas. E checar por todas estas formas é longe de ser a maneira mais eficaz (e viável!) de se proceder.<br />
Temos uma outra opção, suportada por vários bancos de dados.</p>
<h2>Forma 2: deixar o próprio banco escapar</h2>
<p>A segunda opção é passar a string para o banco e deixar ele se virar. Afinal, ele sabe o que pode e o que não pode entrar em uma string. No MySQL, isso poderia ser feito da seguinte forma:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$login</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'login'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$senha</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'senha'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Segundo a documentação, chamando esta função, o banco escapa automaticamente as seguintes sequencias: \x00, \n, \r, \, &#8216;, &#8221; e \x1a. Ou seja, pelo visto as aspas simples não eram nosso único problema mesmo.<br />
Existem funções semelhantes para outros bancos de dados (por exemplo, <em>pg_escape_string()</em> para o PostgreSQL).<br />
Porém, a solução que considero mais elegante é usar consultas preparadas.</p>
<h2>Forma 3: consultas preparadas</h2>
<p>A idéia de se preparar uma consulta é dizer ao banco de dados o formato da consulta (apenas os parâmetros formais), e fazer a amarração dos parâmetros reais somente na hora da execução.<br />
A maior parte dos bancos de dados suportam consultas preparadas, mas vou mostrar o exemplo usando MySQL, devido a popularidade.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$dbh</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> mysqli<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;localhost&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;ususario&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;senha&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;banco&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$c</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT * FROM usuarios WHERE login = ? AND senha = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$c</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bind_param</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;login&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'login'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$c</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bind_param</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;senha&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'senha'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$c</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Ou seja, primeiro informamos ao banco qual será a consulta a ser executada. Perceba que usamos interrogações no lugar dos parâmetros reais. Com isso, o banco prepara a consulta pra ser executada.<br />
Logo em seguida, dizemos ao banco o valor que cada parâmetro irá receber. Esta etapa se chama amarração (binding). Como o banco de dados sabe o tipo de cada campo, ele também sabe como proceder pra escapar corretamente cada valor.<br />
E por último, executamos a consulta. Simples, fácil e seguro!</p>
<h2>Conclusão</h2>
<p>SQL Injection é um problema sério que afeta muitos aplicativos web por aí afora, porém é um problema que só existe por causa da ingenuidade dos programadores, que não programam pensando em segurança. A solução, como vimos, é bem simples.</p>
<h3  class="related_post_title">Artigos relacionados</h3><ul class="related_post"><li><a href="http://www.ataraxia.com.br/posts/criando-captchas-em-php" title="Criando CAPTCHAs em PHP">Criando CAPTCHAs em PHP</a></li><li><a href="http://www.ataraxia.com.br/posts/seguranca-no-envio-de-emails" title="Segurança no envio de emails em PHP">Segurança no envio de emails em PHP</a></li><li><a href="http://www.ataraxia.com.br/posts/agendando-eventos-no-wordpress" title="Agendando eventos no WordPress">Agendando eventos no WordPress</a></li><li><a href="http://www.ataraxia.com.br/posts/removendo-o-generator-do-wordpress" title="Removendo o &#8220;generator&#8221; do Wordpress">Removendo o &#8220;generator&#8221; do Wordpress</a></li><li><a href="http://www.ataraxia.com.br/posts/escrevendo-plugins-para-o-wordpress" title="Escrevendo plugins para o Wordpress">Escrevendo plugins para o Wordpress</a></li><li><a href="http://www.ataraxia.com.br/posts/otimizacao-de-sites-com-memcached" title="Otimização de sites com memcached">Otimização de sites com memcached</a></li><li><a href="http://www.ataraxia.com.br/posts/os-10-piores-captchas-do-mundo" title="Os 10 piores CAPTCHAs do mundo">Os 10 piores CAPTCHAs do mundo</a></li><li><a href="http://www.ataraxia.com.br/posts/pegadinhas-no-php" title="Pegadinhas no PHP">Pegadinhas no PHP</a></li><li><a href="http://www.ataraxia.com.br/posts/otimizacao-em-php-parte-1-minify" title="Otimização em PHP, parte 1: Minify">Otimização em PHP, parte 1: Minify</a></li><li><a href="http://www.ataraxia.com.br/posts/precedencia-no-php" title="Precedência no PHP">Precedência no PHP</a></li><li><a href="http://www.ataraxia.com.br/posts/evitando-spam-em-formularios" title="Evitando spam em formulários">Evitando spam em formulários</a></li><li><a href="http://www.ataraxia.com.br/posts/imprimindo-em-formularios-continuos-em-php" title="Imprimindo em formulários contínuos em PHP">Imprimindo em formulários contínuos em PHP</a></li><li><a href="http://www.ataraxia.com.br/posts/xml-no-php-com-xml_serializer-parte-2-de-2" title="XML no PHP com XML_Serializer, parte 2 de 2">XML no PHP com XML_Serializer, parte 2 de 2</a></li><li><a href="http://www.ataraxia.com.br/posts/xml-no-php-com-xml_serializer-parte-1-de-2" title="XML no PHP com XML_Serializer, parte 1 de 2">XML no PHP com XML_Serializer, parte 1 de 2</a></li><li><a href="http://www.ataraxia.com.br/posts/envio-de-emails-em-php" title="Envio de emails em PHP">Envio de emails em PHP</a></li><li><a href="http://www.ataraxia.com.br/posts/validacao-de-dados-em-php" title="Validação de dados em PHP">Validação de dados em PHP</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.ataraxia.com.br/posts/evitando-sql-injection-em-php/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Evitando spam em formulários</title>
		<link>http://www.ataraxia.com.br/posts/evitando-spam-em-formularios</link>
		<comments>http://www.ataraxia.com.br/posts/evitando-spam-em-formularios#comments</comments>
		<pubDate>Thu, 29 Jan 2009 11:00:56 +0000</pubDate>
		<dc:creator>Bruno Lustosa</dc:creator>
				<category><![CDATA[email]]></category>
		<category><![CDATA[segurança]]></category>
		<category><![CDATA[spam]]></category>

		<guid isPermaLink="false">http://blog.ataraxia.com.br/?p=177</guid>
		<description><![CDATA[Muitas vezes, nossos sites possuem algum formulário de contato. Algo como um &#8220;Fale Conosco&#8221;, ou alguma outra forma genérica de contato. O importante é que o visitante acessa o formulário, preenche os dados e submete. Normalmente, esses dados são enviados a alguem por email. Até aí, tudo muito bonito. Funciona muito bem. Porém, os spammers [...]]]></description>
			<content:encoded><![CDATA[<p>Muitas vezes, nossos sites possuem algum formulário de contato. Algo como um &#8220;Fale Conosco&#8221;, ou alguma outra forma genérica de contato. O importante é que o visitante acessa o formulário, preenche os dados e submete. Normalmente, esses dados são enviados a alguem por email.</p>
<p>Até aí, tudo muito bonito. Funciona muito bem. Porém, os spammers acharam uma forma de propagar links para sites de origem duvidosa através destes formulários. Então, bolaram robôes que varrem a Internet em busca de formulários como estes. Ao encontrar um formulário, preenchem automaticamente todos os campos, e submetem os dados.</p>
<p>O resultado disso é o recebimento de várias mensagens inúteis com links muitas vezes utilizados pra disseminar vírus e outras ameaças.</p>
<p>Uma das formas de se resolver isso é colocando um <acronym title="Completely Automated Turing Test To Tell Computers and Humans Apart">CAPTCHA</acronym>, aquelas imagens com letras tortas que teoricamente só um humano consegue decifrar. Alguns dos problemas com os CAPTCHAs: as vezes, o CAPTCHA é fraco, e é possível se usar um programa para quebrá-lo. Já aconteceu algumas vezes com serviços grandes, como Hotmail e Gmail. Outro problema, é que as vezes as letras ficam tão tortas que nem um humano consegue decifrar de primeira. Eu mesmo já tentei fazer um cadastro no BOL, e só consegui lá pra quarta ou quinta tentativa.</p>
<p>Uma outra forma, mais simples, consiste em se colocar no formulário um campo escondido via CSS. O formulário ficaria mais ou menos assim:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">form</span> <span style="color: #000066;">action</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/email/send&quot;</span> <span style="color: #000066;">method</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;post&quot;</span>&gt;</span>
Nome: <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;nome&quot;</span> <span style="color: #66cc66;">/</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">br</span> <span style="color: #66cc66;">/</span>&gt;</span>
Email: <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;email&quot;</span> <span style="color: #66cc66;">/</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">br</span> <span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;vazio&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #000066;">style</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;display:none&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;submit&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Enviar&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">form</span>&gt;</span></pre></div></div>

<p>Notem que o formulário possui um campo chamado <em>vazio</em>, que está escondido através do estilo &#8220;<em>display:none</em>&#8220;. A técnica é simples: o script que processa o post do formulário, verifica se este campo está preenchido ou não. Se estiver, muito provavelmente se trata de um robô fazendo spam, já que a princípio este campo não deveria nunca ser exibido na tela, e portanto não poderia ser preenchido.</p>
<p>Embora não seja 100% eficaz e peque um pouco pela falta de acessibilidade (já que dependendo do dispositivo que acesse o celular, o campo pode aparecer), ainda assim se trata de mais uma opção, ao meu ver, menos obstrusiva que um CAPTCHA.</p>
<p>NOTAS:</p>
<ul>
<li>O HTML acima está simples, sem seguir nenhum padrão, só para efeitos de demonstração da técnica. Deveria usar tags como &lt;fieldset&gt; e &lt;label&gt; para manter o formulário bonitinho;</li>
<li>O <em>style</em> não deveria estar explícito no campo, e sim externo em um CSS, setando o display pra hidden ou através de uma classe ou através de um ID.</li>
</ul>
<p>Já faço uso desta técnica em alguns sites que recebiam um volume considerável de spam automático, e hoje o nível caiu pra 0.</p>
<p>Outro aspecto do envio de email que também é extramamente importante é em relação ao <a href="http://www.ataraxia.com.br/posts/seguranca-no-envio-de-emails">spam envolvendo a manipulação dos cabeçalhos do email</a>, como já descrito em um outro artigo.</p>
<h3  class="related_post_title">Artigos relacionados</h3><ul class="related_post"><li><a href="http://www.ataraxia.com.br/posts/envio-de-emails-em-massa" title="Envio de emails em massa">Envio de emails em massa</a></li><li><a href="http://www.ataraxia.com.br/posts/evitando-fornecer-seu-email-verdadeiro" title="Evitando fornecer seu email verdadeiro">Evitando fornecer seu email verdadeiro</a></li><li><a href="http://www.ataraxia.com.br/posts/seguranca-no-envio-de-emails" title="Segurança no envio de emails em PHP">Segurança no envio de emails em PHP</a></li><li><a href="http://www.ataraxia.com.br/posts/evitando-sql-injection-em-php" title="Evitando SQL injection em PHP">Evitando SQL injection em PHP</a></li><li><a href="http://www.ataraxia.com.br/posts/criando-captchas-em-php" title="Criando CAPTCHAs em PHP">Criando CAPTCHAs em PHP</a></li><li><a href="http://www.ataraxia.com.br/posts/os-10-piores-captchas-do-mundo" title="Os 10 piores CAPTCHAs do mundo">Os 10 piores CAPTCHAs do mundo</a></li><li><a href="http://www.ataraxia.com.br/posts/envio-de-emails-em-php" title="Envio de emails em PHP">Envio de emails em PHP</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.ataraxia.com.br/posts/evitando-spam-em-formularios/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

