Descrição

Propaganda
Questões de Segurança em Engenharia de Software
Trabalho II
1
Descrição geral
Neste trabalho considera-se um serviço de palavras-passe escrito em Java, com código disponibilizado na forma de um projecto Eclipse. O código em questão tem algumas vulnerabilidades de
segurança, bem como alguns “bugs” na sua funcionalidade.
Pretende-se que:
1. Detecte as vulnerabilidades de segurança usando um auditor de código e elimine as mesmas
com alterações ao código.
2. Feitas as alterações anteriores, que valide parte do código usando testes de software, em particular considerando critérios de partição de espaço de entrada e testes de mutação.
Deverá entregar:
1. Um arquivo ZIP contento o projecto Eclipse modificado, incluı́ndo alterações ao código e testes
que programou.
2. Um relatório abordando os vários aspectos detalhados nas próximas páginas.
Posteriormente deverá apresentar o trabalho na aula, usando eventualmente também alguns “slides”
com um sumário do trabalho desenvolvido.
2
Ferramentas a usar
Veja o ficheiro SETUP.txt disponibilizado na página da disciplina para instruções de instalação.
• Eclipse IDE – recomenda-se que instale uma versão da variante “Classic” de fresco;
• Base de dados H2 – já incluı́da no projecto;
• FindBugs + FindSecBugs para auditoria de código – siga as instruções de configuração em
SETUP.txt.
• contrast-rO0, biblioteca para deserialização segura de objectos Java – já incluı́da no projecto;
• JUnit, biblioteca para escrita de testes de software – já parte do Eclipse;
• JDBDT, biblioteca para suporte aos testes no que toca manuseamento e validação do conteúdo
da base de dados – já incluı́da no projecto;
• PITclipse, plug-in Eclipse para a ferramenta PIT de testes de mutação – siga as instruções de
configuração em SETUP.txt.
3
3.1
Descrição do serviço de palavras-passe
Arquitectura
client
programs
ServerConnection
Request
Reply
Server
server side
manager
operations
Manager
database
access
InputChecker
SHGenerator
PasswordData
DAO
H2
database
A arquitectura de software é ilustrada acima, sendo visı́vel a organização em camadas e referindo
as principais classes Java. A documentação Javadoc pode ser encontrada em home/javadoc.
• O sistema armazena informação numa base de dados H2. É usada uma única tabela chamada
PASSWORDS, com campos LOGIN, SALT e HASH. A entrada para o login root é especial, no sentido
de ser necessária para efeitos de autenticação nas camadas superiores da arquitectura.
• Um objecto DAO (‘data access object”) medeia o acesso à base de dados, mapeando pedidos
de operações em comandos SQL enviados à base de dados. Para interface com DAO são usados
objectos PasswordData, que encapsulam o mesmo tipo de informação que a guardada na tabela
PASSWORDS.
• A classe Manager representa o gestor do sistema, respondendo a operações de modificação ou
consulta de informação. O gestor verifica se as operações são válidas, e nesse caso, delega as
alterações/consultas à base de dados em DAO. No seu funcionamento, Manager interage ainda
com InputChecker para verificar a boa formação de identificadores de utilizadores e de palavraspasse, e com SHGenerator para gerar valores de “salt” e “hash” para palavras-passe.
• O serviço de palavras-passe é exposto na rede por um servidor TCP/IP, instanciado pela
classe Server. Um servidor fica à escuta de ligações cliente, estabelecidas usando a classe
ServerConnection. A interacção cliente-servidor é feita via objectos Java serialisados para
representar pedidos do cliente e respostas do servidor, Request e Reply respectivamente.
3.2
Uso
No directório home/bin do projecto Eclipse encontra os seguintes scripts:
• configure.sh – inicializa a base de dados.
• server.sh <port> – inicia o servidor.
• client.sh <host> <port> – inicia programa cliente.
• dbconsole.sh – utilitário que lança a consola H2 para inspecionar a base de dados.
• sah.sh <seed> <password> – utilitário que mostra o “salt” e o “hash” para uma palavra-passe,
usando a “seed” dada para o gerador de números pseudo-aleatórios (poderá ser útil para gerar
dados de teste).
4
Tarefas a realizar
4.1
Análise e correcção de vulnerabilidades
1. Execute o FindBugs, com o módulo FindBugsSec já acoplado ao FindBugs, e configurando
apenas as opções de Security, Malicious code vulnerability, e Correctness.
• Para configurar aceda às propriedades do projecto, secção FindBugs.
• Para executar selecione src com o botão direito do rato e clique em Find Bugs.
2. Ignore os avisos de vulnerabilidade relacionados com “file system traversal” / uso de java.io.File.
3. Acerte os restantes pontos de vulnerabilidade.
4. Para cada vulnerabilidade, identifique no relatório o código vulnerável na versão original, as
ameaças à segurança do sistema inerentes, e as modificações ao código operadas.
• Nota: para as vulnerabilidades relacionadas com serialização de objectos Java, use as funcionalidades da biblioteca contrast-rO0 em modo “spot fix” (i.e., ao invés do “agent mode”).
4.2
4.2.1
Testes de software
TestInputChecker
A classe TestInputChecker deverá reunir os testes feitos à classe InputChecker, para validar os
métodos isValidLogin e isValidPassword, usando uma aproximação baseada em “input space
partitioning” (ISP).
1. Identifique primeiro no relatório:
(a) Para cada um dos métodos, isValidLogin e isValidPassword, a escolha de caracterı́sticas
e blocos correspondentes;
(b) Os requisitos de teste derivados da escolha de caracterı́sticas/blocos, considerando o critério
ECC (“Each Choice Coverage”) para isValidLogin e o critério PWC (“Pair-wise Coverage”) para isValidPassword;
2. Seguidamente:
(a) Programe casos de teste (um @Test JUnit por caso de teste) que cubram os requisitos,
identificados, e documente no relatório os requisitos cobertos por cada caso de teste.
(b) Encontrou “bugs” ? Acerte o código! Documente os “bugs” e alterações ao código no
relatório.
(c) No final, execute os testes em modo de mutação usando o PIT, e verifique se há mutantes
que sobrevivem. Programe testes adicionais se forem necessários, e faça referência a estes
no relatório. Identifique também se encontrou mutantes funcionalmente equivalentes.
4.2.2
TestDAO
A classe TestDAO deverá reunir os testes feitos à classe DAO.
Os testes deverão validar o retorno dos métodos e também o seu efeito sobre a base de dados
usando asserções δ do JDBDT. São já fornecidos alguns testes exemplo bem como outro código
de suporte aos testes, em particular a inicialização da base de dados de teste.
Os testes a considerar são os seguintes:
1. Para cada um dos métodos delete, insert, query e update : inclua dois testes, correspondentes ao seguintes dois casos: (a) utilizador em causa já existe na base de dados e (b) utilizador
em causa não existe.
2. Dois testes adicionais: um para listLogins e outro para clearAllExceptRoot.
3. Encontrou “bugs” ? Acerte o código! Documente os “bugs” e alterações ao código no relatório.
4.2.3
TestServer
A classe TestServer deverá reunir os testes de sistema feitos à classe Server, i.e., ao servidor no
seu todo.
Os testes deverão validar as respostas do servidor (Reply, sucesso ou falha) e novamente também
o seu efeito sobre a base de dados usando asserções δ do JDBDT. São já fornecidos alguns testes
exemplo bem como outro código de suporte aos testes; em particular a execução do servidor que
iniciará automaticamente antes de qualquer teste.
1. Programe testes análogos aos descritos para a classe DAO (excepto query) na forma de pedidos
ao servidor (Request).
2. Encontrou “bugs” ? Acerte o código! Documente os “bugs” e alterações ao código no relatório.
3. Execute os testes em modo de mutação.
(a) Programe testes por forma a matar todos os mutantes que forem possı́veis na classe
Manager, ignorando mutações sobre a classe Server em si. Ignore também mutações
sobre o texto de objectos Reply, excepto para o método listLogins().
(b) Faça referência a estes testes adicionais no relatório e identifique também se encontrou
mutantes funcionalmente equivalentes.
Download