<?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>cookie &#8211; Rafael Bernard Araujo</title>
	<atom:link href="https://rafael.bernard-araujo.com/tag/cookie/feed" rel="self" type="application/rss+xml" />
	<link>https://rafael.bernard-araujo.com</link>
	<description>desenvolvendo... while(!success){  try(); }</description>
	<lastBuildDate>Mon, 18 Dec 2023 00:49:27 +0000</lastBuildDate>
	<language>pt-BR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	
<site xmlns="com-wordpress:feed-additions:1">21941730</site>	<item>
		<title>Segurança no PHP</title>
		<link>https://rafael.bernard-araujo.com/seguranca-no-php.php</link>
					<comments>https://rafael.bernard-araujo.com/seguranca-no-php.php#comments</comments>
		
		<dc:creator><![CDATA[rafael]]></dc:creator>
		<pubDate>Wed, 12 Nov 2008 16:17:11 +0000</pubDate>
				<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 [&#8230;]]]></description>
										<content:encoded><![CDATA[<h2>Os 6 requisitos mínimos</h2>
<p><em>por Er Galvão Abbott (<a class="extlink" href="http://www.galvao.eti.br/" target="_blank" rel="noopener"><a href="http://www.galvao.eti.br/">http://www.galvao.eti.br/</a></a>) na revista PHPMagazine (<a class="extlink" href="http://www.phpmagazine.org.br/" target="_blank" rel="noopener"><a href="http://www.phpmagazine.org.br/">http://www.phpmagazine.org.br/</a></a>)</em></p>
<p align="center"><a href="http://www.phpmagazine.org.br/" target="_blank" rel="noopener"><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/rafael.bernard-araujo.com/img/phpmagazine-logo-medio.gif?resize=144%2C68" alt="logo-phpmagazine" width="144" height="68" border="0" /></a></p>
<p>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>
<pre><code class="language-php">$url = &quot;http://www.meusite.com.br/index.php&quot;;
$errMsg = &quot;Usuário%20não%20autenticado&quot;;
if (!$autenticado) {
header(&quot;Location: $url?erro=$errMsg&quot;);
} else {
/* A aplicação age com se o usuário estivesse autenticado */
}</code></pre>
<p>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 &quot;enganar&quot; a sua aplicação PHP, basta que eu chame o seu arquivo passando a variável esperada por <em>query string</em>.</p>
<p><code>http://www.meusite.com.br/script.php?autenticado=1</code></p>
<p>Ao receber a <em>query string</em> contendo a informação &quot;autenticado&quot;, 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 é &quot;se não tenho autorização para desligar a <em>register_globals</em> o que eu posso fazer?&quot;. 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>
<pre><code class="language-php">$url = &quot;http://www.meusite.com.br/index.php&quot;;
$errMsg = &quot;Usuário%20não%20autenticado&quot;;
if (!$_SESSSION[&#039;autenticado&#039;]) {
header(&quot;Location: $url?erro=$errMsg&quot;);
} else {
/* A aplicação age com se o usuário estivesse autenticado */
}</code></pre>
<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 &quot;autenticado&quot; 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 - Informações definidas pelo servidor web (Apache, IIS etc)</li>
<li>$_GET - Informações passadas por <em>query string</em> ou por um formulário web utilizando o método GET</li>
<li>$_POST - Informações enviadas, tipicamente, por um formulário web utilizando o método POST</li>
<li>$_COOKIE - Informações fornecidas por um cookie HTTP</li>
<li>$_FILES - Informações fornecidas por arquivos que foram enviados via <em>upload</em> HTTP</li>
<li>$_ENV - Informações fornecidas pelo ambiente do servidor</li>
<li>$_REQUEST* - 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 - como <code>include_once</code> - 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 - erro de digitação, disco corrompido etc - 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(&quot;conecta.php&quot;);<br />
$conn = conecta();<br />
$sql = &quot;SELECT email FROM usuarios WHERE usuario_id = &quot; . $_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><code>http://www.meusite.com.br/script.php?uid=198%20OR%20&#039;x&#039;=&#039;x&#039;</code></p>
<p>Após a conversão dos caracteres especiais desta URL, o valor de uid será (sem aspas duplas): &quot;198 or 'x'='x'&quot;. 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 &quot;Injeção de SQL&quot;. 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 &quot;OR&quot; e a segunda condição ('x'='x') é 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> - como neste exemplo - 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(&quot;conecta.php&quot;);<br />
$conn = conecta();</code></p>
<p><code>settype($_GET['uid'], integer);</code></p>
<p><code>$sql = &quot;SELECT email FROM usuarios WHERE usuario_id = &quot; . $_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 = &quot;SELECT nome, sobrenome FROM usuarios WHERE email = '&quot; . $_GET['email'] . &quot;'&quot;;<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 - 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><a href="mailto:code&gt;/^[A-Z|a-z|0-9|\.|]+\@[A-Z|a-z|0-9\.|]+/&lt;/code">code>/^[A-Z|a-z|0-9|\.|]+\@[A-Z|a-z|0-9\.|]+/</code</a></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(&quot;conecta.php&quot;);<br />
if (preg_match('<a href="mailto:/code&gt;&lt;code&gt;/^[A-Z|a-z|0-9|\.|]+\@[A-Z|a-z|0-9\.|]+/&#039;&lt;/code">/code><code>/^[A-Z|a-z|0-9|\.|]+\@[A-Z|a-z|0-9\.|]+/'</code</a><code>, $_GET['email'])) {<br />
$conn = conecta();</code></p>
<pre><code class="language-php">$sql = &quot;SELECT nome, sobrenome FROM usuarios WHERE email = &#039;&quot; . $_GET[&#039;email&#039;] . &quot;&#039;&quot;;
$recordSet = mysql_query($sql);
while ($record = mysql_fetch_assoc($recordSet)) {
echo $record[&#039;email&#039;] . &#039;&lt;br /&gt;&#039;;
}
} else {
die(&quot;O dado informado não é um endereço de e-mail válido.&quot;);
}
mysql_close();</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://rafael.bernard-araujo.com/seguranca-no-php.php/feed</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">70</post-id>	</item>
	</channel>
</rss>
