ブログに戻る

フォロー&ご登録

Compute で安全なサンドボックスを実現するための Cranelift の検証

Pat Hickey

Principal Software Engineer, Fastly

Chris Fallin

WebAssembly の Staff Software Engineer, Fastly

Sandra Escandor-O’Keefe

Offensive Security Engineer, Fastly

Fastly は、さまざまなプラットフォームで動作する WebAssembly ベースのコンパイラツールや基盤を共同で開発するオープンソースコミュニティを作ることを目指し、2019年に Bytecode Alliance の設立に携わりました。Fastly のサーバーレスコンピューティング環境 Compute は、WebAssembly を基盤としています。WebAssembly プログラムはネイティブコードよりも強力なセキュリティを提供するため、Fastly は WebAssembly の未来に今後も投資を続けます。

今回は、WebAssembly の実装における重要なセキュリティコンポーネントについてご紹介します。Cranelift はオープンソースの次世代コードジェネレーターで、WebAssembly と組み合わせることでサンドボックス型のセキュリティを提供できます。

以前の記事では、Cranelift に存在した特定のセキュリティ問題が悪用される前に、Fastly がどのようにしてそれを検出し、対応したかについて説明しました。今回は、焦点を絞ってセキュリティに特化した評価プロセスと通常の開発プロセスの両方で、こうした問題を発見するために私たちが行っているプロアクティブかつ継続的な取り組みについてご紹介します。ソフトウェアの安全性を確保するためには、開発のライフサイクル全体を通じて、多岐にわたるツールや手法を駆使しながらセキュリティに取り組む必要があると私たちは確信しています。

この記事では、そのうちの2つの手法に焦点を当てます。ひとつは、よく知られているソフトウェアのテスト手法である「ファジング」の適用方法です。もうひとつは、私たちが最近実施した Cranelift の新しいコード生成バックエンドに対する包括的なセキュリティ評価手法です。それでは、Cranelift とは何か、そしてそれを改善するための取り組みについてもう少し詳しくご説明します。

Cranelift とは

Cranelift は、アーキテクチャに依存しない形でプログラムを取り込み、そのプログラムが実行される特定のプロセッサーに対応した高速なコードを生成するネイティブコードジェネレーターです。安全で効率的なソフトウェア基盤の構築を目指す Bytecode Alliance の重要な柱となっているコンポーネントです。

Cranelift は当初、Firefox のコンパイラバックエンドに追加される予定でしたが、Cranelift チームはその後、Firefox 以外の多くの状況でも使用できるようにエンジンを構築しました。Bytecode Alliance は、Lucet や Wasmtime ランタイムのような Cranelift の上に構築された WebAssembly エンジンを含む、Cranelift を中心としたユーザーと開発関係者のコミュニティづくりに力を注いでいます。Fastly は Bytecode Alliance と共に、パフォーマンスとセキュリティを向上させ、このプロジェクトのすべてのユーザーに利益をもたらすように積極的に取り組んでおります。

Compute での安全なサンドボックスの実現

では、実際どのように機能するのでしょうか?Cranelift を使用すると、WebAssembly エンジンは信頼されていない WebAssembly プログラムを取り込み、サンドボックス化された安全なマシンコードにコンパイルすることができます。Cranelift は、元の WebAssembly コードをマシンコードに変換する際、安全性とセキュリティのチェックを挿入し、コード実行時に実装します。そのため、サンドボックスチェックを追加することで、元の WebAssembly がマシンコードに正しく変換されていることを確認することが重要になります。先日の記事で述べたように、これらのチェックが失敗した場合に備えて追加の保護対策が用意されていますが、それにはできるだけ頼らないように努力しています。

このアプローチにより、Compute では非常に速い起動時間で効率的にサービスを実行することができます。これが可能なのは、オペレーティングシステムのプロセス (最先端のブラウザや一部の共有ホスティングプラットフォームなど) やコンテナ (多くのサーバーレスクラウドサービスなど)、あるいは仮想マシン全体 (非管理型クラウドホスティングなど) を使用して個々のサービスやリクエストを分離しているからではなく、ネイティブコード内の軽量なインラインサンドボックスチェックを使用してためです。それにより、複数のサービスのネイティブコードを1つの OS プロセス内に安全に共存させることができるわけです。

Cranelift がすべてのセキュリティサンドボックスチェックを維持しつつコードをコンパイルすると同時に、お客様のサイトに対するすべての Web リクエストの前に配置するのに十分な速度を確保できるよう、Fastly は注力しています。

テスト工程 : ファジングとセキュリティ監査

お客様が利用するサービスのセキュリティにとって、正しくコンパイルされたコードが非常に重要であり、ミスコンパイルは重大な問題であることがお分かりいただけたと思います。ではコンパイラがこの基準を満たすためには、どうすれば良いのでしょうか?

最初に使うのは「ファジング」と呼ばれる技術です。ファジングとは、プログラムを破壊するために、さまざまなランダム入力をプログラムに投げるテストの一形態です。ランダムな入力は、テスト担当者が手動でテストを書くときには思いつかないようなエッジケースに当たるので、プログラムをテストするための強力な手段となります。優れたファジングフレームワークは、プログラムがこれらの入力に対してどのように反応するかを実際に観察し、プログラム内のすべてのコーナーケース (通常の使用方法を超えた使われ方をした場合) に当てはまる方法を見つけます。このアプローチは「フィードバック駆動型ファジング」と呼ばれます。このようなシステマティックなアプローチは、見落とされていたバグを発見するのに非常に有効です。

Mozilla ではすでに Cranelift について綿密なファジングを実施していましたが、Fastly でも独自にテストを行っています。今日では、Wasmtime プロジェクトが Google の OSS-Fuzz インフラストラクチャのファジングプロジェクトに参加したことで、コンパイラに対するファジングが継続的に行われています。実際、主に Rust で記述されたプロジェクトが OSS-Fuzz プログラムに採用されたのは、このプロジェクトが初めてでした。Cranelift のファジングベースのテストを向上させる一環として、Fastly は、Cranelift ベースの実行を WebAssembly インタープリタと比較したり、複数の Cranelift バックエンドを相互に比較したり、正しいレジスタの割り当てを記号を使用して証明したりするコードを付け加えました。Bytecode Alliance は、ファジングがコンパイラやランタイムのバグを見つけるための特に強力な方法であると指摘していますが、私たちも同感です。

また、セキュリティ企業である Atredis Partners と提携し、重点的にセキュリティ評価を実施しました。この評価では、手動による静的解析と動的テストを行い、レジスタの割り当て、命令のエンコーディングと最適化、そしてランタイムが生成されたコードとの接点となる潜在的な攻撃対象領域に焦点を当てました。また、良好なコードカバレッジを確保するために、既存のファジングハーネスの調査も行いました。この評価では、Lucet ランタイムと新しい Cranelift のバックエンドが適切に設計され、実装されており、ファジングを含むテスト手法が適切に利用されていることがわかりました。

まとめ

Fastly では、コンパイラや (Lucet のような) 大規模なシステムへの統合の開発を行う際に、徹底したテストと検証を継続して行っています。さらに、バグが発生したときに対応するためのプロセス (人的プロセスと技術的プロセスのいずれも) を導入しているので、Cranelift はサーバーレスコンピューティング環境において、信頼性の高い、高速で安全なコンポーネントとして、確実に機能するはずです。Cranelift が Compute のサンドボックス化を進めていく中で、Fastly はお客様とオープンソースコミュニティ全体に貢献できるように、そのスピードと品質に対する投資を続けていきます。