Varredura SAST
As auditorias de dependência cobrem o código que você importou; o SAST cobre o código que você escreveu. Ele faz correspondência de padrões (e, com o modo de fluxo de dados, rastreia o fluxo) para as falhas clássicas: injeção de comando/SQL, travessia de caminho, desserialização insegura, eval/execução dinâmica em entrada não confiável, criptografia hardcoded, verificações de autenticação ausentes. Uma alta taxa de falsos positivos é inerente — a disciplina é triagem por acessibilidade, não ignorar em massa.
Quando executar
- Antes de um lançamento, no diff ou na árvore inteira.
- Quando você adiciona código que lida com entrada não confiável (uma nova ferramenta, um endpoint, um parser, um shell-out).
- Em CI em PRs (com escopo no diff, para ser rápido e sinalizar apenas novos problemas).
Execute
# semgrep — os conjuntos de regras de segurança. `auto` seleciona regras das linguagens detectadas.
semgrep scan --config auto --error .
# Conjuntos de regras focados e de maior sinal (menos ruído que auto):
semgrep scan --config p/security-audit --config p/secrets --config p/command-injection .
# Apenas diff (CI em um PR — rápido, apenas NOVOS achados):
semgrep scan --config auto --baseline-commit origin/main .
Para fluxo de dados mais profundo (a entrada não confiável REALMENTE ALCANÇA o sink?), o CodeQL é mais forte, porém mais pesado:
codeql database create db --language=javascript # or rust, python, …
codeql database analyze db --format=sarif-latest --output=results.sarif \
codeql/javascript-queries:codeql-suites/javascript-security-extended.qls
Triagem — rastreie, não descarte
Para cada achado, rastreie o caminho fonte → sink:
- A entrada é controlada pelo atacante? Um
child_process.execem uma constante hardcoded é ok; em um parâmetro de requisição, é um bug de injeção de comando. semgrep sinaliza o sink; VOCÊ confirma a fonte. - Existe um sanitizador entre eles? Se o valor for validado/escapado (um esquema zod, uma lista de permissões, uma consulta parametrizada) antes do sink, é um falso positivo — marque com
# nosemgrep: <rule-id>com uma linha explicando o porquê, não um ignore vazio. - Real? Corrija na fonte (valide/escape a entrada) ou no sink (parametrize, use a API segura), não suprimindo o aviso.
Nunca desative uma regra em massa para limpar o quadro — você suprimirá o único acerto real entre o ruído. Suprima por linha, com um motivo.
O que realmente corrigir (maior valor primeiro)
- Injeção (comando/SQL/template) em qualquer caminho acessível ao usuário — a classe de maior severidade e mais explorada.
- Travessia de caminho — caminhos não validados alcançando leituras/gravações de arquivos (um agente que grava arquivos é exatamente esse risco; bloqueie com uma verificação de escopo).
- Exec/eval inseguros de strings dinâmicas.
- Criptografia hardcoded / aleatoriedade fraca em um contexto de segurança.
O limite
O SAST vê o código-fonte de um repositório estaticamente — ele não pode ver configuração de runtime, um caminho de código orientado por variável de ambiente ou uma falha que só emerge através de um limite de serviço. Ele complementa, nunca substitui, um modelo de ameaças real e [[dependency-audit]]. Para um runtime de agente/ferramenta, o controle mais forte é muitas vezes arquitetural (um kernel que bloqueia cada ação) em vez de por linha — o SAST valida o código EM TORNO desse limite. Incorpore-o em [[security-preflight]].