Programando com PHP de maneira mais segura

 

PHP Security Recommendations

Thiago Toledo

Programando de maneira mais segura em PHP

Apresentação

Esta apresentação mostra algumas recomendações para se programar em PHP utilizando alguns recursos de segurança.

As recomendações feitas foram baseadas em partes de documentos OWASP  específicos sobre a linguagem - acesso em 09/09/2016 - e adaptadas pelo autor para esta apresentação:

Programando de maneira mais segura em PHP

Sobre a OWASP

A OWASP é uma fundação sem fins lucrativos, fundada em 21 de abril de 2004 (data em que foi criada como fundação).
Seu principal objetivo é difundir práticas de segurança de desenvolvimento de software.

Apesar das pressões comerciais, ela não é mantida por nenhuma empresa específica de tecnologia, tornando assim seu conteúdo imparcial e transparente.

Programando de maneira mais segura em PHP

Além disso, vale destacar que os materiais são colaborativos e abertos e podem ser acessados diretamente através do site da Fundação - https://www.owasp.org .

 

Sobre a OWASP

Introdução

 

Programando de maneira mais segura em PHP

Quando falamos da linguagem no PHP devemos considerar 3 pontos importantes que devem ser levados em consideração e por isso estar devidamente atualizados e tratados de vulnerabilidades de segurança:

Introdução

 

Programando de maneira mais segura em PHP

O interpretador

da linguagem

Framework

Bibliotecas

Introdução

 

Programando de maneira mais segura em PHP

Bibliotecas

Apesar de não fazerem parte da linguagem, mas por estarem intimamente relacionados, poderíamos adicionar também outros pontos focais que devem ser seguros:

Introdução

 

Programando de maneira mais segura em PHP

HTTP

APIS

Storage

Banco

de Dados

REDE

REDE

Introdução

 

Programando de maneira mais segura em PHP

Esquecer de um desses pontos pode comprometer a segurança da sua aplicação portanto é importante levar em consideração isso ao escolher fornecedores da sua aplicação, como servidores de hospedagem, por exemplo.

Introdução

 

Programando de maneira mais segura em PHP

Falar detalhadamente sobre esses pontos vai além do escopo dessa apresentação, mas é sempre importante ressaltar que a tarefa de manter a segurança de uma aplicação envolve um conjunto de recursos, ou seja, se o programador fizer a sua parte, programando de maneira segura, ele estará cuidando apenas de uma parte importante dessa estrutura de segurança.

 

PHP Top 5

PHP Top 5

Programando de maneira mais segura em PHP

Baseada em uma importante pesquisa sobre vulnerabilidades comuns em aplicações PHP, o OWASP criou o artigo com  recomendações conhecido como PHP Top 5

A metodologia utilizada na preparação deste artigo é rever todos os lançamentos Bugtraq contendo a palavra "PHP" e categorizar cada falha único.

PHP Top 5

Programando de maneira mais segura em PHP

  1. Execução Remota de Código
  2. Cross site scripting (XSS)
  3. SQL Injection
  4. Configuração do PHP
  5. Ataques no sistema de arquivos


Execução remota de código
 

Execução remota de código

Programando de maneira mais segura em PHP

Como acontece?

Validação insuficiente de entrada do usuário antes de chamadas de sistema de arquivos dinâmico.

Exemplo: fopen($_GET['page']);

allow_url_fopen e/ou PHP wrapp o que é desnecessário para a maioria das aplicações

permissões e privilégios excessivamente amplos

Execução remota de código

Programando de maneira mais segura em PHP

Códigos de exemplo vulneráveis:

$report = $_POST[‘report_name’];
include $report;
$username = $_POST[‘username’];
eval(“echo $username”);

Execução remota de código

Programando de maneira mais segura em PHP

Como se proteger

Revisar o código reescrevendo possíveis vulnerabilidades e validando entradas de usuário.
Desativar permissões desnecessárias
( PHP.ini e outras )

Evitando XSS

Linguagem de template

 

Programando de maneira mais segura em PHP

Evitando XSS

PHP é também uma linguagem de templates ( Você pode combinar o código PHP com HTML para saidas dinâmicas, etc ).

Porém, por padrão, PHP não escapa o HTML do conteúdo da String dando abertura para um ataque XSS (https://pt.wikipedia.org/wiki/Cross-site_scripting).

Linguagem de template

 

Programando de maneira mais segura em PHP

Evitando XSS

Solução

Usar funções que tratam/filtram eliminando as tags HTML como a função htmlspecialchars.

 

 

 

 

Linguagem de template

 

Programando de maneira mais segura em PHP

Evitando XSS

Existem vários tutoriais e informações sobre como evitar ataques desse tipo na internet.

Um desses exemplos é o vídeo: https://www.youtube.com/watch?v=LGWQE4LTeuk em que o autor cria uma classe com uma WhiteList de tags aceitáveis de saída.

Um velho conhecido

SQL Injection

Programando de maneira mais segura em PHP

Um velho conhecido

SQL injection é um dos ataques mais conhecidos da comunidade. Você pode evitá-lo usando recursos como:

  • Usando PDO (disponível através do PECL para PHP 5.0, e está incluído no PHP 5.1 e posterior)
  • Usando MySQLi ou PDO - usar instruções parametrizadas (parameterized statements ou prepareted statements );
  • No mínimo, use funções como mysqli_real_escape_string;

Use as configurações a seu favor

PHP.ini

 

Programando de maneira mais segura em PHP

Use as configurações a seu favor

As modificações feitas em PHP.ini devido a recursos ou bibliotecas utilizadas devem ser feitas de maneira controlada e documentada.

É importante ao desenvolvedor conhecer bem o arquivo de configuração PHP.ini e seus parâmetros, pois este influencia na execução de sua aplicação.

Uma importante fonte de referência sobre isso: http://www.php.net/manual/en/configuration.php

PHP.ini

 

Programando de maneira mais segura em PHP

Use as configurações a seu favor

Você deve considerar desativar ( a menos que estritamente necessário) os parâmetros:

Habilitar configurando o safe_mode and open_basedir;

Ataques no sistema de arquivos

Programando de maneira mais segura em PHP

Perigo no ninho

Este tipo de ataque é mais comum em servidores compartilhados.
São utilizadas técnicas e arquivos para ter acesso a serviço de terceiros também compartilhados;

Programando de maneira mais segura em PHP

  • Certifique-se de que todas as variáveis ​​são devidamente inicializadas antes do primeiro uso;
  • Certifique-se de que os usuários só podem afetar as operações de arquivo para o grau que você tinha em mente;
  • Tente mover segredos e logs de fora da raiz da web;
  • Certifique-se de que os scripts são compatíveis com as restrições do modo safe mode;
  • Use session_save_path () ou definir session_save_path em um arquivo .htaccess;

Ataques no sistema de arquivos

Outras recomendações
importantes de segurança

Questões linguísticas

Questões linguísticas

 

Programando de maneira mais segura em PHP

Existem algumas características da linguagem que se forem ignoradas podem em algum momento comprometer a segurança da aplicação.
Vamos a elas:

Questões linguísticas

 

Programando de maneira mais segura em PHP

  • Evitar comparações fracas ( usar == ao invés de === );
  • Sempre checar o tipo e conteúdo da informação enviada;

  • Forçar a informação para determinado tipo forçando a converção.
    Exemplo:
    (int) $variavel  ;
     

Tipagem fraca

Como resolver:

Programando de maneira mais segura em PHP

Questões linguísticas

 

Programando de maneira mais segura em PHP

 

  • Forçar o tipo de variáveis de parâmetro e de retorno em funções e métodos de objeto (recursos novos do PHP 7.0 e 7.1 e parcialmente implementados nas versões anteriores);  

Tipagem fraca

 

Questões linguísticas

 

Programando de maneira mais segura em PHP

 

Muitas bibliotecas da linguagem usam meios diferentes de reportar um determinado erro (algumas retornam um array com informações de código de erro, outras disparam exceções, etc, etc) permitindo que um código defeituoso continue rodando;

Exceções e manipulação de erro

 

Questões linguísticas

 

Programando de maneira mais segura em PHP

Segundo o OWASP:

Em muitas outras línguas, e a maioria das linguagens de alto nível que competem com PHP, condições de erro que são causados ​​por erros de desenvolvedor, ou erros de execução que o desenvolvedor não conseguiu prever, fará com que o programa pare de correr, que é a coisa mais segura a fazer .

Exceções e manipulação de erro

 

Questões linguísticas

 

Programando de maneira mais segura em PHP

Exceções e manipulação de erro

Muitos erros e exceções podem ter acontecido e não serão mostrados nesse contexto.

É importante, no contexto desse código que o programador saiba tudo o que acontece e onde não foi possível concluir determinada operação ( ex: Erro de login do banco, banco não encontrado, query inválida, etc etc );

Isso não deve ser mostrado ao usuário final, pois pode gerar informação para um possível atacante do sistema;

Questões linguísticas

 

Programando de maneira mais segura em PHP

Exceções e manipulação de erro

Uma abordagem possível:

Gerar uma exceção, parando a execução do programa e gravando em log qual foi a exceção ocorrida em detalhes para um debug por parte do desenvolvedor/ administrador do sistema;

Questões linguísticas

 

Programando de maneira mais segura em PHP

Esta característica muitas vezes esconde erros por parte do desenvolvedor ou injeções de dados inesperados:

 

Tipagem fraca

 

Questões linguísticas

 

Programando de maneira mais segura em PHP

Owasp recomenda

 

  • Utilização do PDO com as frags ERRMODE_WARNING or ERRMODE_EXCEPTION ativadas, quando possível;
     

  • Ele também sugere que sempre que possível utilize o máximo de informações possíveis que possam ser obtidas, utilizando a função error_reporting function;
     

  • Não suprimir erros e seguir sempre os detalhes das informações de alerta, para escrever um código de melhor qualidade;


PHP deve ser atualizado regularmente
 

PHP deve ser atualizado regularmente

 

Programando de maneira mais segura em PHP

Você deve manter atualizado regularmente e versão do PHP que você usa em seu servidor.

Caso você tenha receio de parar sistemas de produção com essa prática, mesmo que mantendo a mesma versão do PHP atualizada com Patchs de segurança você pode:

 

 

 

 

 

PHP deve ser atualizado regularmente

 

Programando de maneira mais segura em PHP

  • Criar um ambiente de integração contínua que teste o código rodando em diversos ambientes de configuração;

  • Antes de realizar qualquer atualização realizar um backup de imagem, guardando arquivos e configurações do ambiente e seus respectivos componentes instalados/configurados;

  • Vale ressaltar, como anteriormente, que a configuração do PHP.ini deve ser detalhadamente revisada, para evitar falhas de segurança por configurações.


Conheça bem o que você usa
 

Questões de Framework

 

Programando de maneira mais segura em PHP

Conheça bem o que você usa

Frameworks normalmente utilizam recursos sensíveis a segurança.

Esses recursos devem ser programados de maneira a evitar problemas de segurança.

Questões de Framework

 

Programando de maneira mais segura em PHP

Roteamento

 

Não existe um padrão na linguagem para roteamento de urls fazendo com que várias soluções diferentes sejam implementadas nesse aspecto.

O problema disso é que programadores desavisados podem criar seus próprios meios abrindo brechas de segurança.

 

Questões de Framework

 

Programando de maneira mais segura em PHP

Roteamento

 

Vejamos algumas vulnerabilidades possíveis:

 

Vulnerabilidade de execução remota - durante o upload de arquivos, se sobe um arquivo que pode ser executado pelo servidor remotamente ao invés de ser simplesmente disponibilizado.
Nesse caso devem ser checados todos os arquivos enviados via upload para aplicação;

 

 

Questões de Framework

 

Programando de maneira mais segura em PHP

Roteamento

 

Vejamos algumas vulnerabilidades possíveis:

 

Visualização de códigos sensíveis - Código fonte, incluindo arquivos de configuração, são armazenadas em diretórios acessíveis ao público junto com os arquivos que se destinam a ser baixado (como ativos estáticos).
Nesse caso é recomendado como única solução pelo OWASP o uso de arquivos .htaccess para limitar esses acessos;

 

 


Seja criterioso
 

Cuide bem do seu array

 

Programando de maneira mais segura em PHP

Seja criterioso

Ao utilizar os arrays do PHP, mantenha uma uniformidade ao buscar as informações e cuidado para não confundir seus valores:

Ex: No PHP podemos declarar um array assim:

 

$array = array( “Betho”=>”Jamayca”, “Karla” => “Pierez”);

 

 

 

Cuide bem do seu array

 

Programando de maneira mais segura em PHP

Seja criterioso

Logo não faz sentido esperar uma informação determinada em $array[0] já que você está  usando um nome como chave de valor;

 

 

 

Cuide bem do seu array

 

Programando de maneira mais segura em PHP

Seja criterioso

Para ter certeza desse comportamento, ou seja, quando usar como chave o índice padrão, ou usar um nome como chave, você pode usar as funções array_values ( retornaria array([0] = “Jamayca”, [1] = “Pierez”) ou array_keys ( retornaria array([0]=>”Betho”, [1] = “Karla”)) em seu foreach.

 

Cuide bem do seu array

 

Programando de maneira mais segura em PHP

Seja criterioso

Esse pequeno detalhe de comportamento gerou um problema de segurança grave já corrigido no Drupal 7 segundo esse link: https://www.drupal.org/SA-CORE-2014-005


Estude o comportamento das funções
 

Funções que não ajudam completamente

 

Programando de maneira mais segura em PHP

Estude o comportamento das funções

Existem algumas funções como addslashes, mysql_escape_string e mysql_real_escape_string podem não realizar completamente suas funções ou não estão sendo mais suportadas em versões da linguagem futuras ( deprecated ).

Evite usar $_REQUEST

 

Programando de maneira mais segura em PHP

Este super global não é recomendado, uma vez que inclui não apenas dados de GET e POST, mas também os cookies enviados pelo pedido.

Todos estes dados são combinados em uma matriz, o que torna quase impossível determinar a fonte dos dados.

Isso pode levar a confusão e torna seu código propenso a erros, que podem levar a problemas de segurança.

 

 

Evite usar $_REQUEST

 

Programando de maneira mais segura em PHP

Curiosidade bacana :

Quando utilizamos o $_REQUEST o PHP prioriza a precedência das variáveis globais de acordo com a configuração variables_order.

Por padrão ele obedece a sequencia EGPCS (Environment, Get, Post, Cookie, e Server):

 

 

Evite usar $_REQUEST

 

Programando de maneira mais segura em PHP

Curiosidade bacana :

 

Se retirarmos algumas dessas letras, a super global $_REQUEST não conseguirá pegar alguma dessas possibilidades:

Ex: variables_order: "SP"

//$_SERVER e $_POST somente

 

(fonte: http://php.net/manual/en/ini.core.php#ini.variables-order).

Filtrar todos os dados enviados

 

Programando de maneira mais segura em PHP

  • Conforme passado anteriormente, mas completando, os dados enviados via $_SERVER, $_GET, $_POST, $_REQUEST, $_FILES e $_COOKIE devem ser filtrados;

  • Nem todos os dados em $_SERVER pode ser falsificado pelo usuário, mas uma quantidade considerável no que puder, em particular e, especialmente, tudo o que lida com cabeçalhos HTTP (que começar com HTTP_);

 

Programando de maneira mais segura em PHP

Código PHP de terceiros

 

As bibliotecas e os projetos escritos em PHP são muitas vezes inseguros devido aos problemas destacados acima, especialmente quando frameworks web adequadas não forem usados.

Não confie em código PHP que você encontrar na web, como muitas vulnerabilidades de segurança pode se esconder em código aparentemente inocente.

Programando de maneira mais segura em PHP

Código PHP de terceiros

 

Código PHP mal escrito muitas vezes resulta em avisos sendo emitidos, que podem causar problemas.

Uma solução comum é desligar todos os avisos, que é exatamente o oposto do que deveria ser feito (ver acima), e leva a progressivamente piora do código.

 

Uploads de arquivo

 

Programando de maneira mais segura em PHP

  • Todo o arquivo enviado via UPLOAD deve ser verificado em seu tipo e conteúdo;

  • A verificação do tipo de arquivo enviado deve ser feita através de extensões/librarys específicas para isso pois códigos como $_FILES['some_name']['type'] podem ser manipulados, por ser uma informações enviadas via cliente;

Uploads de arquivo

 

Programando de maneira mais segura em PHP

  • Uma sugestão de extensão para ser usada e presente no OWASP é http://php.net/manual/pt_BR/class.finfo.php;

  • Uma solução que pode ajudar parcialmente neste processo é utilizar serviços de Storage de informações, ao invés de guardar os arquivos enviados no mesmo servidor que sua aplicação, fazendo com que a execução do arquivo, dessa forma, seja dificultada;

Obrigado!

Programando de maneira mais segura em PHP

Não deixem de acessar o OWASP e outras referências de segurança.

 

Segurança é um processo de melhoria contínua.

 

Grande abraço!

 

Créditos das imagens:

https://giphy.com/
https://gifaknet.tumblr.com/

Programando com PHP de maneira mais segura

By thiagotoledo

Programando com PHP de maneira mais segura

Palestra sobre segurança no PHP baseado em recomendações presentes no projeto OWASP

  • 205