PHP – 15 dicas sobre segurança no desenvolvimento

PHP – 15 dicas sobre segurança no desenvolvimento

3 de maio de 2018 1 Por Ramos de Souza Janones
Como vender Software - Seja desktop, web ou MobilePowered by Rock Convert
Powered by Rock Convert

Separamos 15 dicas que vão ajudá-lo a garantir a segurança do seu sistema desenvolvido em PHP. Conheça as melhores práticas em desenvolvimento PHP.

 

Desenvolver uma aplicação web não é uma das tarefas mais fáceis do mundo. Embora cada vez mais ferramentas e linguagens de programação prometam facilitar todo o trabalho, sempre haverá uma questão que jamais será resolvida sem alguma expertise da parte do desenvolvedor: a segurança.

Além de garantir a segurança dos usuários e das transações, um sistema web seguro também deve garantir a integridade do servidor que o hospeda. Por esse motivo, os profissionais da área devem estar sempre preparados e bem informados sobre as principais ameaças e as técnicas que ajudam a evitá-las. E, pode apostar, essa não é uma tarefa tão simples quanto parece: há uma infinidade de procedimentos que podem ser adotados para evitar uma infinidade maior ainda de acessos ou uso indevido de dados e recursos.

Separamos algumas dicas que podem ajudá-lo a garantir a segurança do seu sistema desenvolvido em PHP. Confira-as:

1. Sempre use nomes de cookies de sessão diferentes

Para evitar que ocorra os chamados roubos de sessão, é sempre bom definir nomes

Curso online PHP do Zero ao Profissional.

Curso online PHP do Zero ao Profissional.

diferentes para os cookies de sessão. Por exemplo, o nome padrão utilizado pelo PHP para guardar ids de sessão é “PHPSESSID”. Logo, mudar esse nome dificultará a ação de qualquer cracker que queira se aproveitar da sua aplicação.

Outra dica interessante é usar nomes diferentes para cada acesso e vinculá-lo a algo do acesso do visitante.

 

 

 

Nome de sessão diferente para cada usuário

2. Só acesse cookies de sessão via HTTP

Embora os ids de sessão sejam armazenados em cookies por padrão no PHP, o atributo session.cookie_httponly não vem como padrão. Ativando-o você garante que os cookies de sessão só poderão sre acessados via HTTP, impedindo que scripts JavaScript, por exemplo, sejam barrados ao tentar fazer o mesmo. Essa á uma ótima dica para evitar principalmente ataques XSS.

Curso de PHP ERP com NFe.

Para mudar a configuração, vá até o arquivo php.ini do PHP, procure pelo atributo session.cookie_httponly e defina seu valor como 1.

3. Atribua um limite de tempo de vida para as sessões

Mesmo que um cracker consiga acessar o seu sistema roubando uma sessão, ele terá pouquíssimo tempo para agir se você limitar o tempo de vida das sessões.

Defina um tempo limite de vida para suas sessões

4. Valide a origem da sessão em todas as páginas

Garanta que o usuário que se autenticou no sistema é o mesmo que está acessando a página atual validando o User Agent e o IP do dono da sessão em todas as páginas.

Valide a origem das sessões em todas as páginas

5. Evite Spoofing de formulário

O Spoofing de formulário ocorre quando uma postagem é feita em um dos formulários do seu site de um local inesperado e/ou desconhecido. Neste caso, uma técnica que pode ajudar a evitar esse tipo de ataque é a utilização de um token. Nele, você pode guardar uma chave na sessão no momento em que o formulário é exibido e, quando os dados forem postados, utilizá-la para comparar se a chave enviada é a mesma gravada na sessão anteriormente.

Vale lembrar, no entanto, que essa dica deve ser implantada em formulário mais simples – para casos mais complexos, a alternativa mais efetiva contra robôs continua sendo o uso do Captcha.

Evite que dados sejam postados nos formulários de outros lugares

6. Nunca esqueça de validar dados externos

Jamais se esqueça de validar os dados que chegam à sua aplicação via comandos GET, POST, COOKIE ou SERVER, pois todos eles podem ser manipulados e merecem ser verificados. Essa prática é especialmente importante para evitar ataques do tipo XSS e SQL Injection.

Para esta tarefa, pode-se usar as validações que vêm nativamente no PHP. Veja alguns exemplos abaixo:

Nunca deixe de validar os dados que chegam à sua aplicação de fora

7. Valide os arquivos enviados ao servidor

É cada vez mais raro encontrarmos sistemas que não oferecem a possibilidade de enviarmos algum arquivo para armazená-lo no servidor. Se o seu utiliza esse recurso, então nunca esqueça de validar os uploads antes de salvar os arquivos no servidor. Dessa forma você evita que arquivos maliciosos sejam armazenados e causem algum dano ao seu servidor e sistema.

Vale ressaltar, no entanto, que validar apenas a extensão do arquivo já não é mais suficiente, pois ela pode ser manipulada no momento do envio. Para uma solução completa, é preciso verificar o cabeçalho do arquivo. No caso de imagens, uma boa alternativa é a seguinte:

Validar os arquivos enviados para o servidor também é importante

8. Impeça que suas pastas sejam acessadas via HTTP

No PHP, inúmeras configurações ficam armazenadas em arquivos com extensões ini, XML, JSON, txt e outras. O pior de tudo é que o conteúdo desses arquivos é visível quando acessados pelo navegador, o que acaba sendo um problema se ali contiver informações confidenciais.

Para evitar esse problema, a melhor alternativa é proteger as pastas que contêm esses arquivos contra acessos externos. Para isso, basta colocar esses arquivos fora da pasta public_html ou adicionar um arquivo .htaccess com as seguintes configurações nas pastas que se deseja proteger:

Bloqueie o acesso às suas pastas via HTTP

9. Mantenha o controle dos erros do sistema

Não adianta: por mais que você previna que erros ocorram na sua aplicação, aqui e ali eles aparecerão. O problema é que, se não forem bem tratadas, essas falhas podem acabar exibindo dados sobre sua aplicação.

Para evitar isso, defina um arquivo de log para registrar esses erros. Caso haja necessidade de acompanhar esse arquivo de log em tempo real, uma boa opção é acessar o servidor via SSH e usar o comando tail -f pathlog/logfile.

Também há uma configuração que pode ser feita no php.ini para evitar que tudo seja exibido na cara do usuário. Acesse-o e modifique as seguintes linhas para armazenar tudo num arquivo predeterminado:

//php.ini

error_reporting = E_ALL & ~E_NOTICE

display_errors=On

log_error=On

error_log=my_file.log

10. Jamais armazene senhas em texto puro

Chega um momento do desenvolvimento que o cansaço começa a tomar conta de nós e acabamos abrindo mão de alguns recursos de segurança para adiantar os testes do projeto. Contudo, isso não pode acontecer quando o assunto é as senhas de acesso ao sistema. Elas jamais devem ser armazenadas sem antes serem criptografadas. Adotando essa técnica, você protege não só os seus usuários, mas também o banco de dados de uma eventual invasão.

Sempre criptografe as senhas da sua aplicação

11. Fique de olho nos erros de senha

Há quem monitore toda tentativa de acesso ao sistema, quer seja ela bem sucedida ou não. Uma vez com esse controle implantado, é sempre bom ficar de olho e bloquear o IP de origem ou adicionar um Captcha como validação adicional em caso de mais de três tentativas de senha incorreta. Dessa forma você mina as possibilidades de ataques de força bruta.

12. Tenha cuidado com as permissões em pastas

Sempre tenha um pé atrás e restrinja o acesso às pastas do servidor. Adicione regras de execução e escrita somente em pastas aproriadas.

13. Cuidado com servidores compartilhados

Os servidores compartilhados são vistos por uma boa parcela dos desenvolvedores como uma ótima opção de hospedagem principalmente por causa dos preços baixos, que acabam os tornando atraentes. Contudo, o que os iniciantes não sabem é que essa solução também traz consigo algumas preocupações extras com segurança.

Há alguns anos, o PHP tentou resolver parte desses problemas com a diretiva safe_mode, mas chegou-se à conclusão que essa preocupação não era de responsabilidade da equipe de desenvolvimento da tecnologia. Por esse motivo, essa diretiva passará a não existir mais a partir do PHP 6.

Mesmo assim, ainda há três diretivas do php.ini que continuam a desempenhar um importante papel na configuração de hospedagens compartilhadas. São elas:

open_basedir: Com ela, é possível imitar os diretórios que o PHP pode abrir com o fopen ou include.

Powered by Rock Convert

//php.ini 
open_basedir = “/home/user/www/:/usr/local/lib/php/”; 
;foram adicionados dois caminhos separados por “:”

disable_functions e disable_classes: essas duas diretivas funcionam de forma semelhante e permitem que você desabilite certas funções nativas do PHP e classes por razões de segurança.

//php.ini
;desabilitando as funções
disable_functions = exec,passthru,shell_exec,system
;desabilitando as classes
disable_classes = DirectoryIterator,Directory

14. Tenha um plano em caso de comprometimento do sistema

Sempre somos levados a pensar que o pior não acontecerá conosco. Contudo, como o seguro morreu de velho, é sempre bom ter um plano de ação para o caso de você descobrir que seu sistema foi comprometido.

Uma boa dica é desabilitar as contas para que uma investigação seja conduzida a fim de descobrir a falha explorada pelos crackers. Depois disso, defina uma estratégia de reativação das contas utilizando e-mails.

15. Fique sempre de olho no seu sistema

Utilize programas de identificação de vulnerabilidades. Além de identificar os pontos fracos da sua aplicação, esses sistemas oferecem informações sobre elas e ainda podem lhe orientar sobre como resolvê-las.

Se quiser experimentar um desses programas, recomendamos o Netsparker e o Mantra.

Um pouco mais sobre PHP e segurança

As falhas de segurança em servidores web é um assunto que está cada vez mais em evidência, e é necessário que os profissionais estejam sempre bem preparados e conhecendo as principais ameaças e as técnicas que ajudam a evita-las. Garantir a segurança de um sistema não é fácil, existem milhares de procedimentos que visam evitar acessos ou uso indevido de dados e recursos. Abaixo listo algumas dicas incomuns que podem trazer um pouco mais de segurança aos sistemas desenvolvidos com PHP. 

LEIA TAMBÉM:  Começando a programar em Python – Parte 2

Evitando Spoofing de formulário

Spoofing de formulário ocorre quando alguém faz uma postagem em um de seus formulários de algum local inesperado. Uma técnica muito útil contra esse tipo de ataque é o uso de um token, ela consiste em guardar uma chave na sessão no momento que é exibido o formulário, e quando os dados forem postados é confirmado se a chave enviada é a mesma gravada na sessão anteriormente. Essa dica é sugerida para formulários simples e não substitui o uso de Captcha que é uma alternativa mais efetiva contra robôs.

session_start();

if(isset($_POST)){
    if($_SESSION['token'] == $_POST[‘token’]){
        //post valido
    }
}else{
   $_SESSION['token'] = md5(time());
   //adicione o token em um input hidden
}

Sempre valide dados externos

Valide todo dado externo a sua aplicação (dados enviados via GET, POST, COOKIE, SERVER), todos esses dados podem ser manipulados e merecem sua desconfiança e consequente validação, com essa dica evitaremos ataques como XSS e SQL injection. Não se esqueçam de validar também dados externos vindos de terceiros, como RSS e API’s socias.

LEIA TAMBÉM:  PHP 7: Até 9 Vezes Mais Rápido Que o PHP 5.6

Existe uma grande variedade de validações disponível nativamente no PHP, pra diversas situações, abaixo uma forma simples de lidar com dados externos.

/Convertendo caracteres especiais para a realidade HTML
$varLimpa = htmlspecialchars($_POST[‘infoForm’], ENT_QUOTES,UTF-8);

//voltando os caracteres originais
$varSuja = htmlspecialchars_decode($varLimpa );

//filtros
$email = "clifton@example"; //Note the .com missing
if(filter_var($email, FILTER_VALIDATE_EMAIL)){
    //válido
}
//recebendo um parâmetro GET, e validando se é inteiro
$id = filter_input('INPUT_GET', 'id', 'FILTER_VALIDATE_INT');

Confira mais filtros em http://www.php.net/manual/pt_BR/ref.filter.php

Mude o nome do cookie de sessão

Defina um nome para o cookie de sessão, nomes comuns facilitam o seu roubo, também conhecido como session hijacking, PHPSESSID é o nome padrão usado pelo PHP para guardar ids de sessão. Com o nome diferente o hacker não saberá qual o nome do cookie que contem esse id. Outra dica é usar nomes diferentes para cada acesso, usando algo vinculado ao acesso do visitante.

//nome de sessão diferente para cada usuário
session_name(md5('seg'.$_SERVER['REMOTE_ADDR'].$_SERVER['HTTP_USER_AGENT']));

Cookies de sessão só devem ser acessados via HTTP

Ids de sessão devem ser armazenados em cookies, essa é uma regra básica que já vem como padrão na configuração do PHP, algo que não vem como padrão é o atributo  session.cookie_httponly, que garante que os cookies de sessão só possam ser acessados via http, não podendo ser lidos por Javascript por exemplo, com isso estamos evitando ataques como XSS.

//php.ini
session.cookie_httponly=1

Limite o tempo de vida das sessões

Mesmo que os hackers consiga acessar seu sistema roubando uma sessão, eles terão pouco tempo de ação.

session_cache_expire(10); //tempo de sessão igual 10 minutos
session_start();

Valide a cada página a origem da sessão

Valide a cada página o User Agent e o ip do dono da sessão, isso garante que o usuário que efetuou o login é o mesmo que está acessando a página atual.

//adicione no momento do login
if($logado){
    $_SESSION[“donoSessao”] =  md5('seg'.$_SERVER['REMOTE_ADDR'].$_SERVER['HTTP_USER_AGENT']);
}

//a cada nova página adicione o trecho abaixo
$tokenUser = md5('seg'.$_SERVER['REMOTE_ADDR'].$_SERVER['HTTP_USER_AGENT']);

if($_SESSION[“donoSessao”]  != $tokenUser){
    header(‘location:login.php’);
}

Monitore os erros de senha

Em caso de mais de três tentativas de senha incorreta, bloqueie o IP de origem, ou adicione um Captcha como validação adicional, isso dificulta ataques de forca bruta.

Permissões em pastas

Restrinja o acesso às pastas do servidor, ou seja, permissões de execução e escrita somente em pastas apropriadas.

Não armazene senhas em texto puro

Senhas não devem ser armazenadas sem “cifragem”, sempre armazene senhas criptografadas, assim estaremos protegendo também nossos usuários, numa eventual invasão ao banco de dados.

$senha = sha1($_POST[‘senha’]);
if($senhaBanco == $senha){
   //user logado
}

Uploads de arquivos

Sempre valide os arquivos antes de salvar no servidor, isso evita subir arquivos que possam ser executados e consequentemente trazer algum dano ao seu sistema. Validar apenas a extensão do arquivo não é o suficiente, pois esse pode ser manipulado no momento do envio. Quando estamos trabalhando com upload de imagem, podemos usar o trecho abaixo para garantir a manipulação de um arquivo válido.

list($largura, $altura) = getimagesize($_FILES["foto"]["tmp_name"]);

if($largura=="" || $altura ==""){
    //ARQUIVO INVÁLIDO
}

Proteja pastas contra acessos HTTP

Muitas vezes temos dados de configuração de sistemas em arquivos com extensões ini, XML, Json, txt e etc. O conteúdo desses arquivos é visível quando acessados pelo browser, logo, se nele contiver informações confidenciais, elas estarão expostas pra todos na internet. Para evitarmos isso, devemos proteger os diretórios que contenham esses arquivos, contra acessos externos. Podemos colocar esses arquivos fora da pasta public_html ou adicionar um arquivo .htaccess com o código a seguir, nas pastas que queremos proteger.

<Files *.*>

order allow,deny

deny from all

</Files>

Controle de erros

Controle as exceções e erros ocorridos eventualmente no seu sistema evite exibir dados sobre sua aplicação, defina um arquivo de log para registrar esses erros. Caso precise acompanhar as informações do arquivo de log em tempo real, acesse o servidor via SSH e use o comando tail -f pathlog/logfile.

Também escrevi sobre uma forma de acompanhar e ser notificados sobre os erros de sua aplicação aqui.

//php.ini
error_reporting = E_ALL & ~E_NOTICE
display_errors=On
log_errors=On
error_log=my_file.log

Servidores compartilhados

Há uma variedade de problemas de segurança que surgem quando se utiliza soluções de hospedagem compartilhada.

LEIA TAMBÉM:  Quais as linguagens de programação populares no mundo

No passado, PHP tentou resolver alguns destes problemas com a diretiva safe_mode. No entanto, como o manual do PHP afirma, “é arquitetonicamente incorreto tentar resolver esse problema no nível do PHP. “Assim, safe_mode não estará mais disponível a partir do PHP 6. Ainda assim, há três diretivas do php.ini que continuam a ser importantes em uma hospedagem compartilhada: open_basedir, disable_functions e disable_classes. estas diretivas não depende de safe_mode, e eles permanecerão disponíveis para as versões futuras.

open_basedir – Com essa diretiva é possível limitar os diretórios que o PHP pode abrir, com por exemplo fopen ou include.

//php.ini
open_basedir =/home/user/www/:/usr/local/lib/php/;
;adicionamos dois caminhos separados por “:

disable_functions e disable_classes – Os disable_functions e disable_classes funcionam de forma semelhante, permitindo que você possa desabilitar certas funções nativas do PHP e classes por razões de segurança.

//php.ini
;desabilitando as funcoes
disable_functions = exec,passthru,shell_exec,system

; desabilitando as classes
disable_classes = DirectoryIterator,Directory

Desabilite as contas

Se for descoberto que seu sistema foi comprometido, investigue e descubra a falha explorada e principalmente desabilite as contas e defina uma estratégia de ativação utilizando e-mails.

Inspecione seu sistema

Use programas de identificação de vulnerabilidade, eles permitem identificar, oferece informações sobre elas e ainda orienta como resolve-las.

Programas de teste de vulnerabilidade

Para finalizar o artigo, deixo duas dicas de software que ajuda na exploração e resolução de falhas de segurança em sistemas web.

Referências

 

» Programação » PHP

 

 

Subscribe to our mailing list

* indicates required


Além de PHP e MySQL, deseja receber outro tema?

Email Format


Powered by Rock Convert
Siga os bons!
Últimos posts por Ramos de Souza Janones (exibir todos)
vote
Article Rating