[インデックス 19480] ファイルの概要
このコミットは、Go言語プロジェクトのmisc/goplayディレクトリに存在していたgoplayプログラムを削除するものです。goplayは、Goコードをウェブブラウザ上で実行できる簡易的なウェブインターフェースでしたが、セキュリティ上の脆弱性(コード実行ベクター)を抱えており、その修正が困難であると判断されたため、削除されることになりました。
コミット
commit f83608256614f831430ee62ffdf86027c0be87a5
Author: Andrew Gerrand <adg@golang.org>
Date: Mon Jun 2 08:34:26 2014 +1000
misc/goplay: remove program
This program has barely been touched since it was first committed,
and in its current state it opens a code execution vector similar
to the one that was recently fixed in go.tools/playground/socket.
Rather than try to make it secure, remove it.
LGTM=minux, rsc
R=rsc, minux
CC=golang-codereviews
https://golang.org/cl/102030047
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/f83608256614f831430ee62ffdf86027c0be87a5
元コミット内容
このコミットの目的は、misc/goplayプログラムを削除することです。このプログラムは、コミットされて以来ほとんど手が加えられておらず、現在の状態では、最近go.tools/playground/socketで修正されたものと同様のコード実行ベクターを開放しています。これをセキュアにしようと試みるよりも、削除する方が良いと判断されました。
変更の背景
この変更の背景には、goplayプログラムが抱えていた深刻なセキュリティ上の問題があります。goplayは、ユーザーがウェブインターフェースを通じてGoコードを入力し、それをサーバー側でコンパイル・実行して結果を返すという機能を提供していました。しかし、このプログラムは、Go Playgroundのような厳格なサンドボックス環境を持たず、ユーザーが入力したコードを直接サーバー上で実行する設計になっていました。
コミットメッセージに「recently fixed in go.tools/playground/socket」とあるように、Go公式のPlayground(go.tools/playground/socketがそのバックエンドの一部を構成)でも同様のコード実行に関する脆弱性が修正されたばかりでした。goplayは、その設計上、ユーザーが任意のシステムコマンドを実行したり、ファイルシステムにアクセスしたりするような悪意のあるコードを注入できる可能性を秘めていました。
このような「コード実行ベクター」は、サーバーがインターネットに公開されている場合、深刻なセキュリティリスクとなります。攻撃者がこの脆弱性を悪用すれば、サーバーの乗っ取り、データの窃取、他のシステムへの攻撃の踏み台など、様々な悪意のある行為が可能になります。
goplayは、元々Go Playgroundの簡易版として提供されていましたが、セキュリティ対策が不十分なまま放置されていました。開発チームは、このプログラムをセキュアにするための労力と、それが提供する価値を比較検討した結果、セキュリティリスクを排除するためにプログラム自体を削除するという決断を下しました。これは、Goプロジェクトがセキュリティを非常に重視していることの表れでもあります。
前提知識の解説
このコミットを理解するためには、以下の前提知識が役立ちます。
- Go Playground: Go言語の公式ウェブサイト(golang.org)で提供されている、Goコードをブラウザ上で記述・実行できるインタラクティブな環境です。ユーザーが入力したコードは、Googleのサーバー上で安全なサンドボックス環境で実行されます。これにより、悪意のあるコードがシステムに影響を与えることを防ぎます。
goplay: Go Playgroundの初期の、よりシンプルなローカル版実装です。$GOROOT/misc/goplayに存在し、ユーザーが自身のローカルマシン上でGoコードを実行するためのウェブインターフェースを提供していました。公式Playgroundとは異なり、厳密なサンドボックス化は行われていませんでした。- コード実行ベクター (Code Execution Vector): 攻撃者がシステム上で任意のコードを実行できる経路や手段を指します。これは、ウェブアプリケーションの脆弱性(例: コマンドインジェクション、リモートコード実行)を通じて発生することが多く、最も深刻なセキュリティ脆弱性の一つとされています。
- サンドボックス (Sandbox): プログラムが実行される際に、そのプログラムがシステムのリソース(ファイルシステム、ネットワーク、メモリなど)にアクセスできる範囲を制限するセキュリティメカニズムです。サンドボックス内で実行されるプログラムは、たとえ悪意のあるコードを含んでいても、サンドボックスの境界を越えてシステムに損害を与えることが困難になります。Go Playgroundは、ユーザーコードを安全に実行するために高度なサンドボックス技術を利用しています。
go runコマンド: Go言語のソースファイルをコンパイルし、すぐに実行するためのコマンドです。開発中にGoプログラムを素早くテストするのに便利ですが、goplayのようにユーザーからの入力を直接go runに渡すような使い方をすると、セキュリティ上のリスクが生じます。
技術的詳細
goplayプログラムは、misc/goplay/goplay.goに実装されており、HTTPサーバーとして動作していました。主な機能は以下の通りです。
- フロントページ (
FrontPageハンドラ):http://localhost:3999/にアクセスすると、Goコードを入力するためのHTMLインターフェースを提供します。 - コンパイル・実行 (
Compileハンドラ): ユーザーが入力したGoコードをHTTP POSTリクエストとして受け取り、それを一時ファイル(例:/tmp/compileXXXX.go)に保存します。その後、os/execパッケージを使用してgo runコマンドを実行し、この一時ファイルをコンパイル・実行していました。プログラムの出力はHTTPレスポンスとしてクライアントに返されます。
この設計の根本的な問題は、go runコマンドが実行される環境にありました。goplayは、ユーザーが提供したコードを、特別な権限分離やリソース制限なしに、goplayプロセスと同じ権限で実行していました。これは、ユーザーが以下のような悪意のあるコードを送信した場合に、サーバー上で任意のコマンドが実行される可能性を意味します。
package main
import (
"fmt"
"os/exec"
)
func main() {
cmd := exec.Command("rm", "-rf", "/") // 危険なコマンドの例
output, err := cmd.CombinedOutput()
if err != nil {
fmt.Printf("Error: %v\n", err)
}
fmt.Printf("Output: %s\n", output)
}
このようなコードがgoplayを通じて実行された場合、サーバーのファイルシステムが破壊されたり、機密情報が漏洩したりする可能性がありました。公式のGo Playgroundは、このようなリスクを軽減するために、ユーザーコードを分離された環境(例えば、Linuxのcgroupsやnamespaces、または仮想マシン)で実行し、ネットワークアクセスやファイルシステムへのアクセスを厳しく制限するサンドボックス技術を採用しています。
goplayは、その簡易性ゆえにこれらのセキュリティ対策を欠いており、開発チームは、既存のコードベースにサンドボックス機能を実装するよりも、プログラム自体を削除する方が、Goプロジェクト全体のセキュリティを維持する上で合理的であると判断しました。これは、メンテナンスコストとセキュリティリスクのバランスを考慮した結果です。
コアとなるコードの変更箇所
このコミットでは、misc/goplayディレクトリ以下の全てのファイルが削除されています。
misc/goplay/Makefile:goplayプログラムのビルドに使用されていたMakefile。misc/goplay/README:goplayに関する簡単な説明が書かれたREADMEファイル。misc/goplay/doc.go:goplayパッケージのドキュメント。特に、セキュリティに関する警告が明記されていました。misc/goplay/goplay.go:goplayプログラムの主要なソースコード。HTTPサーバーの実装、コードのコンパイル・実行ロジック、HTMLテンプレートなどが含まれていました。
変更のタイプとしては、これら4つのファイルに対する「削除 (deletion)」のみです。
コアとなるコードの解説
削除された各ファイルは、goplayプログラムの機能とビルドプロセスに不可欠なものでした。
misc/goplay/Makefile: このファイルは、goplay.goをコンパイルして実行可能ファイルを生成するための指示を含んでいました。go build goplay.goというシンプルなコマンドが記述されており、goplayがGoの標準的なビルドプロセスに従っていたことを示しています。misc/goplay/README:doc.goを参照するように指示する非常に短いファイルでした。これは、プログラムの主要なドキュメントがdoc.go内に記述されていたことを意味します。misc/goplay/doc.go: このファイルは、goplayの目的、使用方法、そして最も重要な点として、セキュリティに関する警告を含んでいました。特に、「WARNING! CUIDADO! ACHTUNG! ATTENZIONE! A note on security: anyone with access to the goplay web interface can run arbitrary code on your computer. Goplay is not a sandbox, and has no other security mechanisms. Do not deploy it in untrusted environments.」という記述は、このプログラムがサンドボックス化されておらず、信頼できない環境での使用は危険であることを明確に示していました。この警告は、プログラムが抱えていた根本的なセキュリティ問題を開発者自身が認識していたことを裏付けています。misc/goplay/goplay.go: このファイルはgoplayの心臓部であり、ウェブサーバーのロジック、HTTPハンドラ、Goコードの受け取り、一時ファイルへの書き込み、go runコマンドの実行、そして結果のクライアントへの返送といった全ての機能が実装されていました。このファイルの削除は、goplayの機能全体がプロジェクトから完全に排除されたことを意味します。
これらのファイルを削除することで、Goプロジェクトは、メンテナンスされていない、かつセキュリティリスクを抱えたコンポーネントをコードベースから排除し、より安全で堅牢な状態を保つことを選択しました。
関連リンク
- Go Playground: https://go.dev/play/
- このコミットのGo Gerritレビューページ: https://golang.org/cl/102030047
参考にした情報源リンク
- Go言語公式ドキュメント
- Go言語のソースコードリポジトリ
- Go Playgroundのセキュリティに関する一般的な情報
- サンドボックス技術に関する一般的な情報
- Web検索: "go.tools/playground/socket security vulnerability" (ただし、このコミットの直接的な脆弱性に関する詳細なCVEは特定できませんでしたが、コミットメッセージの記述から、公式Playgroundで同様のコード実行ベクターが修正されたという事実を背景としています。)