Arquivos .inc
Muitos programadores PHP tinham (alguns ainda tem) o hábito de salvar seus includes em arquivos do tipo /inc/config.inc.
Nesses arquivos config.inc, geralmente colocam strings SQL, variáveis importantes, funções globais, etc. Eis um exemplo de arquivo .inc:
Mas, geralmente estes arquivos .inc tem as permissões de acesso como qualquer outro e como não é interpretado pelo servidor, pode-se facilmente fazer o download dos mesmos.
Qualquer usuário mal intencionado que fizesse o download desse arquivo teria acesso ao seu endereço do seu servidor MySQL, à sua senha e seu usuário.
Correção. Existem dois métodos:
*Deixar seus arquivos em uma pasta especial e mudar as permissões de acesso desta pasta;
*A que eu prefiro. Mudar as extensões de config.inc para config.inc.php.
Assim, o servidor se encarrega de 'ocultar' o conteúdo do arquivo.
SQL Injection
Estamos desenvolvendo uma área restrita. Ao validar o Login, nós fazemos:
Imaginemos que um usuário mal intencionado digite nos campos a seguinte string:
A nossa string SQL ficaria assim:
Como no final teremos um OR 1=1, o resultado da string sempre retornará verdadeiro.
Teríamos que, na resposta da SQL, todos os ítens seriam selecionados. E o usuário mal intencionado terá um login QUALQUER, provavelmente o primeiro login do registro da tabela.
Logar como usuário definido.
Lembramos que esse código vale para o MySQL e não foi testado em outros BDs. Mas quem quiser testar, poste o resultado aqui depois.
No MySQL, o caractere # (sustenido) age como comentário. Então, o nosso 'amigo' usuário malicioso coloca a seguinte string no campo de login:
Independente da senha, teremos no final a seguinte instrução SQL:
Já que tudo que há à direita do sustenido é comentário, então a instrução SQL se resume a isso:
É possível assim acessar qualquer usuário sem precisar da senha.
Solução: Tratamento de dados. Colocar uma barra () antes das aspas simples, fazendo com que a SQL não interprete as aspas simples como parte da string SQL:
Includes mal formatados
É comum ver alguns sites fazendo includes de strings que vem por GET ou POST. Assim:
O programa incluirá o arquivo ./qualquer.php no código. Mas, e se a URL estiver assim:
O usuário terá na tela o seu arquivo de senhas e usuários. E isso com qualquer outro arquivo importante.
Solução: Tratamento de dados.
Varíaveis globais
Para quem está começando a programar em PHP, é muito mais prático liberar variáveis globais em seus scripts PHP.
Em vez de fazer $_GET["usuario"], fazem apenas $usuario.
Isso acarreta em alguns problemas.
Vejamos esta situação, teste.php:
Novamente, o usuário poderia passar a seguinte URL:
Solução: Neste caso, bastaria um 'else $verificado=0', mas as situações podem ficar mais complexas. E podem ser contornadas, evitando o uso de variáveis globais.
Muitos programadores PHP tinham (alguns ainda tem) o hábito de salvar seus includes em arquivos do tipo /inc/config.inc.
Nesses arquivos config.inc, geralmente colocam strings SQL, variáveis importantes, funções globais, etc. Eis um exemplo de arquivo .inc:
Código PHP:
<?
// conectar.inc
$host_db = "localhost"
$user_db = "usuário"
$pw_db = "senha"
$conexao = mysql_connect($host_db,$user_db,$pw_db);
?>
Qualquer usuário mal intencionado que fizesse o download desse arquivo teria acesso ao seu endereço do seu servidor MySQL, à sua senha e seu usuário.
Correção. Existem dois métodos:
*Deixar seus arquivos em uma pasta especial e mudar as permissões de acesso desta pasta;
*A que eu prefiro. Mudar as extensões de config.inc para config.inc.php.
Assim, o servidor se encarrega de 'ocultar' o conteúdo do arquivo.
SQL Injection
Estamos desenvolvendo uma área restrita. Ao validar o Login, nós fazemos:
Código PHP:
<?
$user = $_POST["usuario"];
$senha = $_POST["senha"];
$result = mysql_query("Select * From users Where user='" . $user ."' AND senha='" . $senha . "'",$cox);
?>
Código PHP:
1' OR 1='1
Código PHP:
SELECT * FROM Users WHERE user='1' OR 1='1' AND senha='1' OR 1='1'
Teríamos que, na resposta da SQL, todos os ítens seriam selecionados. E o usuário mal intencionado terá um login QUALQUER, provavelmente o primeiro login do registro da tabela.
Logar como usuário definido.
Lembramos que esse código vale para o MySQL e não foi testado em outros BDs. Mas quem quiser testar, poste o resultado aqui depois.
No MySQL, o caractere # (sustenido) age como comentário. Então, o nosso 'amigo' usuário malicioso coloca a seguinte string no campo de login:
Código PHP:
admin'#
Código PHP:
SELECT * FROM Users WHERE user='admin'#' OR 1='1' AND senha='qualquer'
Código PHP:
SELECT * FROM Users WHERE user='admin'
Solução: Tratamento de dados. Colocar uma barra () antes das aspas simples, fazendo com que a SQL não interprete as aspas simples como parte da string SQL:
Código PHP:
$user = str_replace(''', '\'', $user);
$senha = str_replace(''', '\'', $senha);
É comum ver alguns sites fazendo includes de strings que vem por GET ou POST. Assim:
Código PHP:
<?
// teste.php?arquivo=./qualquer.php
$arquivo = $_GET["arquivo"];
include($arquivo);
?>
Código PHP:
teste.php?arquivo=../../../../etc/passwd
Solução: Tratamento de dados.
Varíaveis globais
Para quem está começando a programar em PHP, é muito mais prático liberar variáveis globais em seus scripts PHP.
Em vez de fazer $_GET["usuario"], fazem apenas $usuario.
Isso acarreta em alguns problemas.
Vejamos esta situação, teste.php:
Código PHP:
<?
if (autenticar($user,$senha)) {
$verificado=1;
}
if($verificado==1) {
// Faz alguma coisa importante
}
?>
Código PHP:
teste.php?verificado=1
Comment