As equipas que tentam acrescentar uma revisão de segurança a cada pull request costumam desistir ao fim de um mês. A fila cresce, os revisores leem na diagonal e a label torna-se uma formalidade. A falha oposta é igualmente comum: ninguém com contexto de segurança vê a alteração que reescreveu a gestão de sessões.
A resposta é encaminhamento. A maioria dos diffs traz pouco risco de segurança. Alguns poucos trazem a maior parte. Se conseguir identificar esses poucos pelo caminho, pode enviá-los automaticamente para os revisores certos e deixar o resto para a revisão normal entre pares e para os scanners.
O que merece um humano
Scanners como o Semgrep e o Gitleaks são bons em padrões: uma função perigosa, um token hard-coded, uma dependência sabidamente má. São fracos em lógica: se este endpoint verifica o dono certo, se este refactor removeu uma verificação, se este novo papel é demasiado amplo. A revisão humana compensa o custo onde a lógica decide a segurança.
Os caminhos que normalmente se qualificam:
- Autenticação e sessões. Login, emissão de tokens, reposição de password, MFA, armazenamento de sessões.
- Autorização. Código de políticas, definições de funções, middleware que verifica a propriedade.
- Criptografia. Tudo o que assina, encripta, faz hash de passwords ou gera tokens.
- Parsers e tratamento de ficheiros. Uploads, desserialização, extração de arquivos, obtenção de URLs.
- Dinheiro e limites. Pagamentos, saldos, quotas, rate limits.
- Infraestrutura como código. Políticas IAM, regras de rede, buckets públicos.
- Configuração de CI e deploy. Ficheiros de workflow, scripts de deploy, definições de ambientes.
A sua lista será diferente. Parta do seu threat model: os caminhos de código ligados aos seus objetivos de abuso mais importantes são os que deve encaminhar.
Encaminhe-o com CODEOWNERS
No GitHub, um ficheiro CODEOWNERS mapeia caminhos para revisores obrigatórios. Combinado com branch protection que exige aprovação do code owner, torna o encaminhamento automático. Um esboço para um repositório de serviço típico:
# .github/CODEOWNERS
# Default: the owning team reviews everything
* @example-org/payments-team
# Security-sensitive paths also need a security reviewer
/src/auth/ @example-org/payments-team @example-org/appsec-reviewers
/src/authz/ @example-org/payments-team @example-org/appsec-reviewers
/src/crypto/ @example-org/appsec-reviewers
/src/uploads/ @example-org/payments-team @example-org/appsec-reviewers
/infra/iam/ @example-org/platform @example-org/appsec-reviewers
# Pipeline and ownership rules are themselves sensitive
/.github/workflows/ @example-org/platform @example-org/appsec-reviewers
/.github/CODEOWNERS @example-org/appsec-reviewers
Há dois detalhes que importam. As regras posteriores sobrepõem-se às anteriores para o mesmo caminho, por isso ponha primeiro o padrão abrangente. E proteja o próprio ficheiro CODEOWNERS, senão qualquer pessoa pode remover uma regra no mesmo pull request que dela precisa.
Quem são os revisores
"appsec-reviewers" não precisa de ser uma equipa de segurança. Na maioria das organizações funciona melhor como um grupo de security champions: um ou dois programadores por área, com alguma formação, que conhecem o threat model da sua parte do sistema. Revêem com um contexto de domínio que uma equipa central não consegue igualar.
Dê-lhes uma checklist curta para as revisões encaminhadas, para que a revisão tenha forma:
- Cada novo entry point está autenticado, e verifica a ownership do objeto em que mexe?
- A alteração removeu ou contornou uma verificação existente?
- O input não fiável é validado onde é usado, e não só onde chega?
- Os secrets, tokens e chaves são tratados pela biblioteca ou store aprovados?
- Os erros e os logs estão livres de dados sensíveis?
- A alteração muda uma fronteira de confiança no diagrama de arquitetura?
Além dos paths
Os caminhos apanham a maioria dos casos, mas não todos. Algumas alterações arriscadas vivem em ficheiros comuns. Dois acrescentos baratos ajudam:
- Labels por conteúdo. Um workflow pode adicionar uma label
needs-security-reviewquando um diff toca em padrões como novas rotas, novas dependências ou alterações de permissões, e um ruleset pode exigir a revisão certa para essa label. - Autodeclaração. Uma checkbox no template de pull request: "Esta alteração afeta autenticação, autorização, pagamentos ou exposição de dados." Normalmente os autores sabem.
Mantenha o volume encaminhado baixo o suficiente para que os revisores leiam cada diff. Se a fila crescer, aperte os caminhos em vez de deixar os revisores ler na diagonal. Uma revisão encaminhada que demora um dia a começar vai ser contornada, por isso combine um tempo de resposta com o grupo de revisores e cumpra-o.
O que fazer na segunda-feira
- Liste os cinco a dez diretórios do seu repositório principal onde um bug seria um incidente de segurança.
- Crie um grupo de revisores com duas ou três pessoas que conheçam essas áreas.
- Adicione os caminhos ao
CODEOWNERS, incluindo a pasta de workflows e o próprio ficheiro. - Ative "Require review from Code Owners" na proteção de branches ou nos rulesets.
- Ao fim de um mês, conte os pull requests encaminhados e ajuste os caminhos para que a carga se mantenha razoável.
Onde isto fica na linha
Na torre (em desenvolvimento):