Manual do PHP
Anterior | Capítulo 16. Segurança | Próxima

# Usando Register Globals

Talvez a mudança mais controversa no PHP é quando o valor padrão para a diretiva do PHP register_globals passou de ON para OFF no PHP 4.2.0. Confiança nesta está diretiva foi bastante pública e muitas pessoas nem mesmo sabiam que ela existia e assumiam que ela é apenas a forma como o PHP trabalha. Esta página irá explicar como alguém pode escrever um código inseguro com esta diretiva, mas mantenha em mente que a diretiva por si só não é insegura, mas o seu uso incorreto sim.

Quando on, register_globals injetará (veneno) em seus scripts todos os tipos de variáveis, como variáveis request de formulários HTML. Isto junta-se com o fato deo PHP não exigir inicialização de variáveis siginifica que escrever códigos inseguros é muito mais fácil. Não foi uma decisão difícil, mas a comunidade PHP decidiu, por definição, desabilitar esta diretiva. Quando on, as pessoas usavam variáveis ainda sem saber realmente, com certeza, de onde elas vinham e podiam apenas supor. Variáveis internas que estão definidas no próprio script conseguem se misturar com dados requisitados enviados pelos usuários e desabilitando register_globals muda isto. Vamos demonstrar com um exemplo de mal uso de register_globals:

Exemplo 16-14. Exemplo de uso incorreto com register_globals = on
`<?php // definir $authorized = true apenas se o usuário está autenticado if (authenticated_user()) { $authorized = true; } // Por isso nós primeiro não inicializamos $authorized como false, isto poderia // ser definido através de register_globals, como por GET auth.php?authorized=1 // então, qualquer um pode ser visto como autenticado! if ($authorized) { include "/highly/sensitive/data.php"; } ?>`

Quando register_globals = on, nossa lógica acima pode ser comprometida. Quando off, $authorized não pode ser setada via request portanto isto é mais agradável, apesar disso é realmente uma boa prática de programação inicializar as variáveis primeiro. Por exemplo, em nosso exemplo acima nós poderíamos ter feito primeiro $authorized = false. Fazendo isto primeiro significa que nosso código acima trabalharia com register_globals on ou off enquanto usuários, por definição, estariam desautorizados.

Um outro exemplo é aquele das sessões. Quando register_globals = on, nós poderíamos também usar $username em nosso exemplo abaixo, mas novamente você deve imaginar que $username poderia, também, vir de outros meios, tal como GET (pela URL).

Exemplo 16-15. Exemplo de uso de sessões com register_globals on ou off
`<?php // Nós saberíamos de onde $username veio, mas fazer com $_SESSION é // para dados de sessão if (isset($_SESSION['username'])) { echo "Olá <b>{$_SESSION['username']}</b>"; } else { echo "Olá <b>Guest</b><br />"; echo "Você gostaria de logar?"; } ?>`

É até possível tomar medidas preventivas para quando a formação de variável está sob tentativa. Se você já sabe de antemão de onde a variável está vindo, você pode ver se os dados submetidos está vindo de um tipo de submissão impróprio. Enquanto não está garantido que dados não foram formados, ele exige a um atacante que advinhe o tipo correto de formação da variável. Se você toma cuidado de onde os dados requisitados vêm, você pode usar $_REQUEST já que ele contém um misto de dados GET, POST e COOKIE. Veja também a seção do manual sobre usando variáveis externas do PHP.

Exemplo 16-16. Detectando simples envenamento de variável
`<?php if (isset($_COOKIE['MAGIC_COOKIE'])) { // MAGIC_COOKIE vem de um cookie. // Certifique se de validar os dados de cookies! } elseif (isset($_GET['MAGIC_COOKIE']) || isset($_POST['MAGIC_COOKIE'])) { mail("admin@example.com", "Possível tentativa de transgressão", $_SERVER['REMOTE_ADDR']); echo "Violação da segurança, admin foi alertado."; exit; } else { // MAGIC_COOKIE não é setado por este REQUEST } ?>`

É claro que, simplesmente desligando register_globals não significa que seu código está seguro. Para cada peça de dados que é submetido, ele também seria verificado de outras formas. Sempre faça a validação de dados de seus usuários e inicialize as suas variáveis! Para verificar por variáveis não inicializadas você pode ligar error_reporting() para mostrar níveis de erros `E_NOTICE`.

> Disponibilidade das superglobais:: Desde o PHP 4.1.0, os arrays superglobais como $_GET , $_POST, $_SERVER, etc. sempre estão carregados. Para mais informações, leia a seção do manual sobre superglobals

Anterior | Principal | Próxima
Relatório de Erro | Acima | Dados Submetidos pelo Usuário