Java Security
Fernando Leal Brayner
Marcellus de Castro Tavares
Roteiro
Introdução
Java Security
High-Level
Low-Level
API
Falhas de Segurança
Guidelines para desenvolvedores
Introdução
A Linguagem Java
Desenvolvida pela Sun Microsystems
Primeiro release público na década de 90
Independente de plataforma
Interpretada
Type-safe
Garbage Collection
Níveis de Segurança
Segurança separada em dois níveis
Low-level : JVM
Gabage collection
bytecode verifier
High-level: aplicações
Sandbox
Security policies
Security APIs
Java Security – High-Level
JDK 1.0 Security Model
Modelo “sandbox”.
Código local com acesso total aos recursos do
ambiente.
Applets não são confiáveis, acesso limitado.
Security manager responsável para determinar
que recursos são permitidos.
JDK 1.0 Security Model
Restrições ao código não confiável
Ler/Escrever arquivos no sistema.
Deletar/Renomer arquivos.
Criar conexões
Escutar/Aceitar conexões em qualquer porta no
sistema cliente.
Carregar bibliotecas.
JDK 1.1 Security Model
Applet assinado (signed applets).
Signed applet é tratado como código local.
Unsigned applets continuam rodando no
sandbox.
JDK 2 Security Model
Todo código, local ou não, sujeito a políticas de
segurança.
Políticas definem um conjunto de permissões.
Cada permissão especifica um acesso a um
recurso em particular.
Sistema organiza códigos em domínios, que
agrupam conjunto de classes cujas instâncias
são dadas o mesmo conjunto de permissões.
JDK 1.2 Security Model
Ferramentas relacionadas a segurança JDK
Keytool
Criação de pares de chave pública/privada.
Jarsigner
Ferramenta para assinar jars e verificar a
autenticidade das assinaturas no jar assinado
PolicyTool
Ferramenta para criação e modificação de
arquivos de políticas de sgurança.
Java Security – Low Level
JVM
Responsável pela “independência de
plataforma”
Interpreta Java bytecodes
Bytecodes são armazenados nos arquivos .class
Arquitetura da JVM
Stack based machine
Instruções puxam argumentos da pilha e
empurram resultados na mesma
Registradores são acessados via fuções de
load/store
Pilha e registradores são preservados entre as
chamadas dos métodos
JVM: Bytecode
JVM provê umas 200 funções, maioria delas são
tipadas
Exemplo
public int add(int i, int j)
{
int res;
res = i + j;
return res;
}
public add(int,int):int
0:
iload_1
1:
iload_2
2:
iadd
3:
istore_3
4:
iload_3
5:
ireturn
Segurança na linguagem Java
O compilador e o sistema run-time de java
implementa várias camadas de defesa contra
códigos potencialmente incorretos.
O ambiente Java de execução assume que nada
é confiável.
Desenhada para ter tipagem segura
Gerenciamento automático de memória
Checagem automática dos limites do array.
Verificação do .class
Certifica que as restrições da linguagem são
cumpridas
Classes finais não podem ser estendidas
Toda classe tem uma super classe, exceto a
classe Object
Assegura que o arquivo possui a estrutura
adequada
Verificação do Bytecode
Byte Code Verifier
Bytecode verifier não faz suposições sobre
a origem do código
Uma vez que a verificação é feita um
número de propriedades são garantidas
Nenhum stack overflow/uderflow foi
causado
Tipagem correta
Todos os registradores foram
inicializados
Inicialiazação dos objetos.
Bytecode verification – estágio 1
Bytes são quebrados em seqüências de
instruções
Endereço de cada instrução é mantido em uma
tabela
Bytecode verification – estágio 2
Interpretador abstrato
Executa instruções JVM, mas opera sobre tipos
Para cada instrução i, uma regra de transação
descreve a modificação da pilha e dos
registradores
i: (S,R)
(S‘,R‘)
Verificador procede método por método
Verificação do Bytecode: interpretador
abstrato
Exemplos
Erros são verificados pela falta de transações
Erro de tipo, stack underflow/overflow
Verificação do Bytecode: interpretador
abstrato
Tipos primitivos (int, long, float, double)
Objetos e referências a arrays
Null: referência nula
T: registrador não inicializado
Bytecode verification: simple example
Bytecode correto
Source
Bytecode
Stack/Registers
float f;
fconst 1.0
([ ], [ C, T, T ] )
Object o;
fstore 1
(float, [ C, T, T ] )
f = 1.0
aload 0
([ ], [ C, float, T ] )
o = this;
astore 2
(C, [ C, float, T ] )
([ ], [ C, float, C ] )
Introduzindo um erro
float f;
fconst 1.0
([ ], [ C, T, T ] )
Object o;
fstore 1
(float, [ C, T, T ] )
f = 1.0;
fload 1
([ ], [ C, float, T ] )
o = f;
astore 2
(float, [ C, float, T ] )
ERROR
Astore
precisa
de um
objeto no
topo da
pilha!
Arquitetura do Class Loader
Class loaders – responsáveis por importar dados
binários que definem as classes e interfaces do
programa em execução
Principais funcões:
Carregar classes (local,net)
Definir namespaces
Modelo criticado
Arquitetura do Class Loader
Primordial class loader
Parte da implementação da JVM, um por vez
Não pode ser sobrescrito
Responsável pelo bootstraping da VM
Classes não passam pelo verificador
Class loader objects
Objetos java que carregam classes de maneira
customizável
Tratados como não-confiáveis por default
Extensível
Applet Class loader
Arquitetura do Class Loader
• Origem distinta classloarder
Applet Class Loader
Carregando Classes
Passos do Class Loader
Determina se a classe foi previamente carregada. Se
sim, retorna a mesma.
Consulta o Primordial Class Loader para tentar carregar
a classe a partir do CLASSPATH.
Checa se o Class Loader tem permissão para criar a
classe que está sendo carregada.
Lê o arquivo num array de bytes.
Constrói um objeto Class e seus métodos
Resolve classes imediatamente referenciadas pela classe
antes de seu uso.
Checa o .class com o verificador
Java Security Manager
Um objeto java que mantem lista de quem pode fazer operações
“perigosas”
Classes da biblioteca java consultam o security manager quando
são executadas
Todo security manager estende de
java.lang.SecurityManager
Cada VM com apenas um SM instalado, não podendo haver
desinstalação
Java Security Manager
-Customizável
-A SUN fornece um template
que deve ser preenchido para
alcançar os requisitos de segurança
Utilizando o Security Manager
Como instalar
Como utilizar
Default Policy File
Inside Security Manager
Identidade – base para decisões de segurança
Origem – De onde vem o código?
Assinatura- De quem é o código?
java.security.CodeSource
Permissão – encapsula o acesso a operações
particulares
Incluem um alvo e uma ação
p = new SocketPermission(“www.poly.edu”, “connect”);
p = new FilePermission(“/tmp/file1”, “*”);
Inside Security Manager
Proteção de domínio – conjunto de classes cujos objetos
são concedidos o mesmo conjunto de permissões com
respeito a recursos
Uma política de segurança define a proteção de domínio
Inside Security Manager
Access Controller (java.security.AccessController)
Decide que permissões devem ser concedidas ou
negadas
Obtém snapshots do contexto de chamadas, dessa
forma decisões de controle de acesso podem ser
tomadas
Examina todas as classes na pilha de chamadas e
garante que todas elas em permissão para realizar
uma operação
Cada frame da pilha pode ter tanto o método
chamado quanto um rótulo(confiável/não-confiável)
Responsabilidades do SM na presença de
Applets não-confiáveis
Previnir instalação de novos Class Loaders.(evitar
spoofing)
Proteger threads e thread groups
Controlar execução de outros programas
Controlar habilidade de desligar a VM
Controlar acesso a outros processos
Controlar operações de sockets na rede
Controlar operações no sistema de arquivos
Java Security API - JAAS
Java Authentication & Authorization Service
Introdução
Autenticar é determinar a identidade do usuário
Autorizar é determinar que recursos o usuário
pode ter acesso
JAAS é um conjunto que APIs que permite que
as aplicações Java tenham um controle
autenticação e de acesso.
JAAS
Primeiro release público foi em maio de 2000
com o JDK 1.4
Implementa uma versão em Java para o padrão
Pluggable Authentication Module (PAM)
Funciona com várias tecnologias de
autenticação
JAAS – Classes e Interfaces
Common
Subject, Principal
Authentication LoginContext, LoginModule,
CallbackHandler, Callback
Authorization
Policy, AuthPermission,
PrivateCredentialPermission
JAAS - Common
Subject
Entidade que deseja se autenticar para se ter
acesso a serviços ou recursos.
Principal
Identificadores associados ao Subject
Nome, CPF
JAAS - Authentication
Permite a independência entre as aplicações e o
mecanismo de autenticação.
Novas Tecnologias de autenticação podem ser
plugadadas
JAAS
JAAS - Authentication
LoginContext
Provê métodos para a autenticação do
Subject.
Usa arquivos de configuração para
determinar que mecanismo de autenticação
(login module) será utilizado.
LoginModule
Provedores de tecnologia de autenticação
implementam essa interface para prover
autenticação.
Mecanismo de autenticação
1.
2.
3.
4.
Aplicação inicia o LoginContext
LoginContext consulta o arquivo de
configuração para carregar os módulos para o
mecanismo de autenticação
Aplicação invoca o método login() do
LoginContext
O método login() invoca dos módulos de
autenticação carregados
Mecanismo de autenticação
5.
6.
Cada módulo tenta autentica o Subject. Em
caso de sucesso os módulos associam
Principals ao Subject
LoginContext retorna o status da autenticação
para a aplicação.
JAAS - Authorization
Permite definir permissões de acesso aos
usuários
Mecanismo
Depois do usuário ser autenticado. A API de
autorização associa o Subject com seus
controles de acesso.
Quando o Subject tenta executar uma
operação (ler arquivo, escrever na base de
dados) Java Runtime consulta o policy file
para determinar quem pode ter acesso a
essas operações.
JAAS - Authorization
PrivilegedAction
Interface
Método run()
Chamadas de métodos com acesso
restringido
Chamada -> Subject.doAs (Subject,
PrivilegedAction )
Falhas de Segurança
Falhas de Segurança
Algumas brechas listadas em Java Security
“Jumping the Firewall”
“Slash and Burn”
Classes carregadas a partir do disco são confiáveis
Falha na implementação de alguns browsers
“Applets running wild”
Um Applet só pode estabelecer uma conexão com o servidor
que o originou?
Applets são proibidos de criar class loaders?
Falha no Class Verifier permite quebra dessa regra(evil class
loader installed and creates type confusion)
Mais famoso dos erros
“Casting Caution”
Falha no teste se um método é privado
Vários aspectos de segurança são protegidos desta forma
Falhas de Segurança
“Big Attacks Come in Small Packages”
Bug na implementação da Microsoft
Código não confiável poderia ser carregado como
parte dos pacotes java (java.lang)
Privilégios!!
Falhas de segurança e bugs em geral:
http://java.sun.com/sfaq/chronology.html
Guidelines para desenvolvedores
Guidelines para Desenvolvedores
Limite o acesso a suas classes,métodos e variáveis
Torne tudo final, a menos que tenha um bom motivo
para não fazê-lo
Um ataque pode estender suas funcionalidades
Evite package scope
Classe no pacote tem acesso aos atributos e métodos
java.lang é fechado, poucas VMs permitem que você
feche seu próprio pacote
Guidelines para Desenvolvedores
Evite Inner Classes
Não existe esse conceito em bytecodes
Como uma classe inner-class consegue
acessar atributos privados?
Torne suas classes não-clonáveis
Ataque pode criar instancias de sua classe
sem execução de construtores.
public final void clone() throws CloneNotSupportedException{
throw new CloneNotSupportedException();
}
Guidelines para Desenvolvedores
Torne suas classes “unserializable”
public final void writeObject(ObjectOutputStream) throws IOException{
}
throw new IOException(“cannot be serialized”);
Torne suas classes “undeserializable”
Seqüência de bytes podem ser deserializada
para instancias de classes em uso, sem
controle do estado do objeto
É um construtor público que não se tem
controle
Guidelines para Desenvolvedores
Não compare classes por nome
If (a.getClass().getName().equals(“Foo”)) ... Errado
If (a.getClass() == b.getClass()) ... ok
Essas dicas não resolvem os problemas de
segurança, mas diminuem as coisas que podem
dar errado
Java - Vantagens
Permite execução controlada de código menos
confiável
Permite control de permissões refinado
“Instant installation”
Revisões constantes da Sun
Desvantagens de segurança (1 de 3)
Difícil de provar corretude
Complexo do ponto de vista de segurança
Expansões e mudanças ocorrendo
rapidamente
VM+libraries falta de um modelo formal
Muitas interdependências; quebra de um
pode quebrar todo sistema
Dependência complexa em outros sistemas
OS, browsers, network (DNS)
Desvantagens de segurança (2 de 3)
Muitas áreas imaturas
Simplifica engenharia reversa do código
(problema?)
Performance pobre pode encorajar atalhos que
enfraquecem a segurança
Desvantagens de segurança (3 de 3)
Fraco contra DoS
Implementações default inseguras (ClassLoader
or SecurityManager)
Gerenciamento da política de segurança
complexo para usuários finais e suportes sem
experiência
Políticas flexíveis aceitas por usuários pode
permitir falhas de segurança
Referências
http://java.sun.com/javase/technologies/securit
y/index.jsp
Securing Java, McGraw and Felten
http://java.sun.com/products/jaas
http://java.sun.com/docs/books/vmspec