Pular para conteúdo

AUR-528 — Pacote malicioso ou typosquat bloqueia o PR

Medido antes (pela leitura)

  • Depois do AUR-527, um advisory MAL- era julgado como qualquer advisory: severidade (normalmente ausente nos registros MAL-) contra fail_on; sem fail_on, informativo; uma exceção cve/MAL-... o aceitava.
  • Nenhum metadado de registro era consultado; o modelo não olhava pacotes novos.
  • fail_on do AUR-527 usava o limiar do gate.fail_on, onde critical e high são o mesmo nível: uma suspeita high reprovaria sob fail_on: [critical]. A escada de dependências passou a quatro níveis (critical > high > medium > low), mantendo a leitura de limiar ("este nível e acima"); docs e spec do AUR-527 atualizados.

Decisão

  • internal/gate/dependencies_policy.go: judgeMalicious — advisory MAL- (pelo id ou alias, Vulnerability.Malicious) reprova sempre (blocksMalicious), em qualquer fail_on; exceção ativa que o nomeie é recusada com aviso e nunca entra em AppliedExceptions.
  • internal/dependencies/registry.go: Registry e DepsDev (API v3 do deps.dev: pacote e versão), metadados achatados em campos nomeados. O sistema do deps.dev vem do modelo (license_system), sem tabela de ecossistemas.
  • internal/dependencies/suspicion.go + prompts/suspicion.md: o modelo recebe os pacotes novos/atualizados com os metadados e devolve suspeitas com evidência campo=valor; groundSuspicion mantém só a que cita pacote consultado e campos/valores exatos dos metadados (AC-005). Registro inalcançável = dependencies_metadata_unreachable; pacote sem sistema é declarado (Unvetted).
  • judgeSuspicion: severidade suspicion_severity (padrão high) contra fail_on; exceção suspicion/<pacote>.
  • O contribuidor julga os achados mesmo quando o relatório ficou inconclusivo depois da consulta OSV (registro fora do ar): um MAL- nunca se esconde atrás do inconclusivo.
  • cmd/aurumcode/dependency_check.go: registro deps.dev de produção (deps_dev_url).

Como cada AC/MUT é provado

tests/acceptance/AUR-528.sh (pacotes internal/gate, internal/dependencies):

  • AC-001 TestAUR528AC001MaliciousAlwaysFails.
  • AC-002 TestAUR528AC002MaliciousExceptionRefused.
  • AC-003 TestAUR528AC003UnreachableIsInconclusive, TestAUR528AC003UnreachableNeverClears (OSV 502 e registro fora do ar).
  • AC-004 TestAUR528AC004GroundedSuspicion (pacote lodahs, publicado há dias, script de instalação, LLM falso cita os campos), TestAUR528AC004SuspicionFollowsFailOn.
  • AC-005 TestAUR528AC005UngroundedSuspicionDiscarded (campo inexistente, sem evidência, valor divergente, pacote não consultado).
  • MUT-001: blocksMalicious passa a aplicar fail_on (p.gated && p.cfg.Fails(...)): AC-001 fica vermelho.

Riscos e fora do escopo

  • Código escrito sem compilar.
  • O deps.dev não expõe scripts de instalação nem dados do autor; o fixture do AC-004 os traz para provar o aterramento. Um registro mais rico entra como outra implementação de Registry.
  • Arquivos fora dos paths do card: internal/config (escada de severidade e suspicion_severity), docs/configuration.md (chaves novas) e docs/specs/AUR-527.md (escada).
  • Pacote que o deps.dev ainda não indexou (comum num typosquat novo) responde 404: dependencies_metadata_unreachable, inconclusivo por desenho (documentado).

Correções da revisão estática

  • Pacote novo que o registro não analisa (sem sistema do modelo, ou só faixa) é declarado e, com fail_on, inconclusivo (dependencies_unvetted_package), salvo quando o mesmo pacote foi analisado pelo lockfile da mudança; sem registro algum com fail_on ou licenses_denied, também inconclusivo (TestUnvettedPackageInconclusiveUnderFailOn).