← voltar
CVE-2021-39226criticalsob ataqueCWE-287

Snapshot authentication bypass in grafana

95Vexday Risk Score

Corrija agora. Ela está sob exploração confirmada pelo CISA e tem exploit funcional público.

ssvc Actcvss 9.8epss 100%
da publicação à arma
Publicada no NVD5 de out.
CISA KEV+324d
probabilidade de exploração
100%top 1% das CVEs
exploração observada
simCISA + VulnCheck
Ação exigida pela CISAprazo federal: 2022-09-15

Apply updates per vendor instructions.

Resumo

Falha no roteador HTTP (macaron) do Grafana permite que requisições para os caminhos literais /api/snapshots/:key, /dashboard/snapshot/:key e /api/snapshots-delete/:deleteKey — com os dois-pontos e o nome do parâmetro digitados ao pé da letra, não substituídos por um valor real — sejam tratadas como rotas estáticas, contornando a extração normal do parâmetro de chave. O resultado é acesso não autenticado ao snapshot de menor chave no banco e, combinado com exclusão, a possibilidade de varrer e destruir todos os snapshots armazenados na instância. O CVSS 9.8 é justificado pela ausência de autenticação e pelo impacto total em C/I/A dos dados de snapshot, mas o raio de ação está limitado à feature de snapshots — não afeta dashboards, datasources ou credenciais diretamente.

Detalhamento técnico

O bug está no router interno do Grafana, baseado no framework macaron (pkg/macaron/router.go). O router tenta primeiro um 'fast match' para rotas estáticas antes de cair no matcher de rotas parametrizadas. Antes da correção, esse fast match não verificava se o path da requisição continha caracteres de parâmetro (':' ou '*'); então uma requisição literal para /api/snapshots/:key — com a string ':key' de fato na URL, não substituída por um valor — batia certo com a definição de rota registrada e era despachada como se fosse uma chamada válida ao handler, só que com o parâmetro de chave vazio.

Nos handlers de pkg/api/dashboard_snapshot.go (GetDashboardSnapshot, DeleteDashboardSnapshotByDeleteKey, DeleteDashboardSnapshot), o valor de c.Params(":key") ou c.Params(":deleteKey") saía vazio nesse cenário, e a query subsequente (GetDashboardSnapshotQuery com Key ou DeleteKey vazio) era executada sem validação, retornando o snapshot com a menor chave primária no banco em vez de um erro. A correção adiciona uma checagem explícita de len(key) == 0 nos três handlers, retornando 404, e ajusta o router do macaron para não usar o fast-match estático quando o path contém ':' ou '*'.

O atacante não controla qual snapshot é retornado — só sempre o de menor ID/chave primária. Isso não é um IDOR clássico de chave arbitrária; é um bypass que expõe sempre o snapshot mais antigo (ou o que sobrar depois de exclusões), o que é suficiente para enumeração sequencial: ver, deletar, ver o próximo que passou a ser o de menor chave, repetir.

Como é explorada

Para visualização, não é necessária autenticação nem configuração especial: basta uma requisição GET para o caminho literal /dashboard/snapshot/:key ou /api/snapshots/:key. Para exclusão sem autenticação, é necessário que o servidor tenha snapshot.public_mode = true no grafana.ini (o padrão é false); nesse caso a requisição para /api/snapshots-delete/:deleteKey remove o snapshot de menor chave sem login. Se o atacante já tiver qualquer credencial válida na instância (qualquer papel, sem exigência de admin), a exclusão funciona independentemente do public_mode, via /api/snapshots/:key ou /api/snapshots-delete/:deleteKey.

O valor prático do bug está na combinação: alternar entre visualizar e deletar o snapshot de menor chave permite percorrer, um a um, todo o conjunto de snapshots da instância — vazando o conteúdo de dashboards compartilhados via snapshot (que podem incluir dados de painéis, valores de métricas e, em alguns casos, texto embutido) e, ao final do processo, apagando permanentemente todos eles. Não há necessidade de adivinhar chaves ou tokens: o comportamento é determinístico e sequencial.

A CISA incluiu esta CVE no catálogo KEV, confirmando exploração ativa observada. O próprio advisory do fornecedor registra que a instância pública do Grafana Cloud foi auditada e não encontrou evidência de exploração antes do patch, mas isso não se estende a instâncias self-hosted, que são o alvo relevante do KEV.

Versões

Afetadas
Grafana 2.0.1 até 8.1.5 (todas as versões desde a introdução do recurso de snapshot).
Corrigidas em
7.5.11 e 8.1.6 (branches 7.5.x e 8.1.x, respectivamente). Não há menção de backport para ramos anteriores ao 7.5.

Como se proteger

Atualizar para Grafana 8.1.6 (branch 8.x) ou 7.5.11 (branch 7.5.x). O advisory recomenda migrar direto de 8.1.4 para 8.1.6, já que a 8.1.5 trouxe apenas uma correção não relacionada em gráficos de barra. Não há indicação de backport para ramos anteriores ao 7.5 — instâncias em versões mais antigas precisam subir de major/minor para receber a correção.

Se a atualização não for viável de imediato, o paliativo divulgado pelo próprio fornecedor é bloquear via proxy reverso (ou equivalente) o acesso aos quatro caminhos literais afetados: /api/snapshots/:key, /api/snapshots-delete/:deleteKey, /dashboard/snapshot/:key e /api/snapshots/:key (repetido no texto original do advisory). Segundo o fornecedor, esses caminhos literais não têm função normal e podem ser bloqueados sem efeito colateral — a exploração depende exatamente de acessar a string literal com os dois-pontos, não de uma URL com parâmetro real substituído, então bloquear esse padrão exato não impede o uso legítimo da feature de snapshot.

Desativar o snapshot.public_mode (mantendo o padrão false) reduz a superfície de exclusão não autenticada, mas não protege contra visualização não autenticada nem contra exclusão por um usuário autenticado qualquer — portanto não substitui o patch ou o bloqueio de caminho.

Como detectar

O próprio advisory do fornecedor detalha como auditar: em logs de proxy reverso/load balancer, procurar requisições para /dashboard/snapshot/:key, /api/snapshots/:key ou /api/snapshots-delete/:deleteKey (com os dois-pontos literais na URL) que retornaram HTTP 200. Em Grafana Enterprise com router_logging = true habilitado (feature de audit log), buscar por requestUri contendo /api/snapshots-delete/ ou /api/snapshots/:key, ou eventos do tipo 'snapshot' combinados com action 'delete'. Instâncias sem esse logging de auditoria habilitado, ou sem retenção de logs de acesso do proxy anteriores ao patch, não têm sinal confiável retroativo de exploração — o Grafana Cloud só conseguiu confirmar ausência de exploração porque tinha esses logs disponíveis.

Pesquisado e redigido com IA a partir do advisory do fornecedor e de análises públicas, com as fontes acima. Confira sempre a versão corrigida no advisory oficial antes de agir.
Grafana is an open source data visualization platform. In affected versions unauthenticated and authenticated users are able to view the snapshot with the lowest database key by accessing the literal paths: /dashboard/snapshot/:key, or /api/snapshots/:key. If the snapshot "public_mode" configuration setting is set to true (vs default of false), unauthenticated users are able to delete the snapshot with the lowest database key by accessing the literal path: /api/snapshots-delete/:deleteKey. Regardless of the snapshot "public_mode" setting, authenticated users are able to delete the snapshot with the lowest database key by accessing the literal paths: /api/snapshots/:key, or /api/snapshots-delete/:deleteKey. The combination of deletion and viewing enables a complete walk through all snapshot data while resulting in complete snapshot data loss. This issue has been resolved in versions 8.1.6 and 7.5.11. If for some reason you cannot upgrade you can use a reverse proxy or similar to block access to the literal paths: /api/snapshots/:key, /api/snapshots-delete/:deleteKey, /dashboard/snapshot/:key, and /api/snapshots/:key. They have no normal function and can be disabled without side effects.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Produtos afetados
grafana · grafana