Evitando falhas de segurança com desenvolvimento em Python
Ei Dev! Já se perguntou sobre a segurança do seu software em Python? Já criou perspectivas de usuários mal-itencionados na sua aplicação? Do que eles poderiam explorar? Se você nunca pensou em nada disso, tem coisa errada aí. Com o surgimento de novas leis de proteçao de dados, os softwares necessitam de mais atenção para garantir confiabilidade e proteção. A proposta deste post é mostrar os problemas de vulnerabilidades mais encontrados em libs e frameworks de Python, através de alguns exemplos de falhas de segurança. Indicar boas práticas para os desenvolvedores, assim como ferramentas em Python que ajudem no processo de desenvolvimento seguro.
Python com 28 anos desde a sua primeira versão, configura-se com uma das linguagens mais usadas no mundo, ficando no ranking das 10 linguagens de programação segundo o Stack Overflow[2] e no Github[5]. Com uma semântica bastante fácil e didática é usado largamente em companhias e instiuições de ensino. Caracteriza-se como uma linguagem de programação de alto nível para uso geral. Possui uma grande quantidade de bibliotecas com as mais diversas funcionalidades, diminuindo o tempo na construção de um software. Python surge na maioria dos casos como uma linguagem de script, com a finalidade de pequenas atividades dentro de uma empresa, não sendo usado para a estruturação de um sistema complexo.
Apesar de grande usabilidade da linguagem, como ilustrado na figura acima, ela não é muito usada para projetos grandes. Tem aplicações em projetos web, desktop, mobile, data analytics. Empresas como Google, Facebook, Netflix, Reddit relatam o uso de Python em suas aplicações. Fundadores do Google, no ínicio, tinham como lei a seguinte frase: “Python where we can, C++ where we must.” que pode ser traduzida como: Python onde podemos, C++ onde devemos. A simplicidade de manutenção do código e entrega ágil possibilitaram que engenheiros aperfeiçoassem a plataforma com rapidez. Assim como o Facebook, que adotou a linguagem para fins de automação industrial, gerenciamento de infraestrutura, distribuição binária e outras. Engenheiros da Netflix relatam Python para análise de dados, onde a comunidade é ativa e o grande número de bibliotecas oferecem várias possibilidades para um determinado problema, deixando assim um desenvolvimento mais produtivo. Com grandes poderes vem grandes responsabilidades, já dizia tio Ben a Peter Parker. Conseguir o posto de linguagens mais adotadas no mundo reforça o quanto a comunidade deve mantê-la segura e estável para que o Python consiga ganhar ainda mais adeptos. A mesma facilidade para criação de novas libs pode trazer consigo vulnerabilidades para a aplicação.
Vulnerabilidades
Em uma busca por projetos em Python, o CVE Details[6], site que lista vulnerabilidades por produtos, fornecedores, linguagens e versões, relata algumas vulnerabilidades em Python. Dentre elas, encontram-se casos como bypass, DoS, Overflow e outros. Em comparação a Java e Node.js que apresentaram um total de 132 e 39 vulnerabilidades, respectivamente nos últimos 3 anos, Python apresenta um número menor de vulnerabilidades chegando a um total de 16 nesse mesmo período, segundo o site CVE Details.
Dentre as vulnerabilidades mais reportadas está a de DoS(Denial of Service), que pode ser traduzida como Negação de serviço. Este tipo de ataque consiste em deixar os recursos de um determinado sistema indisponíveis, isso acontece normalmente pelo envio massivo de requisições a um servidor ou uma rede, o qual não consegue suportar esse número de requisições com retorno inválido, deixando a aplicação ocupada ou até mesmo fora do ar. Em Python há algumas vulnerabilidades que permitem esse ataque, como a do CVE-2018-14647[7] que relata uma falha no package ElementTree. Esse pacote permite fazer o parsing, ler, modificar e popular arquivos XML. A vulnerabilidade acontece na inicialização quando o ElementTree C Accelerator não chama o método XML_SetHashSalt() para inicializar o Expat hash. Um ataque remoto poderia ser feito passando um XML que provocasse uma colisão de hash na estrutura de dados, consumindo assim CPU e RAM e consequentemente deixar a aplicação indisponível.
O segundo tipo de vulnerabilidade mais relatado pelo site é o overflow. Consiste no acesso indevido a endereços de memória, normalmente quando um processo tenta colocar mais dados que o limite estipulado originalmente pelo programa, fazendo com que o processo coloque o dado em outras porções de memória. Como esse dado é ponteiro para a próxima instrução e por sobrescrever o que existia, é possível injetar um comando que permita, através do erro do programa, executá-lo e acessar informações antes não permitidas. O CVE-2018-1000117[8] relata uma vulnerabilidade que ocorre entre as versões 3.2 e 3.6.4 de Python no Windows. A execução do os.symlink()(Criação de link simbólico) pode resultar na execução de um código malicioso permitindo escalação de privilégios, por exemplo. Este ataque pode ser explorado via Python script quando o atacante cria um link simbólico gerenciando onde o link pode ser criado. A partir da versão 3.6.5 foi acrescentada a correção desta vulnerabilidade.
Já o ataque por XSS baseia-se na relaçao de confiança que um usuário tem com uma aplicação web. O atacante se aproveita de alguma vulnerabilidade no site onde possa haver injeção de códigos ou dados(geralmente algum código Javascript/HTML) em qualquer campo e insere algum código malicioso. Através disso pode-se redirecionar o usuário para outro site, obter cookies e até mesmo credenciais de acesso. Um exemplo desse tipo foi encontrado no Django(Framework Python) nas versões 1.11, 2.1 e ajustada na versão 2.2. O CVE-2019-12308[9] relata o uso do pacote django.contrib.admin.widgets possui o AdminURLFieldWidget onde era possível colocar uma URL sem validação de que é uma URL com ou sem payload. Sem essa verificação, o atacante poderia passar um valor diferente do esperado e resultar no link Javascript clicável.
O Server Side Template Injection(SSTI) é um tipo de ataque que pode ser usado diretamente contra servidores web para realizar execução de código remoto [11]. Diferente do XSS, mencionado anteriormente que permite o ataque no frontend, o SSTI usa web templates que colocam dados dinâmicos em web pages e e-mails onde um atacante pode alterá-los e adicionar algum código. Em uma pesquisa do Nvisium[12], o atacante demonstra que pode obter acesso a variáveis de configuração globais passando: na URL de uma página. Como o config representa um objeto global, pode ser acessado a qualquer momento. Para evitar isso, o desenvolvedor precisa desabilitar a flag DEBUG que encontra-se no próprio Flask, impossibilitando assim que essas informações sejam exibidas em ambiente de produção.
Como evitar essas e outras vulnerabilidades?
O time de consultoria da Tempest analisa aplicações web e a maior parte das falhas encontradas está na construção da regra de negócio ou no uso indevido de bibliotecas. Dado que os procedimentos da equipe de desenvolvimento refletem na segurança da aplicação, seguem algumas dicas que podem ajudar nesse processo, como:
- Pesquise: Antes de usar uma lib, verificar o quanto ela é importante para a sua aplicação e a data da última atualização. Isso garante que você não estará usando uma lib antiga, sujeita a falhas de segurança no futuro por falta de atualização. Além disso, é importante pesquisar outros projetos relevantes que usam essa mesma lib.
- Atualizações: Manter as versões de frameworks e libs sempre atualizadas. Qualquer falha de segurança será ajustada nas próximas versões, fazendo isso, o desenvolvedor(a) garante cobertura de possíveis falhas que podem ser encontradas.
- Python Security: O Python Security disponibiliza uma lista de vulnerabilidades encontradas, assim como suas versões. Nesta lista também fica disponível correções dessas falhas. <https://python-security.readthedocs.io/>
- Ambiente: Antes de colocar seu sistema web em ambiente de produção, verificar logs de teste e paths de configuração. Separar arquivos de configuração de produção e teste é uma boa prática, pois evita que um atacante tenha acesso aos dados e paths da máquina local.
- Configuração: Em frameworks como Django e Flask existe um parâmetro DEBUG que quando está ativo mostra informações da aplicação em tempo de execução. Em ambiente de desenvolvimento esta flag é marcada como True pois ajuda no processo de desenvolvimento. É importante lembrar de marcar esta configuração para False quando a aplicação for para ambiente de produção. Assim como o uso da flag SECRET_KEY, lembrar de usar diferentes valores para ambientes de desenvolvimento e produção.
Esta lista de dicas poderia crescer muito mais. Com o tempo e experiência, o desenvolvedor(a) pode identificar pequenas atitudes que podem ajudá-lo no desenvolvimento seguro, como essas listadas anteriormente. Por ter uma comunidade forte e bem ativa, algumas ferramentas podem ajudar os desenvolvedores com questões de segurança. Exemplo disso é Bandit: Ferramenta criada para fazer scanner no projeto. Traz praticidade sendo possível utilizá-lo em vários frameworks Python, ao final, o desenvolvedor terá um report de falhas encontradas. Outra ferramenta é o Secure.Py que adiciona opções seguras nos Headers e Cookies em frameworks web Python. Alguns frameworks mais conhecidos como Django e Flask possuem algumas libs que complementam a sua segurança. O Flask possui o Flask-HTTPAuth que valida autenticação em rotas feitas do Flask. Outra extensão que pode ser usada no Flask é o Talisman que, assim como o Secure.Py, permite a configuração de opções do Header. O Django possui uma lib chamada django-session-csrf que representa uma alternativa ao uso de Cookies. Ao invés disso, é usado um CSRF Token que fica no próprio backend do Django. Ele desve ser incluso em todos os métodos POST da sua API. Vulnerabilidades podem aparecer sempre e em qualquer linguagem. Python se mostra uma linguagem com poucas vulnerabilidades se comparado a outras. Com mais de 20 anos de existência, apresenta-se muito consolidada e com potencial para crescer ainda mais. Tomando algumas precauções no desenvolvimento é possível criar uma aplicação segura com as mais diversas libs que Python oferece. Você desenvolvedor(a) que quer construir uma aplicação web, Python é uma ótima sugestão, que oferece mecanismos além do padrão, permitindo ao desenvolvedor(a) agilidade e segurança. Nada como deitar na cama, no fim do dia sabendo que seu software está seguro não é!?
Let me know what you think of this article on twitter @maricamppos or leave a comment below!