Skip to content

Gestão de Segredos

Introdução

O manuseio adequado de credenciais confidenciais, como chaves de API, senhas de banco de dados e chaves de criptografia, é essencial para manter um ambiente seguro. Incorporá-los diretamente em seu código é uma prática perigosa que deve ser evitada.

Cenário Vulnerável

Olhe o código abaixo (em NodeJS) e pense o que pode estar errado:

const mysql = require('mysql');
const connection = mysql.createConnection({
host: 'mydatabase.example.com',
user: 'myusername',
password: 'mysecretpassword',
database: 'myapp_db'
});
connection.connect();

Se você respondeu "A senha está fixa diretamente no código! Deveria estar com uma variável de ambiente ou similar." acertou.

Riscos

Ao permitir que uma senha esteja fixa no código, criamos os principais riscos para a empresa:

Exposição Através do Controle de Versão

O commit desse código a um sistema de controle de versão (por exemplo, Git) tornaria essas credenciais visíveis no histórico do projeto, acessíveis a qualquer pessoa com acesso ao repositório.

Compartilhamento Acidental

Trechos de código colados involuntariamente em fóruns públicos, IAs ou arquivos de projeto compartilhados acidentalmente podem vazar essas credenciais.

Vulnerabilidades

Se um invasor obtiver acesso ao código-fonte, ele poderá facilmente explorar essas credenciais para acesso não autorizado ao sistema, comprometimento de dados ou ataques posteriores.

Downtime

Se precisarmos fazer a rotação de um segredo por qualquer motivo, precisaremos recompilar a aplicação e publicá-la novamente. Este processo pode ser demorado e/ou depender de algumas pessoas que talvez não tenham disponibilidade no momento.


Como Corrigir

Para resolver este desafio, este documento propõe a descrever um compliance de boas práticas para a gestão de segredos de aplicação, sugerindo a correta implementação de políticas e processos para o manuseio de segredos em todo seu ciclo de vida.

Uma vez construído o compliance, os times de desenvolvimento terão 180 dias para se adequarem aos requisitos de segurança descritos neste documento para estarem em conformidade com este tópico no nível de maturidade de segurança de aplicações.

A seguir, serão descritos todos os requisitos para gestão de segredos em aplicações no ciclo de vida de desenvolvimento. Os requisitos a seguir se aplicam a ambientes.

GSEG001 - Criação de Segredos

  1. Todo o processo de criação de um novo segredo deve estar devidamente documentado de forma centralizada para toda a equipe.
  2. Deve existir apenas uma forma de se criar um segredo para ambientes produtivos.
  3. Deve ser utilizado um mecanismo de gestão de segredos, como AWS Secret Manager, Azure KeyVault ou similares.
  4. Todos os segredos devem ser registrados com o prefixo SECRET_. Exemplo: SECRET_GOOGLE_API_KEY.
  5. Os segredos não podem ser expostos em documentações, e-mails, wikis, repositórios, backups ou qualquer outro lugar.

GSEG002 - Gestão de Acesso aos Segredos

  1. Uma vez criado o segredo, não deve ser possível visualizá-lo. Caso seja realmente necessário ter acesso de visualização, apenas um seleto grupo de pessoas (não podendo ser mais do que 3) podem ter acesso a visualizar estes segredos. Estas pessoas devem estar devidamente nomeadas em um documento formal.
  2. Caso sejam definidas pessoas ou perfis com acesso a visualizar os segredos, todos os acessos aos segredos que não sejam feitos pela aplicação devem ser registrados em logs de auditoria.
  3. Devem ser implementados mecanismos que permitam apenas a aplicação e as pessoas devidamente nomeadas acessarem o segredo.

GSEG003 - Rotação de Segredos

  1. Deve existir um processo onde seja capaz de substituir um segredo por um novo. Este processo é necessário em caso de comprometimento ou invalidação de um segredo, como uma API Key com data de expiração.
  2. O processo de rotação deve estar devidamente documentado.

GSEG004 - Consumo de Segredos pela Aplicação

  1. Cada aplicação que consumir um segredo, deve fazê-lo por uma classe ou função centralizada na aplicação. Exemplo: todos os segredos são consumidos pela classe CompanySecretManager usando métodos como getSecret("SECRET_GOOGLE_API_KEY").
  2. Os segredos devem ser disponibilizados para a aplicação via serviço de secret manager (AWS Secret Manager, Azure Key Vault ou similares). Caso este não esteja disponível, não se deve disponibilizar segredos para as aplicações via variáveis de ambiente. Os segredos devem ser disponibilizados em um arquivo chave-valor (como .env, json, yaml, ou similares) onde apenas a aplicação tenha a permissão de ler.

GSEG005 - Armazenamento de Segredos Mobile

  1. Aplicações desenvolvidas para iOS devem armazenar segredos utilizando Keychain.
  2. Aplicações desenvolvidas para Android devem armazenar segredos utilizando Keystore. Segredos não devem ser armazenados utilizando SharedPreferences.
  3. A aplicação deve definir uma única classe/componente que gerencie todos os segredos da aplicação. Novas funcionalidades e monitoramento de segurança poderão ser aplicados a esta parte do sistema.

GSEG006 - Manuseio de segredos pelas aplicações

  1. Segredos não devem ser passados na URL, apenas em Headers.
  2. Segredos não podem ser trafegados em conexões inseguras (como HTTP).
  3. Segredos não podem estar armazenados em logs.

Referências

  • https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html
  • https://www.nodejs-security.com/blog/do-not-use-secrets-in-environment-variables-and-here-is-how-to-do-it-better
  • https://www.pullrequest.com/blog/ios-app-secret-management-best-practices-for-keeping-your-data-secure/
  • https://medium.com/@kalidoss.shanmugam/top-10-secure-storage-alternatives-to-keychain-for-ios-in-swift-4d701a0a2a49
  • https://github.com/OWASP/owasp-mastg/blob/master/Document/0x05d-Testing-Data-Storage.md#shared-preferences