[Go]プログラミング言語の脆弱性を読む - CVE-2022-29804
この記事ではGo言語に関連するCVEの内容を読んでみます。今回ピックアップしたのは2022年8月10日に報告された CVE-2022-29804 です。
前提知識
go言語の filepath.Clean というパスを整形する関数があります。 挙動は以下のような形でドキュメント記載のルールに従ってパスを綺麗にしてくれます。
func main() {
fmt.Println(filepath.Clean("./dir1/dir1-1/sample.txt"))
fmt.Println(filepath.Clean("./dir1/../dir1/dir1-1/sample.txt"))
fmt.Println(filepath.Clean("./dir1/../dir1/../dir2/../dir1/dir1-1/sample.txt"))
// 全て出力は dir1/dir1-1/sample.txt
}
バグの内容
この関数に、Windowsのドライブを相対パスで指定すると、全て絶対パスに整形されてしまうというバグです。CドライブはWindowsがインストールされているシステムドライブであり、ディレクトリトラバーサルに使われる可能性があります。
filepath.Clean(`.\c:`) // `c:` (正しくは `.\c:`)
filepath.Clean(`.\c:\foo`) // `c:\foo`(正しくは `.\c:\foo`)
filepath.Clean(`.\c:foo`) // `c:foo` (正しくは `.\c:foo`)
以下のIssueにて2022年4月21日に報告されました。
修正
上記のような文字列の場合先頭のドット(.)を除かないようにGoのバージョン1.18.3と1.17.11に修正が入りました。(ソースコードへのリンク)
if out.w == 0 && volumeNameLen(path[r:]) > 0 {
// When joining prefix "." and an absolute path on Windows,
// the prefix should not be removed.
out.append('.')
}