HN 日本語サマリー

← 一覧へ戻る
プログラミング

ソフトウェアサンドボックスの基本

Software Sandboxing: The Basics (blog.emilua.org)

26 pointsby mococa1 コメント

要約

この記事は、ソフトウェアサンドボックスの基本的な概念と実装方法について解説しています。サンドボックスとは、プログラムの権限を制限し、システムリソースへのアクセスを制御する環境のことです。Unixの伝統的な権限管理では不十分な場合に、より高度なOSインターフェースや、特権昇格を伴わない「裁量的な権限降下」といった手法が重要であることを説明しています。

全文翻訳

ソフトウェアサンドボックス:基本 メニュー ホーム PDF EPUB JSON フィード ソフトウェアサンドボックスの領域に飛び込むことは、ほとんど未踏の領域に飛び込むことです。優れたサンドボックスをソフトウェアに実装するために必要な要素は散在しており、開拓者たちはまだ、新しい船乗りをよく理解された安全なルートに導くことができる統一された地図帳に十分な知識を集めていません。このブログ記事では、Emiluaのサンドボックスサポートに取り組む際に私が得た経験を共有します。誤解を避けるために、繰り返しが多くなるため、文章スタイルは少し損なわれるでしょう。ここに示されているLuaコードのサンプルには、未リリースのEmilua 0.11が必要であることに注意してください(リポジトリの開発ブランチから最新のコミットを取得してください)。 まず、私たちが同じ認識を持っていることを確認するために、サンドボックスの非公式(しかし有用な)定義をいくつか見てみましょう。Julien TinnesとChris Evansが2009年のHack In The Box Malaysiaで提示した定義は次のとおりです。 プロセス権限を制限する能力: プログラム的に; マシン上の管理者権限なしで; 裁量的な権限降下。 これは、ボールを転がし続けるための非常に良い定義です。それぞれの点を個別に素早く見ていきましょう。ただし、今日私が持つ意見は、J. TinnesとC. Evansが2009年の講演中に持っていた意見とは少し異なることに注意してください(特に「スーパーユーザーAPIを使用しても大丈夫か?」という点について)。そのため、私の説明は少し異なり、2025年において私がより良いプラクティスと考えるものへとあなたを導くでしょう。 プログラム的な権限降下 OSは、ユーザーとソフトウェア開発者に異なるインターフェースを提供します。システム管理者は伝統的に、サービスを分離するためにファイルシステム権限に依存しています(UNIXデーモン)。もし私たちがサードパーティのプログラムにこれらの権限を自由に(変更)することを許可した場合、それはシステム管理者がそもそも強制しようとしていたポリシーを無効にしてしまいます。さらに、サードパーティのプログラムは独自の仮想世界を抽象化しており、ほとんどの場合、UNIXファイルシステム権限は、そのような他の仮想世界が必要とするセキュリティポリシーをモデル化するのに適していません。Twitterフィードを表示したり、Identi.caでメッセージを送信したりできる人を定義するためにUNIX権限モードを使用しますか?ファイルシステム権限は、システム管理者がアクセス権を制限するために持つ唯一のノブではありませんが、ここで展開された推論は、これらの他のノブにも適用されます。それにもかかわらず、プロセスは必然的にOS上で実行され、プロセスが対話するカーネル露出リソース(例:ファイル)があります。ソフトウェア開発者にとって重要なのは、このインターフェースです。FirefoxのようなWebブラウザはDRMプラグインを実行しており、Firefoxがアクセスできるすべてのファイル(通常はユーザーのHOMEディレクトリ内のすべてのファイル)にフルアクセスを許可せずに、そのようなサードパーティプラグインを実行することは望ましいです。setuidgidのような従来のツールはここでは役に立たず、システム管理者が利用するインターフェースとしての有用性は限られています。setuidgidおよび類似のツールは、ソフトウェア開発者が使用することを意図したインターフェースではありません。 XKCD 1200: 認証 プログラム的な権限降下のために、従来のUNIXインターフェースは不十分であり、このギャップが実際に重要なOSは、従来のUNIXを超える拡張インターフェース(例:FreeBSDのCapsicumとLinuxのSeccomp)を提供します。 ルートなしで権限を降下させる サンドボックス化のための優れたインターフェースが利用できなかったとき、プログラマーはスーパーユーザーのみが利用できるメカニズムを悪用することによって、それでもサンドボックスを作成する方法を見つけました。このクラスで最も象徴的な技術は、chroot jailを設定するヘルパーsuidバイナリです。これらのアプローチの明白な問題は、すべてのプログラムで利用できるわけではないということです。任意のプログラムがsuidバイナリをインストールすることを許可すると、あらゆるセキュリティ対策が無効になります。Suidバイナリは、一時的にシステム全体に対する完全な管理権限に昇格することと同義です。権限は、決して増加するのではなく、常に減少するべきです(最小権限の原則)。ここでのもう1つの関連する懸念は、カーネルの攻撃対象領域を指数関数的に増加させるバックファイアするAPIを設計しないことです。Dockerブームは、サービスを安価に分離するメカニズムとしてLinux名前空間を普及させました。しかし、ネストされたユーザー名前空間内では、プロセスは(その名前空間内で)スーパーユーザーとして実行され、通常はスーパーユーザーのみが利用できるカーネル内のコードパスが、すべてのユーザーが利用できるようになります。私たちは、この前提で書かれていなかった10年以上のカーネルコードを持っています。この決定は過去にセキュリティ問題を引き起こしており、再び起こることは避けられません。Andy Lutomirskiを引用すると次のようになります。 「CLONE_NEWUSERを使用して任意のネットワーク名前空間に対してCAP_NET_ADMINを取得し、それによってネットワーク構成APIにアクセスできる能力は、巨大なリスクであると考えています。例えば、特権のないユーザーはiptablesにアクセスできます。そこに特権昇格がないなら、私は帽子を食べるでしょう。」— Andy Lutomirski https://lore.kernel.org/all/CALCETrWYRvqhyCwx5RX6L3TEYCfW0j6ThFUc+ASL7BpxgO5dEQ@mail.gmail.com/ ユーザー名前空間は、信頼できるコンテナ化ツール(例:Docker)にこのインターフェースを制限する限り、許可しても問題ありません。しかし、Linux名前空間はソフトウェアサンドボックス化のためのひどいインターフェースです。LinuxのLandlockのような新しいサンドボックスインターフェースは、Linuxのユーザー名前空間で見られたような災害を避けるために、カーネルの攻撃対象領域を指数関数的に増加させないように慎重に設計されました。さらに、Linux内で名前空間を制限する新しい方法がまだ開発されており、長期的には一般的なサンドボックスメカニズムとしてそれらに依存するのは悪い賭けです。Emiluaに費やしたソフトウェアサンドボックス研究の最初の数年間は、Linux名前空間にのみ焦点を当てていました。多くのフラストレーションの後、焦点は異なるソリューションに移りました。現在、EmiluaはLinux名前空間のサポートを提供していますが、意図されたユースケースはコンテナ化ツールの作成です。Emilua内での適切なサンドボックス化のために、Linux名前空間以外のメカニズムを使用します。 裁量的な権限降下 実際、サンドボックスは次のように定義することもできます。 「悪意のある可能性のあるソフトウェアが、ソフトウェアが許可されているシステムリソース以外のものにアクセスするのを防ぐ、制限された制御された実行環境。」— Committee on National Security Systems (CNSS) Glossary 2022 https://www.cnss.gov/CNSS/issuances/Instructions.cfm コードがサンドボックス化されていると見なされるために必要な特性について、実際にはコンセンサスはなく、定義は通常非常に緩いです。これらの定義は、これまで議論してきたプロパティを必要としません。したがって、まったく異なる用語が役立つかもしれません。J. Tinnesは「裁量的な権限降下」を提案しました。この記事で調べるのはこの種のサンドボックスです。裁量的な権限降下は、システム管理ポリシーを置き換えるものではありません。むしろ、それらは互いに補完し合い、連携して採用されるべきです。 実践的なサンドボックス:プロセス これで、うまくいけば同じ認識を持てたはずです。私たちにとってサンドボックスとは、裁量的な権限降下を意味します。既存の現実世界のOSで、サンドボックス化されていないプログラムからサンドボックス化されたプログラムにどのように移行しますか?今日のすべての主要なOSでは、権限の境界はプロセスレベルにあります。資格情報は各プロセスに関連付けられており、カーネルはプロセスがアンビエント権限を使用して新しいリソースを取得できるかどうかを決定する際にチェックするものです。Linuxは実際には異なり、スレッドレベルで資格情報を関連付けますが、スレッドレベルで根ざした設計は機能しません。そのため、glibcはカーネルがその点でずさんであっても、スレッド間で資格情報を同期するために余分な作業を行います。GNOME開発者はスレッドレベルで作業できると考えましたが、CVE-2023-43641で誤りであることが証明されました。Adam Langleyは理論的にはスレッドレベルで機能するメカニズムを説明しましたが、実際には経済的にコストが高すぎ、決して機能しないと思います。 「したがって、私たちがやっていることは次のとおりです。信頼されていない各スレッドには、同じプロセスで実行されている信頼されたヘルパー スレッドがあります。これは明らかにかなり敵対的な環境を提示します」