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.
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
}
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.
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
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']));
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
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 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’);
}
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.
Restrinja o acesso às pastas do servidor, ou seja, permissões de execução e escrita somente em pastas apropriadas.
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
}
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
}
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 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
Há uma variedade de problemas de segurança que surgem quando se utiliza soluções de hospedagem compartilhada.
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
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.
Use programas de identificação de vulnerabilidade, eles permitem identificar, oferece informações sobre elas e ainda orienta como resolve-las.
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.
Por enquanto é isso, espero ter ajudado.
fonte: https://imasters.com.br/back-end/seguranca-em-aplicacoes-web-com-php