Pular para conteúdo

AUR-530 — Varredura agendada acha CVE publicada depois do merge

Medido antes (pela leitura)

  • .github/workflows/review.yml é on: workflow_call com um job review só de PR (github.event.pull_request.*); não declara gatilho próprio e não pode conceder security-events: write (o SARIF do PR sai como artefato e o caller faz o upload, AUR-521).
  • internal/render/sarif.go gera o SARIF do PR com partialFingerprints de regra, caminho, linha e contexto, sem automationDetails (a categoria vem do category: do caller).
  • A verificação de dependências (AUR-495) só existia sobre um diff.
  • docs/configuration.md dizia que "um futuro run agendado" atualizaria a mesma análise aurumcode-policy-gate; docs/getting-started.md listava os subcomandos sem mcp. Ambos corrigidos.

Decisão

  • internal/dependencies/scan.go: Scan sobre a árvore inteira: o osv-scanner extrai (uma execução, --recursive) os pacotes de todo arquivo que reconhece e essa extração é usada como está; o modelo aponta, na lista de arquivos rastreados, manifestos que o scanner não conhece e lê só esses (arquivo inteiro como linhas adicionadas, aterrado). Lista de arquivos acima do limite do modelo, modelo ausente, scanner ausente ou base inalcançável = inconclusivo.
  • cmd/aurumcode/cmd_dependencies.go: subcomando aurumcode dependencies --repo --sarif [--politica] [--categoria] (registrado em subcommands.go). Conclusivo: grava o SARIF e sai 0 (os achados não reprovam o job: o estado é o do code scanning). Inconclusivo: sai 1, diz o motivo e não grava SARIF. Configuração/uso: 2.
  • Impressão digital estável: o Context do achado é dependency/v1|<ecossistema>|<pacote>, com regra cve/<id> e caminho do manifesto, sem linha (0), versão, severidade nem data; o hash é o FindingFingerprint existente.
  • internal/render/sarif_categorized.go: BuildCategorizedSARIF / WriteCategorizedSARIF reusam BuildSARIFLog e a redação, e põem automationDetails.id (aurumcode/dependencies-scheduled/) no run.
  • .github/workflows/review.yml: job review com if: github.event_name != 'schedule'; job novo dependencies (só em schedule) que constrói a imagem, faz checkout da branch padrão, roda o subcomando no container e envia o artefato aurumcode-dependencies-sarif só com if: success().
  • action.yml não mudou: a action standalone é só de PR (documentado).
  • Docs: seção nova "Varredura agendada de dependências" (com o job de upload do caller, sem category:), link em docs/index.md, comentário velho da seção SARIF corrigido, lista de subcomandos em docs/getting-started.md.

Como cada AC/MUT é provado

tests/acceptance/AUR-530.sh (pacote cmd/aurumcode; a raiz temporária também copia .github para o teste do workflow):

  • AC-001 TestAUR530AC001ScheduledSARIF (resultado cve/GHSA-..., CVE na mensagem, automationDetails.id), mais os testes do registro de subcomandos (TestAUR572*).
  • AC-002 TestAUR530AC002StableFingerprintAndClosure: duas execuções vulneráveis com versão e severidade diferentes têm a mesma impressão digital; depois da correção o documento conclusivo não tem o resultado.
  • AC-003 TestAUR530AC003UnreachableKeepsAlerts (exit 1, sem SARIF, motivo no stderr), TestAUR530AC003WorkflowUploadsOnlyConclusive (job só em schedule, upload só com success()).
  • MUT-001: a impressão digital passa a incluir a versão: AC-002 fica vermelho.

Riscos

  • Código escrito sem compilar; o workflow não foi executado.
  • github/codeql-action/upload-sarif com category: sobre um SARIF que já tem automationDetails.id: o guia manda não passar category:.
  • Arquivos fora dos paths do card: internal/dependencies/scan.go, internal/render/sarif_categorized.go, docs/index.md, docs/getting-started.md.
  • Repositório com lista de arquivos rastreados acima de 256 KiB (por volta de 6 mil arquivos) fica inconclusivo na varredura agendada (documentado).

Correções da revisão estática

  • Pacote listado pelo scanner sem versão é Unresolved e a varredura fica inconclusiva, nunca conclusiva com menos pacotes (TestScanVersionlessPackageIsInconclusive).
  • Regra do SARIF pelo identificador canônico (o menor do advisory) e registros GO-/GHSA- do mesmo advisory num alerta só (TestAUR530AliasRecordsAreOneAlert).
  • Job agendado com timeout-minutes: 30 e persist-credentials: false em todos os checkouts.
  • Docs: a varredura agendada não aplica fail_on, preexisting, licenses_denied, suspeita nem exceptions; o osv-scanner precisa de rede.
  • Não feito: incluir a versão na impressão digital. Isso contradiz o AC-002 e o MUT-001 deste card (a mesma vulnerabilidade numa versão ainda vulnerável fecharia e reabriria o alerta, perdendo dispensa e histórico do code scanning). A versão continua na mensagem do resultado. Se o dono quiser um alerta por versão, o card precisa mudar o AC-002.