Você está na página 1de 16

Principios

Defesa em Profundidade
Defesa em profundidade é um conceito de segurança que extrapola o contexto
da programação de computadores. Diz que sempre devemos nos antever a
possibilidade de algo dar errado, como no caso de mergulhadores que sempre
usam dois cilindros. O cilindro principal pode nunca ter apresentado problemas,
mas nem por isso deixa-se de usar um reservar.
Em programação isso significa que sempre devemos ter um plano de proteção:
caso um método falhe, é preciso que haja outra camada de protenção para
conter a ausencia da primeira. Isso pode ser visto, por exemplo, quando em
algumas operações críticas em sistemas, mesmo que o usuário já esteja
autenticado, é requisitado que ele digite a senha novamente.
É importante apenas observar que os custos de segurança nunca podem
extrapolar os custos daquilo que está sendo protegido.

Privilégio Minimo
Outro conceito utilizado fora do contexto da computação, o privilégio mínimo
diz que: o privilégio dado a uma entidade deve ser o mínimo necessário para
que ele execute sua função. Isso evita que recursos sejam utilizados de forma
indevida.
Um exemplo seria a chave de um carro que só pode ser usada para ligar o
automóvel. Desta forma, ao passar a chave para um manobrista, ele pode
executar sua função de motorista sem ter capacidade de abrir outros
compartimentos do carro que estejam trancados.
Na progração isso pode ser entendido como conceder os privilégios mínimos a
usuários e sistemas que compõe nossa arquitetura de software e hardware.

Simplicidade
Códigos deve ser o mais simples possível, pois a complidade pode abrir brecha
para que erros ocorram.

Minimizar Exposição
Aplicações online requer frequente comunicação entre o sistema e fontes
remotas. Uma das fontes mais comuns são os navegadores de Internet
utilizado por bilhões de usuários todos os dias. Se é realizada a prática do
rastreamento é possível saber quando os dados estão sendo expostos.
A exposição de dados nem sempre representa um risco, mas alguns dados são
sensíveis o suficiente para receberem atenção neste sentido.
Uma das formas de sanar o problema é utilizar técnicas de criptografia no
tráfego dos dados, como a utilização de SSL. Isso já é suficiente para criar uma
primeira cada de proteção para que os dados não seja visualizados por quem
não for de direito. Porém, algumas vezes, podemos escolher adicionar uma
cada adicional que incluí minizar a exposição do dado simplesmente não
trafegando ele completamente. Um exemplo disso é quando trafegamos
apenas os 4 últimos do número do cartão de crédito.
Para minizar a exposição do dado, por tanto, é necessário antes analisar os
dados que serão trafegados, identificar quais são sensíveis, fazer seu
rastreamento, e ver onde é necessário atuar para diminuir sua exposição.
Práticas
Proteção versus Usabilidade
Proteção e usabilidade não são características exclusivistas. Porém, para que
ambas estejam presentes em um sistema, é preciso fazer considerações de
forma que para a obtenção de uma característica, a outra não fique
comprometida.
Um das formas de se fazer isso é buscar técnicas de proteção que sejam
transparentes ao usuário. Não sendo possível, pode-se escolher entre técnicas
de segurança em que os usuários já estejam familiarizados.

Rastreamento dos Dados


A prática mais importante quando falamos da segurança dos dados é fazer um
restramento dos dados. Isso não inclui apenas registrar o que é o que, mas de
onde vem e para onde vai. Para isso é muito importante conhecer também as
características do ambiente pelo qual os dados serão trafegados e
armazenados.

Filtragem da entrada dos dados


Outra prática muito importante é realizar a filtragem dos dados de entrada da
sua aplicação. A filtragem permite garantir que os dados que entram na nossa
aplicação estão da forma que deveriam estar, diminuindo a chance de
manipulação destes dados como forma de obter recursos e privilégios
inesperados.
Essa prática pode ser dividida em três etapas:
1. Identificar a entrada do dado;
2. Filtrar o dado que entrou;
3. Fazer distinção entre o dado que entrou e o filtrado.
PHP possui arrays globais que nos ajudam a identificar quais são os dados de
entrada. Entre estes arrays podemos citar: $_POST, $_GET, $_SERVER,
$_COOKIE. Alguns não consideram $_SESSION como uma entrada de dado,
mas como o identificador da sessão é (geralmente vinda através de
$_COOKIE), é importante considera-lo.
Existem várias formas de se realizar a filtragem dos dados, umas mais seguras
que as outras. Uma das consequencias de não realizar a filtragem dos dados
são os ataques de manipulação de caminhos de arquivo, injeção de SQL, etc.
Fazer a distinção entre os dados filtrados ou não trás, além da vantagem óbvia
de qualquer dados utilizar, a possibilidade manipular os dados fora do escopo
no qual entrarão e finir qual será o conjunto de dados válido a ser utilizado. O
que é criado pelo programador é considerado um dado seguro, o que é obtido
como entrada não é garantido que seja. Para os casos em que não queremos
que um dado criado pelo programador seja substituído por um de entrada,
podemos utilizar constantes no lugar de variáveis.

Tratamento de Caracteres na Saída


Este tópico é relacionado ainda a filtragem de dados, mas enquanto a atividade
anterior está mais associada a entrada dos dados, o tratamento de caracteres
está mais relacionado a saída deles.
Este tipo de tratamento é muito comun com caracteres especiais que podem
levar a um comportamendo inesperado quando estamos passando os dados
como entrada para outros sistemas, como bancos de dados e navegadores de
Internet.
Para tratamento de dados que serão exibidos em navegadores podemos
utilizar a função htmlentities().
Quando a saída é para um banco de dados (MySQL) temos a função
mysql_real_escape_string(). Cada banco de dados tem sua respectiva função.
No caso de não have, podemos utilizar addslashes().
Globais
O parametro register_globals permite que uma série de informações de fontes
remotas é criado.
Isso não cria uma brecha em si, mas pode maximizar os dados de quando
ocorrer um ataque.
Caso seja necessário o uso, é preciso que o parametro error_reporting esteja
configurado para E_ALL | E_STRICT.
Erros
É importante definir o erro_reporting como da forma mais estrita possível para
que nenhum erro passe despercercebido.
Caso se esteja utilizando um servidor compartilhado e não tiver acesso as
configurações do php.ini, é possível utilizar a função init_set(<propriedade>,
<valor>) para alterar suas configurações em tempo de execução.
No caso de estar executando em produção, é preciso que a exebição dos erros
seja desabilitada através da configuração display_errors.
É possível criar uma função específica para tratar os erros através da função
set_error_handler(<nome da funcao>[, <nivel de seguranca>]). A assinatura da
função passada deve ser:
minha_funcao_de_erro(<numero>, <string>, <arquivo>, <linha>, <contexto>)
Ataques
URL semântica
Envio de Arquivos
 is_uploaded_file()
 move_uploaded_file()

XSS
XSS ou Cross-Site Script é talvez um dos tipos de ataques mais conhecidos,
presente em um grande número de plataformas.
Todo sistema de uma forma ou de outra exibe o conteúdo de uma entreda de
dados. E caso as entradas não sejam filtradas, o sistema está em risco.
Um tipo de ataque seria em um formulário de comentários que, ao ser
submetido, tem o conteúdo da sua caixa de texto inserido no site. Um atacante
poderia simplemente comentar um código JavaScript que, uma vez carregado
na página (como um comentário) seria executado por todos os demais
visitantes. Dessa forma, este script poderia enviar para um site remoto as
informações de cookie de todos os usuários, incluindo tokens.

CSRF
Ataque que consite fazer com que outro computador realize requisições de
forma inadvertida.
No caso do PHP, este ataque pode ser maximizado quando tratamos
requisições utilizando a variável global $_REQUEST ao invés de $_POST.
Dessa forma, uma tag HTML (como uma imagem) pode adicionada à página e,
cada vez que o HTML for requisitado, ao tentar carregar o endereço da
imagem, na verdade, a vítima estará fazendo requisições para um outro
endereço.
Isso pode permitir ataques do tipo que o atacante conhece a estrutura de
requisição para compra em um comercio eletrônico. Caso a vitima esteja
logada nesse site, toda vez que acessar o endereço ele irá fatalmente realizar
uma compra de produtos sem que saiba disso.
Uma das formas de evitar este tipo de ataque fazer uma validação saber se,
quem está postando a informação para o endereço é o mesmo que carregou o
formulário HTML. Isso pode ser feito gerando um token no momento da
requisição da página, salva-lo numa sessão e ao submeter o formulário este
token deve ser enviado para ser feita a comparação. A validade do token pode
ser controlada para alguns minutos.
Formulários Modificados
Este ataque consiste em conhecer a estrutura de um formulário (ou dos dados
que serão submetidos) e então alterar a estrutura da requisição para tentar
alterar o comportamento da resposta do servidor.
Um exemplo seria um formulário de envio de arquivos onde um campo
maxlength fosse usado para para controlar o tamanho máximo do arquivo.
Assim, ao reproduzir este formulário em outro local, o atacante poderia
simplesmente alterar este valor para que o servidor passasse a aceitar um
arquivo muito maior que seria enviado. Desta forma poderia-se, por exemplo,
preencher todo espaço de armazenamento do servidor.
A solução para este tipo de ataque seria evitar submissões que viessem de
servidores diferentes, e também a filtragem dos dados de entrada.

Requisições HTTP Modificadas


O HTTP é um protocolo aberto, por tanto, inseguro. Este ataque basicamente
consite em utilizar um cliente HTTP (que não o cliente que a aplicação
servidora espera se comunicar) para gerar requisições configuradas
manualmente para tentar descobrir comportamentos inesperados do servidor.
As soluções para este tipo de ataque são as mesmas para o ataque de
Formulários Modificados: firewalls e filtragem dos dados recebidos pela
aplicação.
Nunca devemos confirmar nas informações que chegam através de uma
requisição HTTP.

Credenciais de Bancos de Dados Expostas


Este ataque explora a vulnerabilidade de alguns sistemas em colocar
informações de conexão em arquivos que podem ser requisitados como texto
puros.
Isso acontece, por exemplo, em arquivos de configuração que possuem a
extensão .inc, e o servidor web está configurado para tratar este tipo de arquivo
como um arquivo de texto comum.
A solução para este caso é alocar tais arquivos de configuração fora do
diretório document root.
No caso do PHP, podemos utilizar a extensão dos arquivo de configuração
como .php. Dessa forma o servidor web não iria retornar seu conteúdo como
texto aberto.

Injeção de SQL
Um dos tipos de ataque mais comuns. É aquele em que o atacante envia os
dados para acesso a um banco de dados em um formato que mofique a
instrução SQL original. Dessa forma ele poderá enviar consultas e comando
inesperados ao servidor de banco de dados.
Ataques de Injeção de SQL são facilmente evitados. Uma das formas de
dificultar este tipo de ataque é: (1) não utilizar o nome dos campos de sua
aplicação como o mesmo nome dos campos na tabela de banco de dados. (2)
não permitir que as mensagens de erro do banco de dados sejam retornadas
para a aplicação cliente; (3) e finalmente utilizar funções para filtrar os dados
de entrada de forma que não permita a modificação da consulta original.

Dados em SGBD Expostos


É importante que dados sensíveis sejam gravado no banco de dados de forma
encriptada.

Roubo de Cookies
Cookies podem armazenar dados sensíveis como tokens de acesso. Caso
estes dados sejam roubados.
Cookies podem ser roubados através de técnicas de XSS ou falhas de
segurança nos navegadores.

Exposição de Dados de Sessão


Sessão quase sempre são salvas no ambiente do servidor de aplicação. A
forma de roubar seus dados seria tendo acesso ao local onde a sessão é
armazenada, ou durante o tráfego destes dados (que pode ser evitado com o
uso de SSL).
A função session_set_save_handler() pode ser usada para alterar o
comportamento padrão para armazenamento de sessão do PHP.

Fixação de Sessão
Existem três formas de obter o identificador da sessão de um usuário: (1)
descobrir, (2) capturar, ou (3) fixar. Este ataque implica que definir de forma
arbitrário o identificador da sessão da vitimos, para que o atacante sempre
tenha acesso ao tokem e possa fazer requisições por ele mesmo.

Roubo de Sessão
Ataque mais comum quando falamos de sessão. Nela um invasor tenta fazer
uso de uma sessão já existente consumido os recursos dela.
Para que este ataque ocorra, a primeira coisa a ser feita é obter um número de
sessão valido.
O principio da Defesa em Profundidade pode ser utilizado neste caso, criando
obstaculos que possam identificar o real dono daquela sessão (como
armazenar o agente que o cliente usou para gerar a sessão).
Outra forma de proteção é sempre propagar um token através da URL. O token
pode ser gerado usado informações do primeiro acesso do usuário utilizando
uma palavra chave como complemente. Essa seria uma seguda camada de
proteção.
Exposição de Código Fonte
Vulnerabilidade que expõe o código fonte do sistema. Isso ocorre quando
usamos um arquivo de extensão que o servidor interpreta como arquivo de
texto e arquivos para inclusão são inseridos dentro do documento root.
<Files ~ “\.inc$”>
Order allow, deny
Deny from all
</Files>

Entrada pelos fundos com URL


Entrada pelos fundo com URL (Backdoor URL) é a vulnerabilidade que permite
acesso a arquivos sensíveis diretamente através da URL.
A solução para isso é colocar tais arquivos fora da pasta document root.
Manipulação de Arquivos
Vulnerabilidade que permite ao atacante especificar qual arquivo ele deseja ter
acesso. Isso ocorre muito no caso de inclusões de arquivo de forma dinâmica
durante sua execução.
<?php
include “/cache/{$_GET[‘meu_arquivo’]}.html”;
?>

Injeção de Código
É a vulnerabilidade que permite ao invasor incluir arquivos externos a execução
do sistema.
<?php
include “{$_GET[‘caminho’]}/cabecalho.inc”;
?>
A solução para isso é fazer o controle de cada tipo de caminho de diretório que
pode ser passado como parametro.

Atravessando o Sistema de Arquivos


Ataque que consiste passar nomes de arquivos que tentem navegar pelo
sistema de arquivos do sistema operacional.

Arquivos Remotos
Vulnerabilidade que permite recuperar trechos de códigos em fontes não
confiáveis que podem permitir a execução de códigos maliciosos.
No PHP isso pode acorrer quando a diretiva allow_url_fopen está habilitada,
permitindo a recuperação de uma váriada diversidade de conteúdos de fontes
de dados remotas.
Tal vulnerabilidade pode ser porta de entrada de outros ataques, como Cross-
Site Scripting e SQL Injection.
A solução para isso é filtrar os arquivos de entrada que podem ser utilizados
com a função file_get_contents(). Além disso, o conteúdo obtido também deve
ser filtrado (seja HTML, instrução SQL, ou outros) antes de ser efetivamente
utilizado no sistema.

Injeção de Comandos
Ataque que explora vulnerabilidade que permita ao invasor executar comandos
de sistema operacional.
O PHP possui a função exec() que é responsável por passar comandos para o
sistema operacional.

Força Bruta
Consiste em tentar a autenticação de forma exautiva até que a credencial
correta seja descoberta.
As soluções para isso são:
 Aumentar o tempo entre cada tentativa de autenticação;
 Buscar identificar entre uma autenticação humana ou de máquina;
 Limitar o número de tentativas;
 Utilizar códigos captcha.

Farejando Senhas
Farejando Senhas (Password Sniffing) é o ataque que explora a
vulnerabilidade de um sistema onde as credenciais trafagam desprotegidas
entre os usuários e ele.
A solução para isso é utilizar SSH para que o tráfego destas informações
ocorra de forma criptografada.

Ataque de Resposta
Ataque de Resposta (Raplay Attack) ou Ataque de Apresentação (Presetation
Attack) é a vulnerabilidade explorada em que um invasor faz uso de credeciais
válidas para gerar requisições não autorizadas.
Isso acontece quando protegemos as informações, mas não protegemos os
dados que dão acesso as informações.
Um exemplo seria um programa cliente que, para não revelar o password de
um usuário, usa um hash antes de envia-lo para a rede. Neste caso o
password original estaria protegido, mas alguem que tivesse acesso ao hash
poderia enviar requisições se fazendo passar pelo usuário original.
Isso pode ser explorado nos casos em que o código de acesso é também
armazenado em cookie, fazendo com o que o acesso do usuário seja
permantente. Uma forma de mitigar este ataque seria, por tanto, conceder tais
credenciais com um tempo limitado de uso. Isso esta relacionado ao próximo
tipo de ataque.

Login Persistente
É um recurso de navegadores web que permitem que o usuário permita
permanecer logado muito tempo, após encerrar seu uso no sistema, mesmo
depois do tempo de sessão ter expirado. O Login persistente trás problemas de
segurança, mas aumenta a usabilidade do sistema. Isso pode ser visto nos
casos em que, ao invés de pedir que o usuário se autentique no sistema a cada
visita, ela tenha a opção de “permanecer logado”.
A forma mais tradicional de fazer este login persistente é armazenar usuário e
senha em um cookie. Assim, ao invés do usuário digitar estas informações,
elas são simplesmente recuperadas do cookie. Como isso não altera em nada
a implementação das rotinas de autenticação, é muito fácil sua implementação.
Ao invés de armazenar o usuário e senha, é possível gerar um token para cada
acesso e armazena-lo em uma sessão. Porém, armazena-lo em uma sessão
não irá ajudar a criar um login permanente, já que a sessão irá espirar.
Neste caso, é indicado colocar no cookie apenas o nome do usuário (que é
uma informação menos sensível que a senha) e usar este nome para saber a
qual usuário o token pertence. Ou melhor, gerar para cada usuário uma outra
informação que irá o identificar, sem que revele seu nome de usuário.
Podemos gerar este identificador através do hash da combinação de uma
palavra chave (chamada de SALT) e uma informação fixa do usuário, como seu
nome de usuário.
Algumas considerações devem ser levadas em conta:
 O Cookie pode expirar em uma semana ou menos;
 A utilização de cookie é valido cada autenticação. No caso de uma nova,
um novo cookie deve ser gerado;
 Podemos liberar o acesso ao sistema de forma permanente, mas na
hora de executar funções mais sensíveis pedir a senha.
Configurações PHP
allow_url_open
Permite acessar fontes remotas como se fossem locais. Essa propriedade deve
ser desabilitada.

disable_functions
Propriedade que permite desabilitar funções que podem ser perigosas de
alguma forma.
// php.ini
disable_functions = exec,passthru,shell_exec,system 
disable_classes = DirectoryIterator,Directory 
display_errors
Exibição de erros é importante durante o desenvolvimento. Durante a produção
esta propriedade deve ser desabilitada.

enable_dl
Permite carregar extensões PHP em tempo de execução. Deve ser
desabilitado sempre que possível.

error_reporting
Deve estar configurado ao menos para E_ALL. E_ALL | E_STRICT é
recomendado.

file_uploads
Permite definir quais tipos de arquivos podem ser carregados via upload.
Se o programa não necessita do envio de arquivos, essa opção deve ser
desabilitada.

log_errors
Deve ser habilitado quando display_erros está desabilitado. O caminho para o
log deve ser configurado na opção error_log.

magic_quotes_gpc
Faz o escape de todos os dados de entrada em $_POST, $_GET, $_COOKIE
utlizado operações semelhantes a addslashes().
Deve ser desabilitada por duas razões: modifica os dados de entrada sem o
controle do programador e, no caso de Injeção de SQL, é melhor utilizar as
funções do seu banco de dados.
memory_limit
Permite definir a quantidade de memória alocada para a execução do
programa.
A quantidade de memória vai variar de aplicação para aplicação. O valor por
tanto deve ser testado, mas sempre indicado um limite.
Essa diretriz irá funcionar apenas se compilamos o PHP com a opção –enable-
memory-limit.

open_basedir
Faz com que os arquivos que podem ser abertos pelo PHP estejam restritos a
um determinado diretório.

register_globals

safe_mode

session.cookie_httponly
Permite que cookies sejam acessados apenas via HTTP, e não através de
requisições JavaScript.
Funções PHP
exec()
Executa funções do sistema operacional. Deve ser evitado.

file()
Pode ser utilizado em detrimento de fopen(), principalmente nos casos em que
allow_url_fopen estiver habilitado.

include
Não utilizar caminhos não filtrados.

preg_replace()
Não utilizar máscaras em que a informação seja passada pelo usuário.
Dicas
Inicialize todas as variáveis antes de utiliza-las.
Utilize nomes de armazenamento de dados de sessão diferentes que o padrão.
Use session.cookie_httponly para evitar ataques de XSS.
Atribuir um tempo de vida as sessões.
É possível validar se o usuário que gerou a sessão é o mesmo que utiliza o
token através de informações pessoais, como o IP.
Para evitar ataques de formulários modificados, é possível gerar um token para
cada formulário carregado pelo cliente e aceitar somente envios que possuam
tais tokens validos.
Valide dados, valide dados, valide dados.
Bloqueie IPs que tentem fazer acessos fracassados várias vezes.
Controle permissões de pasta.
Utilize programas de vulnerabilidade.
Tenha um plano de contigência.

Você também pode gostar