<?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>Rafael Bernard Araujo &#187; PHP</title>
	<atom:link href="http://rafael.bernard-araujo.com/categoria/tecnologia/programacao-tecnologia/php-programacao-tecnologia-tecnologia/feed" rel="self" type="application/rss+xml" />
	<link>http://rafael.bernard-araujo.com</link>
	<description>desenvolvendo... while(!success){  try(); }</description>
	<lastBuildDate>Wed, 25 Jan 2012 01:00:20 +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>Segurança no PHP&#160;II</title>
		<link>http://rafael.bernard-araujo.com/seguranca-no-php-ii.php</link>
		<comments>http://rafael.bernard-araujo.com/seguranca-no-php-ii.php#comments</comments>
		<pubDate>Fri, 16 Sep 2011 05:06:55 +0000</pubDate>
		<dc:creator>rafael</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[cookie]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[register globals]]></category>
		<category><![CDATA[segurança]]></category>
		<category><![CDATA[sessão]]></category>

		<guid isPermaLink="false">http://rafael.bernard-araujo.com/?p=846</guid>
		<description><![CDATA[Requisito 4: Sem erros para o usuário Falaremos aqui de outro ponto importantíssimo na questão de segurança que é freqüentemente ignorado pelos desenvolvedores: as mensagens de erro. As mensagens de erro foram feitas para que o desenvolvedor possa trabalhar de forma mais prática e descobrir o que ele está fazendo de errado. Observem, entretando, que, [...]]]></description>
			<content:encoded><![CDATA[<!-- boo-widget start -->
          <script type="text/javascript">
            bb_keywords = "cookie";
            bb_bid  = "1613262";
            bb_lang = "pt-BR";
            bb_name = "custom";bb_limit = "9";bb_format = "bbo";
          </script>
          <script type="text/javascript" src="http://widgets.boo-box.com/javascripts/embed.js"></script>
          <!-- boo-widget end --><p><strong>Requisito 4: Sem erros para o usuário</strong></p>
<p>Falaremos aqui de outro ponto importantíssimo na questão de segurança que é freqüentemente ignorado pelos desenvolvedores: as mensagens de erro.</p>
<p>As mensagens de erro foram feitas para que o desenvolvedor possa trabalhar de forma mais prática e descobrir o que ele está fazendo de errado. Observem, entretando, que, quando uma aplicação atinge maturidade suficiente para &#8220;entrar em produção&#8221;, torna-se imperativo que o usuário não visualize mensagens de erro.</p>
<p>A razão disso é muito simples: as mensagens de erro freqüentemente trazem informações sensíveis. Observe como exemplo uma típica mensagem de falha de conexão com a base de dados:</p>
<p><code>Warning: <span style="color: #ff0000;">mysql</span>_connect() [function.mysql-connect]:<br />
Access denied for user '<span style="color: #ff0000;">foo</span>'@'<span style="color: #ff0000;">localhost</span>' (using password: YES)<br />
in <span style="color: #ff0000;">/usr/local/apache/htdocs/script.php</span> on line 2<br />
</code><br />
Note, através das partes destacadas, que esta mensagem me informa:</p>
<ol>
<li>O tipo de RDBMS: mysql</li>
<li>O usuário de conexão com a base: foo</li>
<li>Que este usuário está tentando uma conexão de dentro do servidor: localhost</li>
<li>O caminho absoluto da raiz web: /usr/local/apache/htdocs</li>
<li>O nome do script: script.php</li>
</ol>
<p>É por isso que, quando colocamos uma aplicação em produção, ocultamos as mensagens de erro e as gravamos diretamente em um arquivo de log. Isto é muito simples de implementar:</p>
<p>Exemplo:</p>
<p><code>display_errors = Off<br />
log_errors = On<br />
error_log = /log/php_errors.log<br />
</code><br />
<strong>Requisito #5: Esconda do servidor web o que ele não precisa acessar</strong></p>
<p>Quantos de nós não usamos em nossas aplicações um arquivo, tipicamente chamado de config.php ou setup.php, onde guardamos, por exemplo, usuário e senha da base de dados?</p>
<p>Não há nada de errado nisso, mas cuidado: se este arquivo não gera saída de informação em HTML, por que deixá-lo acessível via web?</p>
<p>Para esclarecermos o problema, vamos definir 3 coisas:</p>
<ol>
<li>minha raiz web é: /usr/local/apache/htdocs</li>
<li>meu arquivo de configuração fica localizado em /usr/local/htdocs/config/config.php</li>
<li>este é um código típico que usa este arquivo:</li>
</ol>
<p><code>require_once("/urs/local/htdocs/config/config.php");<br />
/* bla bla bla */<br />
</code><br />
Observe que o erro neste caso é confundir interpretador PHP e servidor web. O Apache (ou IIS, Xitami etc) não precisa saber onde está este arquivo. Isto é responsabilidade do interpretador.</p>
<p>Outro problema é que se arquivo fica desnecessariamente exposto, afinal de contas basta eu abrir um navegador e digitar:</p>
<p>http://www.meusite.com.br/config/config.php</p>
<p>Não faz sentido. Por mais que você possa argumentar que não há forma de ler o código-fonte deste arquivo, ainda assim, isto não muda o fato de que ele está desnecessariamente exposto.</p>
<p>A solução é simples: movemos o arquivo para fora da raiz web:</p>
<p>/usr/local/config/config.php</p>
<p>E depois apenas acertamos as permissões e corrigimos nosso código:</p>
<p><code>require_once("/urs/local/config/config.php");<br />
/* bla bla bla */<br />
</code><br />
A partir de agora nosso arquivo de configuração só pode ser lido por quem precisa dele: o interpretador PHP.</p>
<p><strong>Requisito #6: Use criptografia</strong></p>
<p>Dados sigilosos são chamados assim por um motivo. Quando tratamos especificamente de senhas é impressionante a quantidade de aplicações web que gravam senhas em texto puro na base de dados.</p>
<p>Ora, se a senha possui a importância que tem e quem a escolhe é o usuário, por que alguém mais precisa ler essa senha?</p>
<p>Se a senha possui este peso em nossa aplicação, não podemos nos dar o luxo de fazer com que ela trafegue pela aplicação totalmente exposta.</p>
<p>PHP implementa criptografia de várias formas, mas eu sugiro &#8211; para quem puder usar, pois exige instalação e configuração extra &#8211; a utilização da função <code>mcrypt</code>.</p>
<p>Os <em>hashes</em> MD5 e SHA-1 são opções válidas, mas o problema é a sua fragilidade: para o MD5 existe até dicionário de dados, enquanto o SHA-1 foi recentemente &#8220;quebrado&#8221; por um pesquisador chinês.</p>
<p><strong>Conclusão</strong></p>
<p>A implementação de regras básicas de segurança depende apena da boa vontade do desenvolvedor. Você deve ter percebido como a maior parte das soluções aqui apresentadas significam simples mudanças de hábito.</p>
<p>É mais do que tempo de nós, desenvolvedores PHP, deixarmos de lado nossos antigos vícios e começarmos a implementar boas práticas de programação.</p>
<p>Ganha o profissional, ganha a sua aplicação, ganha o seu cliente, ganha o mercado. Só quem perde nessa situação é quem tenta se aproveitar de nossa aplicação.</p>
<p><strong>Referências e links sugeridos</strong></p>
<p>[PHP Security Consortium] &#8211; <a class="extlink" href="http://phpsec.org/" target="_blank">http://phpsec.org/</a><br />
[PHP RS] &#8211; <a class="extlink" href="http://www.phprs.com.br/" target="_blank">http://www.phprs.com.br/</a></p>
<blockquote><p>Er Galvão Abbott trabalha há mais de dez anos com programação de websites e sistemas corporativos com interface web. Autodidata, teve seu primeiro contato com a linguagem HTML em 1995, quando a internet estreava no Brasil. Atualmente, além de lecionar em diversos cursos, tem se dedicado ao desenvolvimento de sistemas baseados na web, tendo nas linguagens PHP, Perl e JavaScript suas principais paixões.</p></blockquote>
<p><a title="Segurança no PHP" href="http://rafael.bernard-araujo.com/seguranca-no-php.php">Parte I</a></p>
]]></content:encoded>
			<wfw:commentRss>http://rafael.bernard-araujo.com/seguranca-no-php-ii.php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Enviando mensagens com o&#160;PHPMailer</title>
		<link>http://rafael.bernard-araujo.com/enviando-mensagens-com-o-phpmailer.php</link>
		<comments>http://rafael.bernard-araujo.com/enviando-mensagens-com-o-phpmailer.php#comments</comments>
		<pubDate>Wed, 20 Jul 2011 16:55:26 +0000</pubDate>
		<dc:creator>rafael</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[e-mail]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://rafael.bernard-araujo.com/?p=784</guid>
		<description><![CDATA[O PHPMailer é um componente de envio de e-mail para servidores que exigem autenticação ou para um desenvolvedor que deseje configurações mais avançadas para a rotina de e-mail pelo php que o a função mail() não possua. É importante percebermos que um servidor que exige autenticação o faz por razões de segurança, para que o [...]]]></description>
			<content:encoded><![CDATA[<!-- boo-widget start -->
          <script type="text/javascript">
            bb_keywords = "e-mail";
            bb_bid  = "1613262";
            bb_lang = "pt-BR";
            bb_name = "custom";bb_limit = "9";bb_format = "bbo";
          </script>
          <script type="text/javascript" src="http://widgets.boo-box.com/javascripts/embed.js"></script>
          <!-- boo-widget end --><p>O <a title="PHPMailer" href="http://phpmailer.codeworxtech.com/">PHPMailer</a> é um componente de envio de e-mail para servidores que exigem autenticação ou para um desenvolvedor que deseje configurações mais avançadas para a rotina de e-mail pelo php que o a função <em>mail()</em> não possua. É importante percebermos que um servidor que exige autenticação o faz por razões de segurança, para que o mesmo não caia nas <a title="Estatísticas de Spam relatadas ao cert.br" href="http://www.antispam.br/estatisticas/">listas negras caracterizado como um servidor de Spams</a>.</p>
<p>A seguir, um exemplo de código para envio de e-mail pelo PHPMailer (para páginas de Contato ou Fale Conosco, por exemplo).</p>
<p>Obs: O ideal é que você baixe o PHPMailer e coloque no seu próprio servidor, deixando com que o seu domínio sempre tenha independência e rapidez no envio de mensagens através das suas páginas.</p>
<p><script src="https://gist.github.com/1095355.js"> </script></p>
<p>Relacionados:</p>
<ul>
<li><a href="http://noticias.aspecto.net/index.php/pagina-de-contato-usando-o-aspemail.html">Página de contato usando o AspEmail</a></li>
<li><a title="Página de contato usando o ASP.Net" href="http://noticias.aspecto.net/index.php/pagina-de-contato-em-aspnet.html">Página de contato usando o ASP.Net</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://rafael.bernard-araujo.com/enviando-mensagens-com-o-phpmailer.php/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tropeçando&#160;11</title>
		<link>http://rafael.bernard-araujo.com/tropecando-11.php</link>
		<comments>http://rafael.bernard-araujo.com/tropecando-11.php#comments</comments>
		<pubDate>Fri, 25 Sep 2009 14:39:58 +0000</pubDate>
		<dc:creator>rafael</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Segurança]]></category>
		<category><![CDATA[Tropeçando]]></category>
		<category><![CDATA[armazenamento]]></category>
		<category><![CDATA[código-aberto]]></category>
		<category><![CDATA[pdf]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[segurança]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://rafael.bernard-araujo.com/?p=301</guid>
		<description><![CDATA[pdftk &#8211; the pdf toolkit Bem vindo &#124; HDFree Brasil Hospedagem de páginas gratuitas Dividindo dados em colunas &#8211; Mauro Pichiliani &#8211; SQL Server yfrog &#8211; Share your images/videos on Twitter! Media Converter &#8211; the fastest free online audio and video converter Top 100 Open Source Security Tools]]></description>
			<content:encoded><![CDATA[<!-- boo-widget start -->
          <script type="text/javascript">
            bb_keywords = "código-aberto";
            bb_bid  = "1613262";
            bb_lang = "pt-BR";
            bb_name = "custom";bb_limit = "9";bb_format = "bbo";
          </script>
          <script type="text/javascript" src="http://widgets.boo-box.com/javascripts/embed.js"></script>
          <!-- boo-widget end --><p><a href="http://www.accesspdf.com/pdftk/">pdftk &#8211; the pdf toolkit</a></p>
<p><a href="http://www.hdfree.com.br/">Bem vindo | HDFree Brasil</a></p>
<blockquote><p>Hospedagem de páginas gratuitas</p></blockquote>
<p><a href="http://imasters.uol.com.br/artigo/14294/sql_server/dividindo_dados_em_colunas/">Dividindo dados em colunas &#8211; Mauro Pichiliani &#8211; SQL Server</a></p>
<p><a href="http://yfrog.com/">yfrog &#8211; Share your images/videos on Twitter!</a></p>
<p><a href="http://www.mediaconverter.org/">Media Converter &#8211; the fastest free online audio and video converter</a></p>
<p><a href="http://www.jeromiejackson.com/index.php/top-100-security-tools">Top 100 Open Source Security Tools</a></p>
]]></content:encoded>
			<wfw:commentRss>http://rafael.bernard-araujo.com/tropecando-11.php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tropeçando&#160;2</title>
		<link>http://rafael.bernard-araujo.com/tropecando2.php</link>
		<comments>http://rafael.bernard-araujo.com/tropecando2.php#comments</comments>
		<pubDate>Mon, 11 May 2009 17:48:46 +0000</pubDate>
		<dc:creator>rafael</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[3G]]></category>
		<category><![CDATA[claro]]></category>
		<category><![CDATA[cristão]]></category>
		<category><![CDATA[editora]]></category>
		<category><![CDATA[filme]]></category>
		<category><![CDATA[galeria de foto]]></category>
		<category><![CDATA[gráfico]]></category>
		<category><![CDATA[imagem]]></category>
		<category><![CDATA[menu de navegação]]></category>
		<category><![CDATA[tropeçando]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://rafael.bernard-araujo.com/?p=240</guid>
		<description><![CDATA[O mundo de lunga: Conexão 3G &#8211; Solução para problema com DNS Para resolver o problema de DNSs para conexões com modems Huawei, que sobrescreve o /etc/resolv.conf 50+ Gorgeous Navigation Menus &#124; Vandelay Design Blog 50 exemplos de menu de navegação Edições Cristãs Editora Ltda. Chartle.net &#8211; interactive charts online! Ferramenta para montagem de gráfico [...]]]></description>
			<content:encoded><![CDATA[<!-- boo-widget start -->
          <script type="text/javascript">
            bb_keywords = "tropeçando";
            bb_bid  = "1613262";
            bb_lang = "pt-BR";
            bb_name = "custom";bb_limit = "9";bb_format = "bbo";
          </script>
          <script type="text/javascript" src="http://widgets.boo-box.com/javascripts/embed.js"></script>
          <!-- boo-widget end --><p><a href="http://www.mundolunga.com/2008/11/conxexo-3g-soluo-para-problema-com-dns.html">O mundo de lunga: Conexão 3G &#8211; Solução para problema com DNS</a></p>
<blockquote><p>Para resolver o problema de DNSs para conexões com modems Huawei, que sobrescreve o <code>/etc/resolv.conf</code></p></blockquote>
<p><a href="http://vandelaydesign.com/blog/galleries/inspirationalnavigation-menus/">50+ Gorgeous Navigation Menus | Vandelay Design Blog</a></p>
<blockquote><p>50 exemplos de menu de navegação</p></blockquote>
<p><a href="http://www.edicoescristas.com.br/">Edições Cristãs Editora Ltda.</a></p>
<p><a href="http://www.chartle.net/">Chartle.net &#8211; interactive charts online!</a></p>
<blockquote><p>Ferramenta para montagem de gráfico para colocar em sites</p></blockquote>
<p><a href="http://piwigo.org/">Piwigo.org | Photo Gallery Software for the Web</a></p>
<blockquote><p>Mais um exemplo de uma boa galeria de fotos</p></blockquote>
<p><a href="http://www.resizeyourimage.com/">Resize your image online &#8211; It&#8217;s easy, it&#8217;s free!</a></p>
<blockquote><p>Redimensionamento de imagens pela web</p></blockquote>
<p><a href="http://filmow.com/">Filmow</a></p>
<blockquote><p>&#8220;O Filmow foi criado para pessoas viciadas e apaixonadas por filmes. A principal ideia do Filmow é que você mostre aos seus amigos os filmes que já assistiu, comente sobre eles e dê sua opinião, na página do filme. Mas, para os que apenas gostam de filmes, o Filmow também é uma rede social onde é possível encontrar pessoas e amigos.</p>
<p>No Filmow você fica sabendo quais filmes são lançados, os que estão no cinema e aqueles que já estão em DVD, para você assistir em casa.&#8221; (<a href="http://filmow.com/sobre-o-filmow/">http://filmow.com/sobre-o-filmow/</a>)</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://rafael.bernard-araujo.com/tropecando2.php/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Validar CPF com&#160;php</title>
		<link>http://rafael.bernard-araujo.com/validar-cpf-com-php.php</link>
		<comments>http://rafael.bernard-araujo.com/validar-cpf-com-php.php#comments</comments>
		<pubDate>Wed, 26 Nov 2008 12:56:34 +0000</pubDate>
		<dc:creator>rafael</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://rafael.bernard-araujo.com/?p=139</guid>
		<description><![CDATA[Uma função utilíssima para cadastros que exigem CPF. Returna true se o CPF for válido e false se inválido. function valida_cpf($cpf) { // verifica se e numerico if(!is_numeric($cpf)) { return false; } // verifica se esta usando a repeticao de um numero if( ($cpf == '11111111111') &#124;&#124; ($cpf == '22222222222') &#124;&#124; ($cpf == '33333333333') &#124;&#124; [...]]]></description>
			<content:encoded><![CDATA[<p>Uma função utilíssima para cadastros que exigem CPF. Returna <code>true</code> se o CPF for válido e <code>false</code> se inválido.</p>
<p><code><br />
function valida_cpf($cpf) {<br />
// verifica se e numerico<br />
if(!is_numeric($cpf)) {<br />
return false;<br />
}</code></p>
<p><code>// verifica se esta usando a repeticao de um numero<br />
if( ($cpf == '11111111111') || ($cpf == '22222222222') || ($cpf == '33333333333') || ($cpf == '44444444444') || ($cpf == '55555555555') || ($cpf == '66666666666') || ($cpf == '77777777777') || ($cpf == '88888888888') || ($cpf == '99999999999') || ($cpf == '00000000000') ) {<br />
return false;<br />
}</code></p>
<p><code>//PEGA O DIGITO VERIFIACADOR<br />
$dv_informado = substr($cpf, 9,2);</code></p>
<p><code>for($i=0; $i&lt;=8; $i++) {<br />
$digito[$i] = substr($cpf, $i,1);<br />
}</code></p>
<p><code>//CALCULA O VALOR DO 10º DIGITO DE VERIFICAÇÂO<br />
$posicao = 10;<br />
$soma = 0;</code></p>
<p><code>for($i=0; $i&lt;=8; $i++) {<br />
$soma = $soma + $digito[$i] * $posicao;<br />
$posicao = $posicao - 1;<br />
}</code></p>
<p><code>$digito[9] = $soma % 11;</code></p>
<p><code>if($digito[9] &lt; 2) {<br />
$digito[9] = 0;<br />
} else {<br />
$digito[9] = 11 - $digito[9];<br />
}</code></p>
<p><code>//CALCULA O VALOR DO 11º DIGITO DE VERIFICAÇÃO<br />
$posicao = 11;<br />
$soma = 0;</code></p>
<p><code>for ($i=0; $i&lt;=9; $i++) {<br />
$soma = $soma + $digito[$i] * $posicao;<br />
$posicao = $posicao - 1;<br />
}</code></p>
<p><code>$digito[10] = $soma % 11;</code></p>
<p><code>if ($digito[10] &lt; 2) {<br />
$digito[10] = 0;<br />
}<br />
else {<br />
$digito[10] = 11 - $digito[10];<br />
}</code></p>
<p><code>//VERIFICA SE O DV CALCULADO É IGUAL AO INFORMADO<br />
$dv = $digito[9] * 10 + $digito[10];<br />
if ($dv != $dv_informado) {<br />
return false;<br />
}</code></p>
<p><code>return true;<br />
} //  function valida_cpf($cpf)</code></p>
<p><a title="Valida CPF" href="/php/valida-cpf.php.txt" target="_blank">Copie o código aqui.</a></p>
<p>Código adaptado do <a href="http://imasters.uol.com.br/artigo/1403/php/validacao_de_cpf_usando_php/" target="_blank">iMasters</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://rafael.bernard-araujo.com/validar-cpf-com-php.php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Galvão bota a mão na massa em&#160;SP</title>
		<link>http://rafael.bernard-araujo.com/galvao-bota-a-mao-na-massa-em-sp.php</link>
		<comments>http://rafael.bernard-araujo.com/galvao-bota-a-mao-na-massa-em-sp.php#comments</comments>
		<pubDate>Fri, 21 Nov 2008 17:33:22 +0000</pubDate>
		<dc:creator>rafael</dc:creator>
				<category><![CDATA[Banco de dados]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[xss]]></category>

		<guid isPermaLink="false">http://rafael.bernard-araujo.com/?p=105</guid>
		<description><![CDATA[Quem está em SP e estiver disponível em 1º de março (1ª edição) ou 31 de maio (2ª edição) terá uma ótima oportunidade de conhecer ainda mais sobre práticas de segurança no desenvolvimento em php. Recebi a seguinte mensagem do Er Galvão: No dia primeiro de Março estarei em São Paulo ministrando um workshop sobre [...]]]></description>
			<content:encoded><![CDATA[<!-- boo-widget start -->
          <script type="text/javascript">
            bb_keywords = "xss";
            bb_bid  = "1613262";
            bb_lang = "pt-BR";
            bb_name = "custom";bb_limit = "9";bb_format = "bbo";
          </script>
          <script type="text/javascript" src="http://widgets.boo-box.com/javascripts/embed.js"></script>
          <!-- boo-widget end --><p>Quem está em SP e estiver disponível em 1º de março (1ª edição) ou 31 de maio (2ª edição) terá uma ótima oportunidade de conhecer ainda mais sobre práticas de segurança no desenvolvimento em php. Recebi a seguinte mensagem do <a href="http://www.galvao.eti.br" title="Er Galvão - TI" target="_blank">Er Galvão</a>:</p>
<blockquote><p>No dia primeiro de Março estarei em São Paulo ministrando um workshop sobre segurança em aplicações PHP, focando em tópicos específicos e técnicas 100% práticas de defesa.</p></blockquote>
<p>Er Galvão entende muito de segurança e tem grande facilidade em passar seu conhecimento, como pode ser visto no artigo <a href="http://rafael.bernard-araujo.com/index.php/seguranca-no-php.php" title="Segurança no PHP">Segurança no PHP</a>. Se eu estivesse em São Paulo, não perderia.</p>
<p>Segurança no desenvolvimento é fundamental para que a internet seja, verdadeiramente, uma ferramenta benéfica para o comércio. Conheço códigos de lojas virtuais que não foram desenvolvidas com preocupação nos tópicos de segurança. Se isso acontece por terem sido construídas antes de se conhecer as práticas atuais, está mais do que na hora de que sejam reconstruídas. Imagine o prejuízo que já se tem (só não se sabe) quando algum criminoso digital conhece essas falhas.</p>
<p>Use a tecnologia a seu favor. Ouça o que o Er Galvão tem a contribuir.</p>
<blockquote><p><a href="http://www.temporealeventos.com.br/?area=88" title="Mão na massa" target="_blank">http://www.temporealeventos.com.br/?area=88</a></p>
<p>São Paulo &#8211; SP<br />
<strike> 1 de Março</strike> 31 de maio das 9h00 às 17h00 (2ª edição)</p>
<p>Aprenda: 1 profissional por máquina</p>
<p>PHP: Proteja sua Aplicação</p>
<p>técnicas para defender sua aplicação PHP de ataques como SQL Injection, Cross Site Scripting e Cross Site Request Forgeries</p>
<p>Objetivo: Neste treinamento o profissional aprenderá técnicas para defender sua aplicação PHP de ataques como SQL Injection, Cross Site Scripting e Cross Site Request Forgeries. Primeiramente serão apresentados exemplos práticos de funcionamento de cada um destes ataques de forma à compreender os pontos fracos de cada aplicação. Serão então colocadas em prática diversas técnicas, variando das mais simples às menos óbvias que axiliarão o desenvolvedor à diminuir consideravelmente o nível de vulnerabilidade de suas aplicações.</p>
<p>Público Alvo: Desenvolvedores PHP e demais interessados</p>
<p>Pré-requisitos: Conhecimentos básicos de HTML e Conhecimentos intermediários de PHP</p>
<p>Sistema operacional em que o curso será ministrado: Linux</p>
<p>Após o término deste treinamento o participante estará imediatamente apto a: Compreender o funcionamento dos ataques mais comuns que rondam a web, desenvolver aplicações mais seguras e robustas, menos vulneráveis à ataques.</p>
<p>Conteúdo Programático</p>
<p>Boas práticas:</p>
<p>O que todo o programador PHP deveria saber<br />
O que é e como funciona um ataque de SQL Injection<br />
SQL Injection &#8211; Técnicas de defesa: Porque addslashes não é o bastante<br />
O que é e como funciona um ataque de Cross Side Scripting (XSS)<br />
XSS &#8211; Técnicas de defesa<br />
O que é e como funciona um ataque de Cross Site Request Forgeries (CSRF)<br />
CSRF &#8211; Técnicas de defesa</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://rafael.bernard-araujo.com/galvao-bota-a-mao-na-massa-em-sp.php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Converter formato de data para o formato BR, em uma linha de código&#160;só</title>
		<link>http://rafael.bernard-araujo.com/converter-formato-de-data-para-o-formato-br-em-uma-linha-de-codigo-so.php</link>
		<comments>http://rafael.bernard-araujo.com/converter-formato-de-data-para-o-formato-br-em-uma-linha-de-codigo-so.php#comments</comments>
		<pubDate>Wed, 19 Nov 2008 12:12:41 +0000</pubDate>
		<dc:creator>rafael</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Banco de dados]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://rafael.bernard-araujo.com/?p=98</guid>
		<description><![CDATA[Vou pedir licença ao Frederico e também palpitar sobre a possibilidade de, em uma linha, converter o formato de data do banco (funciona para o MySQL e outros bancos) para o formato brasileiro em php. Considerando que &#60;?php $data = "2008-01-09 14:56:06"; ?&#62;: &#60;?php echo date('d/m/Y H:m:s', strtotime($data)); ?&#62; mostrará 09/01/2008 14:01:06. &#60;?php echo date('d/m/Y', [...]]]></description>
			<content:encoded><![CDATA[<!-- boo-widget start -->
          <script type="text/javascript">
            bb_keywords = "data";
            bb_bid  = "1613262";
            bb_lang = "pt-BR";
            bb_name = "custom";bb_limit = "9";bb_format = "bbo";
          </script>
          <script type="text/javascript" src="http://widgets.boo-box.com/javascripts/embed.js"></script>
          <!-- boo-widget end --><p>Vou pedir licença ao <a href="http://d3rf.wordpress.com/2008/01/08/converter-formato-de-data-do-mysql-para-o-formato-br-em-uma-linha-de-codigo-so/" title="Converter formato de data do MySQL para o formato BR, em uma linha de código só" target="_blank">Frederico</a> e também palpitar sobre a possibilidade de, em uma linha, converter o formato de data do banco (funciona para o MySQL e outros bancos) para o formato brasileiro em php.</p>
<p>Considerando que <code>&lt;?php $data = "2008-01-09 14:56:06"; ?&gt;</code>:<br />
<code>&lt;?php echo date('d/m/Y H:m:s', strtotime($data)); ?&gt;</code> mostrará 09/01/2008 14:01:06.<br />
<code>&lt;?php echo date('d/m/Y', strtotime($data)); ?&gt;</code> mostrará 09/01/2008.</p>
<p>Simples assim. <img src='http://rafael.bernard-araujo.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Essa solução funciona para datas no formato yyyy-mm-dd hh:mm:ss e yyyy-mm-dd.</p>
]]></content:encoded>
			<wfw:commentRss>http://rafael.bernard-araujo.com/converter-formato-de-data-para-o-formato-br-em-uma-linha-de-codigo-so.php/feed</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Segurança no&#160;PHP</title>
		<link>http://rafael.bernard-araujo.com/seguranca-no-php.php</link>
		<comments>http://rafael.bernard-araujo.com/seguranca-no-php.php#comments</comments>
		<pubDate>Wed, 12 Nov 2008 16:17:11 +0000</pubDate>
		<dc:creator>rafael</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[cookie]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[register globals]]></category>
		<category><![CDATA[segurança]]></category>
		<category><![CDATA[sessão]]></category>

		<guid isPermaLink="false">http://rafael.bernard-araujo.com/?p=70</guid>
		<description><![CDATA[Os 6 requisitos mínimos por Er Galvão Abbott (http://www.galvao.eti.br/) na revista PHPMagazine (http://www.phpmagazine.org.br/) Apresentareremos neste artigo 6 requisitos que todo o desenvolvedor PHP deveria contemplar em sua aplicação. São boas práticas e hábitos simples que implementam um nível mínimo de segurança em qualquer sistema ou ferramenta desenvolvida com a linguagem. A linguagem PHP é, sem [...]]]></description>
			<content:encoded><![CDATA[<!-- boo-widget start -->
          <script type="text/javascript">
            bb_keywords = "cookie";
            bb_bid  = "1613262";
            bb_lang = "pt-BR";
            bb_name = "custom";bb_limit = "9";bb_format = "bbo";
          </script>
          <script type="text/javascript" src="http://widgets.boo-box.com/javascripts/embed.js"></script>
          <!-- boo-widget end --><h3>Os 6 requisitos mínimos</h3>
<p><em>por Er Galvão Abbott (<a class="extlink" href="http://www.galvao.eti.br/" target="_blank">http://www.galvao.eti.br/</a>) na revista PHPMagazine (<a class="extlink" href="http://www.phpmagazine.com.br/" target="_blank">http://www.phpmagazine.org.br/</a>)</em></p>
<p align="center"><a href="http://www.phpmagazine.org.br/" target="_blank"><img src="http://rafael.bernard-araujo.com/img/phpmagazine-logo-medio.gif" alt="logo-phpmagazine" width="144" height="68" border="0" /></a></p>
<p><img src="http://www.galvao.eti.br/img/foto.jpg" alt="" width="100" height="105" align="left" />Apresentareremos neste artigo 6 requisitos que todo o desenvolvedor PHP deveria contemplar em sua aplicação. São boas práticas e hábitos simples que implementam um nível mínimo de segurança em qualquer sistema ou ferramenta desenvolvida com a linguagem.</p>
<p>A linguagem PHP é, sem dúvida, uma das mais populares quando o assunto é desenvolvimento de aplicações web. Existe, porém, um preconceito muito grande com a linguagem quando a questão é segurança. Neste artigo veremos 6 requisitos básicos que toda aplicação deveria possuir e que implementarão o mínimo de segurança em tudo o que você desenvolver.</p>
<p><strong>Conceito: PHP é uma linguagem mais vulnerável do que as outras?</strong></p>
<p>Atualmente impera no mercado de desenvolvimento um preconceito relacionado à segurança de aplicações PHP. A linguagem é freqüentemente alvo de duras críticas por parte da própria comunidade de desenvolvimento, e não é raro presenciarmos aplicações extremamente vulneráveis que, com toda a certeza, dão razão a essas críticas.</p>
<p>Este preconceito, totalmente equivocado, tem suas origens na extrema flexibilidade de configuração e uso da linguagem e no número cada vez maior de desenvolvedores inexperientes que começam sua carreira desenvolvendo aplicações PHP, ignorando questões básicas, seja por falta de conhecimento ou porque estão procurando agilizar sua produção pessoal.</p>
<p>Este artigo não é destinado apenas aos que estão começando. É surpreendente o número de desenvolvedores mais experientes que, por terem adquirido vícios, ainda ignoram as questões que apresentaremos aqui.</p>
<p><strong>Requisito #1: Esqueça <em>register_globals</em>!</strong></p>
<p><em>Register_globals</em> é, sem dúvida alguma, a diretiva de configuração mais popular e polêmica já implementada no PHP. É popular entre os desenvolvedores por tornar o processo de programação muito mais ágil e prático. É polêmica porque retira tanto do programador quanto do interpretador da linguagem a responsabilidade em definir a origem das informações utilizadas pela aplicação.</p>
<p>Esta diretiva causou tantos problemas que começou a vir desabilitada por <em>default</em> a partir da versão 4.2.0 e <strong>será eliminada na versão 6</strong>. Por isso, se você ainda programa com <em>register_globals</em> ligada, está mais do que na hora de mudar.</p>
<p>Observe o seguinte exemplo de código:</p>
<p><code>$url = "http://www.meusite.com.br/index.php";<br />
$errMsg = "Usuário%20não%20autenticado";<br />
if (!$autenticado) {<br />
header("Location: $url?erro=$errMsg");<br />
} else {<br />
/* A aplicação age com se o usuário estivesse autenticado */<br />
}<br />
</code><br />
Este código verifica por uma variável booleana chamada <code>$autenticado</code>, que tipicamente viria de uma sessão aberta quando o usuário se autenticou em nossa aplicação ou mesmo de um <em>cookie</em>. Ao utilizarmos os recursos da <em>register_globals</em>, porém, não estamos dizendo ao interpretador PHP que este dado deve vir obrigatoriamente de uma destas duas fontes.</p>
<p>Sendo assim, o interpretador procurará por esta variável em diversas fontes (variável do servidore web, dados de formulário, <em>cookie</em>, arquivos enviados por <em>upload</em>, <em>query string</em> ou sessões) das quais ele obteve informações até encontrá-la, desprezando se esta fonte está correta.</p>
<p>Torna-se extremamente simples &#8220;enganar&#8221; a sua aplicação PHP, basta que eu chame o seu arquivo passando a variável esperada por <em>query string</em>.</p>
<p>http://www.meusite.com.br/script.php?autenticado=1</p>
<p>Ao receber a <em>query string</em> contendo a informação &#8220;autenticado&#8221;, este dado será automaticamente interpretado como uma variável pelo interpretador, quer exista sessões ou <em>cookies</em> ou não.</p>
<p>Uma dúvida freqüente é &#8220;se não tenho autorização para desligar a <em>register_globals</em> o que eu posso fazer?&#8221;. A resposta para isso é tão simples quanto tudo o mais na linguagem: <strong>programe como se ela estivesse desligada!</strong> Veja como fica o nosso código ao não utilizar a <em>register_globals</em>:</p>
<p><code>$url = "http://www.meusite.com.br/index.php";<br />
$errMsg = "Usuário%20não%20autenticado";<br />
if (!$_SESSSION['autenticado']) {<br />
header("Location: $url?erro=$errMsg");<br />
} else {<br />
/* A aplicação age com se o usuário estivesse autenticado */<br />
}</code></p>
<p>Observe a mudança: ao utilizarmos o <em>array</em> super global <code>$_SESSION</code>, estamos explicitando para o interpretador que a informação &#8220;autenticado&#8221; tem que, obrigatoriamente, vir de uma sessão. Isto significa que será impossível para o interpretador confundir este dado com um dado enviado pela <em>query string</em>, pois este fica armazenado em um <em>array</em> super global diferente:</p>
<ul>
<li>$_SERVER &#8211; Informações definidas pelo servidor web (Apache, IIS etc)</li>
<li>$_GET &#8211; Informações passadas por <em>query string</em> ou por um formulário web utilizando o método GET</li>
<li>$_POST &#8211; Informações enviadas, tipicamente, por um formulário web utilizando o método POST</li>
<li>$_COOKIE &#8211; Informações fornecidas por um cookie HTTP</li>
<li>$_FILES &#8211; Informações fornecidas por arquivos que foram enviados via <em>upload</em> HTTP</li>
<li>$_ENV &#8211; Informações fornecidas pelo ambiente do servidor</li>
<li>$_REQUEST* &#8211; Informações fornecidas por GET, POST ou COOKIE</li>
</ul>
<p><strong>* Cuidado</strong>: O uso do <em>array</em> super global <code>$_REQUEST</code> é quase tão perigoso quanto a <em>register_globals</em> em si, pois nesse caso a informação pode vir de qualquer um dos 3 métodos: GET, POST ou COOKIE.</p>
<p><strong>Requisito #2: Use require e não include</strong></p>
<p>O comando <code>include</code> e seus derivados &#8211; como <code>include_once</code> &#8211; são freqüentemente usados em detrimento do comando <code>require</code>. Este fato curioso a princípio é conseqüência da similaridade do comando <code>include </code>com outras linguagens, como C e Java.</p>
<p>O que muita gente não sabe, porém, é que este comando carrega consigo um risco muito grande para sua aplicação: se por algum motivo a inclusão do arquivo falhar &#8211; erro de digitação, disco corrompido etc &#8211; será gerado um erro de nível <em>warning</em>, um nível leve de erro que não causa a parada da execução do script.</p>
<p>Utilizando o comando <code>require</code>, garantimos que, no caso de falha na carga do arquivo, seja gerado, além do erro de nível <em>warning</em>, um erro de nível <em>fatal</em>. Em bom português isso significa que a execução do seu script será imediatamente interrompida neste caso. Por que é bom que seu script seja interrompido no caso de falha de inclusão de outro arquivo? Simples: no caso de falhas, as variáveis, as funções, as constantes e o que mais este arquivo carregava consigo, simplesmente, não estarão disponíveis.</p>
<p><strong>Requisito #3: Filtre a entrada de dados!</strong></p>
<p>Um dos principais conceitos de segurança é a filtragem dos dados que são recebidos antes de utilizá-los. A falta de fitlragem é a causa de inúmeros problemas de segurança, incluindo o infame <em>SQL Injection</em>, ou Injeção de SQL. Observe o seguinte código:</p>
<p><code>require_once("conecta.php");<br />
$conn = conecta();<br />
$sql = "SELECT email FROM usuarios WHERE usuario_id = " . $_GET['uid'];<br />
$recordSet = mysql_query($sql);<br />
while ($record = mysql_fetch_assoc($recordSet)) {<br />
echo $record['email'] . '&lt;br /&gt;';<br />
}<br />
mysql_close();</code></p>
<p>O problema deste código é utilizar um dado informado pela <em>query string</em> (uid) sem fazer nenhuma filtragem, ou seja, nosso script aceitará cegamente qualquer coisa que for digitada como valor de uid. Observe a seguinte URL:</p>
<p>http://www.meusite.com.br/script.php?uid=198%20OR%20&#8242;x&#8217;='x&#8217;</p>
<p>Após a conversão dos caracteres especiais desta URL, o valor de uid será (sem aspas duplas): &#8220;198 or &#8216;x&#8217;='x&#8217;&#8221;. Note que, quando concatenarmos isto à nossa <em>query</em>, ela terá sofrido uma grande modificação:</p>
<p><code>SELECT email FROM usuarios WHERE usuario_id = 198 <span style="color: #ff0000;">or 'x'='x'</span></code></p>
<p>É por isso que a chamamos de &#8220;Injeção de SQL&#8221;. A parte em vermelho acima é formada de SQL válido, mas completamente alienígena à nossa plicação: <strong>ele modifica o comportamento original da query</strong>.</p>
<p>Observe que, com um mínimo de esforço, um usuário conseguiu expor todos os e-mails cadastrados em nossa base de dados: como foi utilizado o operador &#8220;OR&#8221; e a segunda condição (&#8216;x&#8217;='x&#8217;) é sempre verdadeira, serão exibidos todos os registros.</p>
<p>Para evitarmos este tipo de problema, devemos aplicar um tratamento à informação <strong>antes</strong> de utilizá-la. Caso a minha <em>query</em> &#8211; como neste exemplo &#8211; esteja esperando um número inteiro, a solução é simples: forçamos a conversão do dado recebido para número inteiro:</p>
<p><code>require_once("conecta.php");<br />
$conn = conecta();</code></p>
<p><code>settype($_GET['uid'], integer);</code></p>
<p><code>$sql = "SELECT email FROM usuarios WHERE usuario_id = " . $_GET['uid'];<br />
$recordSet = mysql_query($sql);<br />
while ($record = mysql_fetch_assoc($recordSet)) {<br />
echo $record['email'] . '&lt;br /&gt;';<br />
}<br />
mysql_close();</code></p>
<p>A partir de agora, qualquer dado enviado pela <em>query string</em> será primeiro convertido para inteiro e somente depois desta conversão é que o utilizaremos. No caso de uma tentativa de Injeção de SQL, nosso script considerará apenas a parte numérica (198), como deveria ser. Além disso, se por um acaso nosso script receber apenas texto, a função <code>settype</code> converterá isto para o número 0.</p>
<p>Caso a minha <em>query</em> esteja esperando uma <em>string</em> a solução reside em criar um tratamento que valide esta <em>string</em>. Vejamos um exemplo: possuo uma <em>query</em> que busca dados de um usuário através de seu endereço de e-mail:</p>
<p><code>$sql = "SELECT nome, sobrenome FROM usuarios WHERE email = '" . $_GET['email'] . "'";<br />
</code><br />
Sabemos que um endereço de e-mail é formado por um nome de usuário, uma arroba e um domínio. Para fins de simplificação do exemplo, trabalharemos como se o usuário só pudesse usar letras, números e o caracterese de ponto &#8211; para quem levar a validação de e-mail a sério consulte a RFC 822. Podemos representar isso através de uma expressão regular:</p>
<p><code>/^[A-Z|a-z|0-9|\.|]+\@[A-Z|a-z|0-9\.|]+/</code></p>
<p>Sendo assim, só aceitaremos o dado de endereço de e-mail se ele estiver dentro dos padrões de minha expressão regular. Nosso código então ficaria assim:</p>
<p><code>require_once("conecta.php");<br />
if (preg_match('</code><code>/^[A-Z|a-z|0-9|\.|]+\@[A-Z|a-z|0-9\.|]+/'</code><code>, $_GET['email'])) {<br />
$conn = conecta();</code></p>
<p><code>$sql = "SELECT nome, sobrenome FROM usuarios WHERE email = '" . $_GET['email'] . "'";<br />
$recordSet = mysql_query($sql);<br />
while ($record = mysql_fetch_assoc($recordSet)) {<br />
echo $record['email'] . '&lt;br /&gt;';<br />
}<br />
} else {<br />
die("O dado informado não é um endereço de e-mail válido.");<br />
}<br />
mysql_close();<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://rafael.bernard-araujo.com/seguranca-no-php.php/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

