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:
PHP Security Cheat Sheet e PHP Top 5
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
- Execução Remota de Código
- Cross site scripting (XSS)
- SQL Injection
- Configuração do PHP
- 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:
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
- 697