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