DevSecOps

2 mar, 2015

Segurança de aplicações iOS

Publicidade

Recentemente dei uma palestra sobre segurança em aplicações iOS (o arquivo da apresentação está disponível no aqui). Após a palestra, falei com algumas pessoas e percebi que seria interessante escrever alguns artigos explicando melhor os pontos que foram abordados. E este é o primeiro da série.

Para hoje, escrevi uma aplicação de exemplo simples, que está disponível via Github: https://github.com/garrefa/evil-app

git clone https://github.com/garrefa/evil-app

Logs (NSLog)

Logs são muito úteis no desenvolvimento de um app. Podemos adicionar logs em vários pontos do código e, assim, ter uma visão clara do que está acontecendo no aplicativo – quais dados estão sendo passados, quais funções estão sendo chamadas etc.

O problema dos logs é que muitas vezes o app vai para produção e os logs ficam. Acredite ou não, existem casos famosos de apps que fazem log de usuário e senha na hora do login.

Mas o processo de deploy pra Apple Store não remove os logs do meu código? Não! Ok, mas como os logs são capturados? Como alguém que não tem o código do app pode ver os logs em produção? É simples. Basta plugar o device em um Mac, abrir o Xcode, ir no menu Window, Devices. Veja imagem abaixo.

02

Ao clicar em devices, será aberta uma tela com a listagem de devices à esquerda. Selecione o desejado e à direita serão apresentadas as suas informações, aplicativos instalados e logs.

Na imagem abaixo é possí­vel ver a tela de devices aberta e o log especí­fico da aplicação de testes. É possí­vel ver no log o username, senha e número de cartão de crédito do usuário.

03

A aplicação de testes está versionada. A versão 1.0 pode ser usada para testes em produção e desenvolvimento. Para isso, basta fazer checkout na tag v1.0.

git checkout v1.0

Podemos facilmente evitar que o log vaze para produção usando uma macro no arquivo pch. Essa macro vai redefinir NSLog nos casos onde a variável DEBUG não está setada. O código para isso é muito simples:

#ifndef DEBUG 
#define NSLog(...) 
#endif

Se estivermos em ambiente de DEBUG, essas três linhas redefinem NSLog para não fazer nada, já que o segundo parâmetro da macro que define NSLog está vazio.

Fazendo checkout na versão 2.0 do app de testes, podemos ver esse código aplicado no arquivo PrefixHeader.pch.

git checkout v2.0

No mundo perfeito, o programador adicionaria logs build de desenvolvimento e removeria no build de produção. Alguns programadores dizem que os logs devem ser removidos completamente após uma funcionalidade ser testada. O problema é que remover log é chato, consome tempo e ninguém lembra de fazer. Definir macros ajuda bastante a automatizar esse processo.

Outra possibilidade é usar um pod chamado CocoaLumberjack. Esse pod possui vários recursos avançados para controle de logs, como logs com cores diferentes para alertas, erros e etc. No futuro deve pintar um artigo por aqui explicando como utilizá-lo.

App Background Snapshots

Outra coisa que pouca gente lembra é que quando os apps vão para background, o iOS tira um snapshot da tela do app para ser exibida como miniatura. Esse snapshot fica salvo descriptografado no disco e é muito fácil de recuperá-lo.

Ainda na tela de Devices do Xcode, clique no app desejado, depois no botão com í­cone de engrenagem e escolha a opção “Download Container”. Veja imagem abaixo:

04

Salve o container no seu disco e depois troque a extensão para .zip. Fazendo isso, é possível navegar na estrutura de diretórios do container e chegar até o snapshot, conforme imagem abaixo:

05

No caso do app de teste, o hacker não teria visto a senha do usuário, pois o campo é protegido, mas ele teria visto o username e o número do cartão de crédito. E como já vimos antes, a senha estava aberta nos logs.

061-169x300

E como eu me protejo desse tipo de ataque?

Uma forma é colocar uma view por cima da view atual quando o app for entrar em background, removendo-a depois quando ele for voltar ao foreground. Um exemplo de como fazer isso está na v3.0 do app de testes.

git checkout v3.0
- (void)applicationDidEnterBackground:(UIApplication *)application {
    UIView *currentView = [self.window.subviews objectAtIndex:0];
    UIView *redView = [[UIView alloc]
    initWithFrame:currentView.bounds];
    redView.backgroundColor = [UIColor redColor];
    redView.tag = 100;
    [currentView addSubview:redView];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
    UIView *currentView = [self.window.subviews objectAtIndex:0];
    UIView *redView = [currentView viewWithTag:100];
    [redView removeFromSuperview];
}

Componentes de terceiros (pods)

Usar pods e componentes de terceiros agiliza muito o trabalho de desenvolvimento. Alguns pods são padrão na área, como por exemplo o AFNetworking. É bom lembrar que o mesmo cuidado que temos com o nosso código precisamos ter com o código de terceiros, ou seja, precisamos verificar as issues em aberto no Git, ver se tem manutenção ou se existe uma comunidade de pessoas utilizando, por exemplo. Todo seu esforço de segurança pode ser posto abaixo com um pod em que o desenvolvedor não tomou tanto cuidado com segurança quanto deveria.

No próximo artigo detalharei o ataque de man in the middle, ataque a redes wifi, funcionamento do SSL, SSL pinning e um pouco de criptografia.

Alguma dúvida, sugestão ou crítica? Só deixar nos campos abaixo.

Até a próxima!