Ir para o conteúdo

50 · Os códigos de um relatório: QG e QC

Um relatório do stalwart verify ou de uma varredura traz achados sob dois tipos de código. Os códigos QG são do caçador de bugs: caminhos através das suas regras, encontrados no grafo dos agentes, no rulebook e no roteador. Os códigos QC são das verificações de código: problemas em como o código das suas ferramentas lida com a rede e com credenciais. Este capítulo diz em que os dois diferem, lista toda regra QC e diz como cada família se relaciona com os padrões sob os quais uma equipe de segurança arquiva achados.

Idiomas

O seletor lê turnos escritos em inglês e em português do Brasil (pt-BR). O idioma é escolhido, nunca adivinhado a partir do turno: na página Settings do console (Language the selector reads), em language numa requisição de plano, ou no settings.language do seu arquivo de vocabulário; sem nenhum deles, inglês. Um turno em português pode ser digitado com os acentos ou sem eles. O português europeu não é uma gramática que o seletor tenha, e um turno em qualquer outra língua não é lido.

Duas famílias

QG -- o caçador de bugs QC -- as verificações de código
Lê o grafo dos agentes, o rulebook ou a planilha de regras, o catálogo, o roteador na frente deles os arquivos-fonte da pasta onde está o agent.yaml: Python, JavaScript, TypeScript e Go
Roda nos servidores da Stalwart, como um job hunt na sua máquina, no runtime licenciado; o seu código nunca sai dela, só a contagem de achados por regra vai com o registro
Um achado traz a regra, a severidade e o tipo, o local no arquivo que você edita, o fluxo, uma reprodução, uma correção conferida e as entradas OWASP a regra, o CWE, o arquivo e a linha, o caminho que o valor percorreu até ali e uma frase
Reprova o gate pelas condições do gate: um achado Critical novo, uma linha quebrada das suas próprias tabelas e as outras do capítulo 28; o perfil de qualidade de um projeto pode pedir mais todo achado, sem nível, sem dispensa e sem comentário de supressão: só mudar o código o resolve
Guardado ao longo do tempo num projeto, contra a sua linha de base, com as decisões de uma pessoa -- falso positivo, risco aceito com validade (capítulo 51) não guardado: a próxima execução lê o código como ele estiver

A primeira é uma pergunta sobre rotas: se um turno, um documento ou outro agente pode fazer o agente fazer o que as suas regras dizem que ele não deve. A segunda é uma pergunta sobre código: se uma ferramenta envia dados em texto claro, confia num servidor que deveria verificar ou guarda um segredo onde ele pode vazar. Uma resposta limpa a uma não diz nada sobre a outra.

As regras QG

O caçador de bugs tem 49 regras, em quatro faixas:

  • QG0xx são encontradas numa política ou num grafo de agentes: um caminho através de uma regra.
  • QG1xx são itens de revisão, security hotspots: uma pessoa decide se cada um é um problema.
  • QG2xx dizem o que uma varredura não conseguiu decidir ou descrever. QG201 Undecided é a que um relatório limpo ainda precisa ser lido para encontrar.
  • QG3xx são encontradas num host construído a partir do seu catálogo e do roteador na frente dele.

As páginas de regras têm uma página por regra: quando é levantada, por que importa, como corrigir, a severidade e as entradas OWASP. O capítulo 28 lê um achado linha por linha.

As regras QC

Toda regra que as verificações de código rodam, a partir do pacote de regras que o runtime lê:

Segurança de rede

Regra CWE Levantada onde o seu código O que a resolve
QC001 CWE-1327 abre um socket de escuta -- um servidor, uma porta ligada -- que não seja um servidor MCP em loopback sobre o transporte http declarado não escute a partir do código de ferramenta; um servidor MCP roda em stdio, ou em loopback com --transport http
QC002 CWE-295 desliga a verificação TLS ou substitui o repositório de confiança -- verify=False, rejectUnauthorized: false, InsecureSkipVerify, ssl.CERT_NONE, um bundle de CA próprio remova a configuração; o repositório de confiança do sistema é o que as verificações aceitam
QC003 CWE-319 envia uma requisição por http:// ou ws:// a um host que não é loopback use https:// ou wss://
QC004 CWE-918 envia uma requisição a um endereço tirado de um argumento de ferramenta ou de uma resposta, sem conferi-lo antes contra uma lista constante fixe o host no código, ou confira o valor contra uma lista constante (if host in ALLOWED) antes da requisição
QC005 CWE-441 envia uma requisição a um host constante fora da lista de saída declarada com o catálogo (--egress) acrescente o host à lista de saída, ou remova a requisição
QC006 CWE-693 contorna o proxy do ambiente -- trust_env=False, uma configuração de proxy apagada, um socket cru deixe as configurações de proxy como o ambiente as dá, e use um cliente HTTP
QC007 CWE-494 roda código que buscou, importa código de uma URL ou instala pacotes em tempo de execução declare a dependência e instale-a antes de o agente rodar

Credenciais

Regra CWE Levantada onde o seu código O que a resolve
QC010 CWE-798 escreve um segredo no código-fonte -- um token, uma senha, uma chave num formato conhecido leia-o de uma variável de ambiente em tempo de execução, e revogue o que foi escrito
QC011 CWE-532 põe um segredo numa linha de log, na mensagem de uma exceção ou no resultado de uma ferramenta registre e devolva para que o segredo foi usado, nunca o segredo
QC012 CWE-598 põe um segredo na query string de uma URL envie-o num cabeçalho
QC013 CWE-312 guarda um segredo num armazenamento próprio -- um arquivo, um cache, um banco de dados leia-o da sua variável de ambiente a cada vez que precisar
QC014 CWE-522 lê uma credencial de outro lugar que não uma variável de ambiente -- um keyring, um arquivo .env, um .netrc, os cookies de um navegador, um arquivo de credenciais como ~/.aws/credentials leia-a de uma variável de ambiente com que o processo é iniciado
QC015 CWE-522 roda o seu próprio fluxo de login -- uma troca OAuth, um pedido de token deixe o gateway fazer o login (capítulo 37) e passe à ferramenta o token que ele obtém

Código que as verificações não conseguem ler

Regra CWE Levantada onde o seu código O que a resolve
QC020 -- não pode ser lido -- um arquivo que não é analisável, código minificado ou gerado, uma extensão nativa, uma linguagem para a qual as verificações não têm regras, código rodado a partir de uma string mantenha o código-fonte legível na pasta, ou tire dela o que não pode ser lido

Um segredo é um valor lido de uma variável de ambiente cujo nome contém uma palavra como token, secret, password ou api_key -- mas não um que só diz onde um segredo está, como TOKEN_FILE --, ou um literal num formato de chave conhecido. Um argumento de ferramenta é um valor que o modelo ou a pessoa dá a uma função de ferramenta. Uma requisição é uma chamada de um cliente HTTP, de um socket ou de um fetch.

QC005 precisa de uma lista de saída para comparar: stalwart catalogue import recebe uma com --egress. O stalwart verify não tem nenhuma, então não levanta QC005, e todo socket de escuta é QC001.

Lendo um achado QC

QC002 CWE-295 shop/tracking.py:8  This code turns TLS verification off (`verify=False`), at shop/tracking.py:8.
    shop/tracking.py:8  turns TLS verification off (`verify=False`)

A primeira linha é a regra, o CWE, o local e a frase. As linhas abaixo são o caminho: de onde o valor veio, cada função por que passou e onde terminou. Um achado sobre um segredo num log começa onde o segredo foi lido; um sobre o destino de uma requisição começa no argumento de ferramenta de onde ele veio. O capítulo 46 mostra este achado num relatório completo.

As verificações seguem um valor através das suas funções, então um achado pode estar num arquivo que nenhuma ferramenta importa diretamente. Elas leem todo arquivo-fonte da pasta, de ferramenta ou não, já que uma ferramenta pode importar qualquer um deles.

Os padrões

Um achado QG traz as entradas do OWASP Top 10 for LLM Applications e do OWASP Top 10 for Agentic Applications de que é uma instância, com a edição (LLM01:2026, ASI04:2026), no relatório e nas taxonomies do SARIF (capítulo 28). O capítulo 39 tem o inverso: quais regras cobrem cada entrada.

Um achado QC traz o CWE da fraqueza no seu código -- CWE-295 é validação imprópria de certificado -- e nenhuma entrada OWASP: as listas OWASP são sobre o que um agente pode ser levado a fazer, e uma regra QC é sobre como um trecho de código é escrito. QC020 não tem CWE: diz que as verificações não conseguiram ler o código, não que o código é fraco.

Os limites

  • As verificações de código leem segurança de rede e tratamento de credenciais, em Python, JavaScript, TypeScript e Go, e nada mais sobre o que o seu código faz: uma ferramenta que calcula o reembolso errado passa por elas.
  • Código que as verificações não conseguem ler é um achado, QC020, nunca uma aprovação: um arquivo que não é analisável, código minificado, uma extensão nativa ou código rodado a partir de uma string reprova o gate até ficar legível ou sair da pasta.
  • Um relatório QC limpo não é um relatório QG limpo, nem o contrário: cada um responde à sua própria pergunta.