Em scripts shell, muitas vezes lidamos com informações sensíveis, como senhas, chaves de API e tokens. A gestão inadequada dessas informações pode resultar em vazamentos de dados, acesso não autorizado e comprometimento do sistema. Nesta aula, vamos explorar como proteger esses segredos, entender os riscos associados ao uso de variáveis de ambiente e como configurar permissões padrão com umask para minimizar exposições.

Vamos mergulhar em técnicas práticas e boas práticas que você pode aplicar imediatamente em seus scripts para garantir que informações confidenciais não caiam em mãos erradas.

Arquivos sensíveis

Arquivos que contêm senhas, chaves privadas, tokens de API ou outras informações confidenciais devem ser protegidos com permissões restritivas. No Linux, as permissões de arquivo são representadas por três conjuntos de três bits: leitura (r), escrita (w) e execução (x), para o dono, grupo e outros. Para arquivos sensíveis, é comum usar permissões 600 (apenas leitura/escrita para o dono) ou 400 (somente leitura para o dono).

Por exemplo, se você tem um arquivo chamado senha.txt, pode definir permissões para que apenas o dono possa ler e escrever:

chmod 600 senha.txt

Além disso, é importante considerar o diretório onde esses arquivos estão. Diretórios com permissões excessivamente permissivas (como 777) podem permitir que outros usuários listem ou acessem os arquivos. Use 700 para diretórios privados.

Outra prática recomendada é usar arquivos com extensões não óbvias ou em locais fora do diretório web, mas isso não substitui as permissões adequadas.

Variáveis com senhas (riscos)

Armazenar senhas em variáveis de ambiente ou diretamente em scripts pode ser arriscado. Variáveis de ambiente podem ser expostas a outros processos, e scripts podem ser lidos por outros usuários se as permissões não forem restritas. Além disso, o histórico do shell pode capturar comandos que contêm senhas, como em export SENHA=123.

Por exemplo, se você define uma variável com uma senha e o script é executado com set -x para depuração, a senha será exibida no terminal. Da mesma forma, se o script for comprometido, a senha pode ser extraída.

Para mitigar esses riscos, evite colocar senhas diretamente no código. Prefira ler de arquivos protegidos ou usar ferramentas de gerenciamento de segredos, como Vault. Se precisar usar variáveis, defina-as no momento da execução e limpe-as após o uso:

read -s -p "Digite a senha: " SENHA
export SENHA
# ... usar a senha ...
unset SENHA

O comando read -s oculta a entrada do usuário, e unset remove a variável após o uso.

umask em scripts

O umask define as permissões padrão para novos arquivos e diretórios criados pelo shell. Ele mascara bits de permissão, e o valor padrão é geralmente 022, que resulta em arquivos 644 e diretórios 755. Para maior segurança, você pode definir um umask mais restritivo, como 077, que resulta em arquivos 600 e diretórios 700.

Em scripts, você pode alterar o umask para garantir que arquivos temporários ou sensíveis tenham permissões restritas. Por exemplo:

#!/bin/bash
umask 077
# Agora todos os arquivos criados terão permissões 600
> /tmp/segredo.txt
echo "conteúdo" > /tmp/segredo.txt
ls -l /tmp/segredo.txt

Isso é útil quando o script cria arquivos com dados confidenciais. No entanto, lembre-se de que o umask afeta todos os arquivos criados durante a execução do script, então ajuste conforme necessário.

Boas práticas

Além das técnicas específicas, aqui estão algumas boas práticas gerais para lidar com segredos em scripts:

  • Nunca hardcode segredos no código. Use variáveis de ambiente, arquivos de configuração protegidos ou serviços de gerenciamento de segredos.
  • Use permissões restritivas (600 ou 400) para arquivos de segredos.
  • Evite usar set -x em scripts que lidam com segredos, pois isso exibe todos os comandos e variáveis.
  • Limpe variáveis de ambiente que contenham segredos após o uso usando unset.
  • Use read -s para capturar senhas sem exibi-las no terminal.
  • Considere usar ferramentas como gpg para criptografar arquivos de segredos e descriptografá-los apenas quando necessário.
  • Quando possível, use autenticação por chave em vez de senhas (ex.: SSH keys).
  • Revise regularmente os scripts e arquivos em busca de segredos expostos.

Implementar essas práticas reduz significativamente o risco de vazamento de informações confidenciais.

Referências

Exercícios

  1. Crie um script que solicite uma senha ao usuário usando read -s, armazene em uma variável, exiba uma mensagem de confirmação e depois limpe a variável com unset.

    ✓ Resposta:
    #!/bin/bash
    read -s -p "Digite a senha: " SENHA
    echo "Senha recebida. Usando..."
    # Simula uso da senha
    sleep 1
    unset SENHA
    echo "Variável limpa."
  2. Explique por que usar set -x em um script que contém senhas é perigoso e como você evitaria isso.

    ✓ Resposta: O set -x imprime cada comando executado, incluindo variáveis expandidas. Se uma senha estiver em uma variável, ela aparecerá no log ou terminal. Para evitar, não use set -x em scripts com segredos, ou redirecione a saída para um arquivo com permissões restritas, mas o ideal é não expor segredos.
  3. Escreva um comando para criar um arquivo chamado chave.pem com permissões somente leitura para o dono.

    ✓ Resposta:
    touch chave.pem && chmod 400 chave.pem
  4. Qual é o efeito de definir umask 077 em um script? Dê um exemplo de permissões resultantes para um arquivo e um diretório.

    ✓ Resposta: Com umask 077, novos arquivos terão permissões 600 (rw-------) e diretórios 700 (rwx------). Exemplo: touch arq cria arq com -rw-------; mkdir dir cria dir com drwx------.
  5. Liste três boas práticas para proteger segredos em scripts shell.

    ✓ Resposta: 1. Não hardcode segredos; use variáveis de ambiente ou arquivos protegidos. 2. Use permissões restritivas (600/700) para arquivos e diretórios sensíveis. 3. Limpe variáveis de ambiente após o uso com unset e evite set -x em scripts com segredos.