Security auditing de scripts: análise estática e dinâmica
1. Introdução à Segurança em Scripts Bash
Scripts Bash são amplamente utilizados para automação de tarefas administrativas, pipelines de CI/CD e operações de infraestrutura. No entanto, sua natureza interpretada e o uso intensivo de comandos externos criam uma superfície de ataque significativa. Riscos comuns incluem injeção de comandos via variáveis não sanitizadas, vazamento de variáveis de ambiente contendo senhas ou chaves, e o uso inseguro de eval que pode executar código arbitrário.
A auditoria de segurança em scripts Bash divide-se em duas abordagens complementares:
- Análise estática: examina o código-fonte sem executá-lo, identificando padrões perigosos, vulnerabilidades de sintaxe e más práticas.
- Análise dinâmica: monitora a execução real do script em ambiente controlado, observando chamadas de sistema, fluxo de dados e comportamento em tempo real.
O ciclo de vida de um script seguro envolve quatro etapas: desenvolvimento com práticas defensivas, revisão estática automatizada, testes dinâmicos em sandbox e implantação controlada em produção.
2. Análise Estática com Ferramentas de Linter e Scanner
ShellCheck: regras de segurança integradas
O ShellCheck é a ferramenta mais madura para análise estática de scripts Bash. Ele detecta automaticamente vulnerabilidades como:
- SC2069: expansão insegura de $() sem aspas
- SC2086: variáveis sem aspas duplas permitindo globbing e splitting
- SC2155: declaração de variáveis exportadas com export em vez de declare -x
Exemplo de script vulnerável e correção:
#!/bin/bash
# Script vulnerável
arquivo=$1
rm -rf $arquivo # SC2086: variável sem aspas
# Correção segura
rm -rf "$arquivo"
Bashlint e shfmt: validação de sintaxe
O bashlint (parte do pacote checkbashisms) valida sintaxe específica do Bash, enquanto shfmt formata o código automaticamente, reduzindo ambiguidades que podem levar a vulnerabilidades.
Padrões perigosos detectáveis
# Uso inseguro de eval
eval "echo $1" # Permite injeção de comandos
# Source de fontes externas sem validação
source "$ARQUIVO_BAIXADO" # Código arbitrário pode ser executado
# Substituição de comando sem sanitização
resultado=$(curl -s "$URL") # Se URL for controlada pelo atacante
3. Análise Estática Avançada com Regras Customizadas
Scripts de auditoria com grep/awk
Para cenários específicos, é possível criar auditores customizados:
#!/bin/bash
# Auditor de padrões perigosos
padroes=(
'eval\s'
'rm\s+-rf\s+[^"]'
'sudo\s+.*\$'
'exec\s+.*\$'
'source\s+\$'
)
for padrao in "${padroes[@]}"; do
grep -rnE "$padrao" --include='*.sh' /caminho/scripts
done
Integração com SAST (Semgrep, CodeQL)
Ferramentas de SAST como Semgrep permitem criar regras específicas para Bash:
rules:
- id: bash-eval-injection
pattern: eval "... $... ..."
message: "Uso de eval com variável não sanitizada"
severity: HIGH
languages: [bash]
4. Análise Dinâmica por Monitoramento de Execução
Rastreamento com strace e ltrace
O strace captura chamadas de sistema, revelando operações suspeitas:
# Monitorar execução do script
strace -f -e trace=execve,open,unlink,rename ./script.sh 2>&1 | grep -E 'execve|open'
# Saída típica:
# execve("/bin/rm", ["rm", "-rf", "/tmp/dados"], ...) = 0
# open("/etc/passwd", O_RDONLY) = 3
Modo debug com bash -x
#!/bin/bash
export PS4='+ [${BASH_SOURCE}:${LINENO}] ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
set -x
# Comandos do script
arquivo="$1"
rm -f "$arquivo"
Sandboxing com Bubblewrap
# Executar script em ambiente isolado
bwrap --ro-bind /usr /usr \
--ro-bind /bin /bin \
--tmpfs /tmp \
--proc /proc \
--dev /dev \
--unshare-all \
--seccomp 10 \
./script.sh
5. Testes de Injeção e Validação de Entrada
Simulação de ataques
# Teste de injeção via IFS
IFS=';' read -r cmd1 cmd2 <<< "comando1;rm -rf /"
echo "$cmd1" # Apenas "comando1"
# Teste de globbing malicioso
touch '--help' '--version'
ls * # Expande para todos os arquivos, incluindo flags
Validação defensiva
#!/bin/bash
# Validação com [[ ]]
if [[ "$1" =~ ^[a-zA-Z0-9_]+$ ]]; then
echo "Entrada válida: $1"
else
echo "Entrada inválida" >&2
exit 1
fi
# Validação com case
case "$2" in
start|stop|restart) action="$2" ;;
*) echo "Ação inválida" >&2; exit 1 ;;
esac
Detecção com shellcheck + bash -n
# Verificação de sintaxe sem execução
bash -n script.sh || echo "Erro de sintaxe detectado"
# ShellCheck com foco em segurança
shellcheck --severity=warning --shell=bash script.sh
6. Automatização da Auditoria em Pipelines CI/CD
Integração em GitHub Actions
name: Security Audit
on: [push, pull_request]
jobs:
shellcheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run ShellCheck
uses: ludeeus/action-shellcheck@master
with:
severity: warning
format: sarif
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: shellcheck.sarif
Bloqueio de deploys
#!/bin/bash
# Script de auditoria para CI/CD
resultado=$(shellcheck --severity=error --format=json scripts/*.sh)
qtd_erros=$(echo "$resultado" | jq 'length')
if [ "$qtd_erros" -gt 0 ]; then
echo "Erros críticos encontrados: $qtd_erros"
exit 1
fi
7. Boas Práticas e Mitigações Pós-Auditoria
Substituição de comandos perigosos
# Ruim: find -exec com expansão
find /tmp -name "*.tmp" -exec rm -f {} \;
# Bom: while read com sanitização
find /tmp -name "*.tmp" -print0 | while IFS= read -r -d '' arquivo; do
rm -f "$arquivo"
done
Configuração defensiva do shell
#!/bin/bash
set -euo pipefail
trap 'echo "Erro na linha $LINENO: comando $BASH_COMMAND"' ERR
# Tratamento seguro de arquivos temporários
tempfile=$(mktemp) || exit 1
trap 'rm -f "$tempfile"' EXIT
Documentação de exceções
# shellcheck disable=SC2086 # Intencional: expansão para múltiplos arquivos
rm -f $ARQUIVOS_TEMP
Referências
- ShellCheck: Official Documentation — Ferramenta de análise estática para scripts Bash com regras de segurança integradas
- OWASP Bash Scripting Security Cheat Sheet — Guia completo de boas práticas de segurança para scripts Bash
- Semgrep: Bash Rules Registry — Repositório de regras SAST customizáveis para detecção de vulnerabilidades em Bash
- Bubblewrap: Sandboxing Tool — Ferramenta de isolamento de processos para execução segura de scripts
- GitHub Actions: ShellCheck Action — Ação oficial para integração de ShellCheck em pipelines CI/CD
- strace Manual Page — Documentação completa do rastreador de chamadas de sistema para análise dinâmica
- CodeQL: Bash Query Library — Biblioteca de consultas de segurança para análise de scripts Bash com CodeQL