Como eu descobri uma falha de segurança em um sistema na minha universidade
Tags: security, api, pentest
Published: 2022-05-17 21:54:36

**English version:** [How did I discover a security vulnerability in a system of my university](https://dev.to/ianito/how-did-i-discover-a-security-vulnerability-in-a-system-of-my-university-916)

Eai galera, então hoje eu vou contar como eu descobri uma falha de segurança em um dos sistemas que minha universidade utiliza, o que eu fiz logo em seguida, como podemos evitar e minhas conclusões.

Quero deixar claro que meu objetivo não é manchar a imagem da empresa, universidade ou dos desenvolvedores, mas sim poder contribuir com a segurança do sistema bem como também contribuir para o cenário de Segurança da Informação no país. 

## Como eu descobri a falha?
Bom, na época estavamos na pandemia em que as aulas em sua maioria eram todas onlines e por isso o uso de sistemas onlines eram mais frequentes do que no presencial. Então, nessa aula foi nos apresentados um sistema (já utilizado a algum tempo pela universidade) e que deveriamos utilizar para postar atividades e acompanhar notas. Sendo um sistema novo, tive a curiosidade de ver o que estava trafegando nas requisições feitas pelo sistema e comecei a procurar requisições que fossem interessantes. 

Então, encontrei duas requisições interessantes.
- Uma que me retornava meus dados cadastrais
- Outra que me retornava alguns números do meu cartão de crédito, data de validade, bandeira e etc.

![Rota dados pessoais](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yh31zketqhcszxzy7kfd.png)
![Rota cartão de crédito](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/88uop6werxyfarh3sfua.png)

> Mas Iaan, até agora só encontramos duas rotas que mostram nossos próprios dados, e dai?

Você tem razão, por isso eu decidi testar se essas rotas permitiriam ser feitas se eu não tivesse um token ou se meu token fosse inválido, e...

Não deu em nada. :(

Foi então que eu pensei, e se meu token for válido mas minha requisição tiver um id diferente do meu, ou seja, de outro usuário?

**E... funcionou! :D**

Fiz uma requisição utilizando o comando `curl` e mudando meu `id` que era um paramêtro na rota.

![Imagem do terminal com curl](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8psg4rgb8s90ind7y9tb.png)

O mesmo acontecia na rota que mostrava informações dos cartões de créditos.

Isso acontece pois o back-end da aplicação apenas verificava se o token era válido para fazer a requisição mas não verificava se o id que eu estava solicitando realmente pertenciam a meu usuário. 

Suponhamos que meu `id` seja o 21 e que eu esteja autenticado na aplicação, então a rota para mostrar meus dados pessoais poderia ser algo assim:

`http://apidosistema.com.br/dados-pessoais?id=21`

Então, como eu estava autenticado e meu token era válido, se eu mudasse o `id` da requisição para 22, eu conseguia obter dados do usuário com esse `id`.

`http://apidosistema.com.br/dados-pessoais?id=22`

Ok, falha encontrada e agora?

## O que eu fiz logo após encontrar a falha?
Comecei a documentar o que eu tinha descoberto para reportar aos responsáveis.
Criei um documento em que eu dava um resumo da falha que tinha acabado de descobrir.
Nesse documento descrevi um resumo da falha, gravidade, como executar, possível solução, um script simples que mostrava a falha (Proof-of-concept) e o código fonte do mesmo.

![Documento](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ye8psn0360d19lctrol5.png)
 
PoC:https://www.youtube.com/watch?v=tU1qOoPhwtg

Como não sabia o email dos responsáveis pela plataforma, entrei em contato com meu professor que me ajudou a enviar o documento para eles.
No dia seguinte, recebi um email com uma resposta da plataforma.

> Prezados,
Esperamos encontrar todos bem.
Recebemos a sua notificação a respeito de uma falha de segurança em uma de nossas aplicações e gostaríamos de informar que de imediato, submetemos essa notificação ao nosso time de engenharia para análise e devidas correções.
Após análise ficou constatado que de fato existia uma vulnerabilidade que permitiria a consulta dos dados cadastrais de outras pessoas, somente quando em posse de um token válido. O token nesse contexto é semelhante a uma chave, gerada a partir da autenticação bem-sucedida de um aluno no após informar seu usuário e sua senha pessoal. Pessoas sem esse token, ou seja, sem um login válido, não conseguiriam acesso aos referidos dados pessoais.

> Todas as correções e validações necessárias foram implementadas para que esse cenário não ocorra mais.
Com relação aos dados de cartão de crédito é importante destacar que não armazenamos nenhum dado crucial ou sigiloso do cartão de crédito do aluno. A fim de não restarem dúvidas, abaixo segue uma breve explicação de como funciona o uso do cartão de crédito nas nossas soluções:

> Quando um aluno deseja realizar qualquer pagamento via cartão de crédito, ao inserir as informações do seu cartão, esses dados são enviados diretamente à Instituição Bancária através de um processo chamado de “Checkout transparente” onde os dados estão sendo enviados diretamente ao banco de dentro da nossa plataforma. Em outras palavras, é como se o aluno estivesse no site do banco estando ainda na nossa plataforma. Essa comunicação com o banco é realizada utilizando uma conexão segura e criptografa, além de todos os mais recentes protocolos de segurança disponíveis para internet. Em nenhum momento nós coletamos quaisquer informações transacionadas nessa operação. Após a finalização do pagamento a Instituição Bancária nos retorna se ela foi bemsucedida ou não, e, quando bem-sucedida, nos envia um token que identifica aquele cartão do aluno junto ao banco. Acompanhado desse token vem o número mascarado do cartão e sua bandeira, para que caso o aluno precise realizar outro pagamento pela plataforma, ele consiga fazê-lo de forma mais fácil e rápida. Esse token por si só não tem nenhuma validade pois, na eventualidade de um novo pagamento, será exigido a inserção do código de verificação impresso no cartão de crédito e de uma chave pública e outra privada criadas entre o banco e nosso sistema para que a transação seja validada, reforçando que toda a transação será realizada em um ambiente seguro fornecido pela Instituição Bancária.

> Prezamos muito pela qualidade e integridade dos serviços que prestamos. Nosso ciclo de inovação contempla revistar serviços já construídos para mensurar critérios de desempenho e segurança. Sentimos profundamente que essa falha tenha passado despercebida. Por isso, verificamos com muita cautela todos os pontos que foram levantados e estes já se encontram corrigidos. Ressaltamos também nosso compromisso em seguir e mantermos atentos a toda
a legislação vigente referente a segurança da informação, em destaque para a Lei
nº. 13.709/18 (Lei Geral de Proteção de Dados pessoais - "LGPD") e a Lei
12.965/2014 (Marco Civil da Internet). 

> Em todas as nossas plataformas, está disponível, de forma pública, a nossa política de privacidade que explica como os dados pessoais são tratados nas nossas soluções. Questionamentos relacionados à Política de Privacidade da XX ou quaisquer outras dúvidas relacionadas ao tema de segurança e proteção dos Dados Pessoais, podem ser enviadas através do e-mail de contato com o suporte
Certo de nossa compreensão, nos colocamos à disposição para quaisquer esclarecimentos. Atenciosamente, 

Em seguida, eu conferi se a falha tinha sido corrigida:

![Falha resolvida](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dgrzri79fso0xlalq5ub.png)
 
## O que podemos aprender disso?
Nunca confie no usuário, lembre-se que qualquer validação que você faça no lado do cliente é suceptível a mudanças pelo usuário. Valide tudo no back-end que seja necessário validação e faça testes para que se certifique que o seu resultado seja o esperado. Poderíamos trocar o `id` de `int` para um `UUID`? Depende, se for só pra isso, não é uma boa ideia pois uma validação ja impossibilitaria isso e somente com essa mudança você estaria resolvendo apenas uma parte do problema. Você tem que entender os trade-offs ao se adotar essa técnica. (Recomendo o artigo [Pretende usar UUID como PK em vez de Int/BigInt no seu banco de dados? Pense novamente...](https://gist.github.com/rponte/bf362945a1af948aa04b587f8ff332f8), tem alguns insights muito bom)

## Conclusão
Obrigado por ler até aqui, esse é um dos meus posts que faz parte do meu novo jeito de aprender usando learn in public.

Caso tenha interesse, você pode dar uma conferida sobre o que é isso: https://www.swyx.io/learn-in-public/

Pretendo continuar fazendo isso e já tenho o próximo post preparado. 

Spoiler: Esse também envolveu minha universidade

:)