Capabilities for Python? ============================= :原著者: Guido van Rossum :原文: http://neopythonic.blogspot.com/2009/03/capabilities-for-python.html :原文公開日: MARCH 6, 2009 私はMark Miller氏からemailを受け取った。`Zooko氏のcap-talkメーリングリスト(私は参加していない)のポスト `_ を引用したものである。Markは私に対して、 `capability `_ (訳注:チケットを用いたオブジェクトの保護システム)に対する見解を明らかにして欲しいと質問をしてきた(おそらくPythonに対して) 。他のメーリングリストへの参加が必要ということもあるので、自分の意見をここに書くことにした。検索エンジンの魔法によりこの記事は関係する場所に届くことが期待される (訳注:GuidoはGoogleで働いているため検索エンジンに触れているのかも) 。 彼がポストした内容によると、Zooko氏は、私がcapabilityについてのアイディアを敵視をしていて、Amoeba(Pythonは、もともとは、Amoeba向けに開発された)におけるパスワードを使ったcapabilityと、私の想定される態度や経験とを結び付けようとしているようである。これはいくつかの理由で奇妙だと言わざるを得ない。最初に、私が覚えている範囲内では、Amoebaのcapabilityはパスワードを利用しているわけではなく、不可逆(一方向)の関数と乱数を基にしている。それと、安全な壁に埋め込まれたイーサネットのソケット(これはおそらく流行らなかった:)も。二番目にAmoebaにおけるcapabilityの私の経験から、何年もかけて、プログラミング言語の `E `_ のようなモダンな言語から、Pythonへcapabilityを組み込む提案の中に効果のあるものがあったとは思えないことである。最初の提案は確か、Ka-Ping Yee氏とBenLaurie氏のものであった。この内容はというと、足し算的なアプローチよりも、引き算的なアプローチであったが、実質的にはユーザを制限するPythonサブセットのことである。 今回の件でもっとも驚いたことは、人々が私のひとつひとつの言葉を細かく読んでいるということである。私は宗教的な権威であるローマ法王でもなんでもないのに!私は、設計上の問題について独り言を言うのが好きなハッカーでしかないのである。その独り言も、正しいとは決して言えないのである。もし、私がつぶやいた意見に同意できず、何か質問をしたいというときは、私が投稿しているフォーラム(python-dev, python-ideas, もしくはこのブログ)に反応を返していただきたいと思う。私が読んでいないところに転送して、あれやこれや、推測をするのはやめていただきたい。 とりあえずこの件は置いて、ついでにこの記事はすべて独り言である、と表明したうえで、capabilityとPythonについての、現在の私の考えについていくつか表明したいと思う。 まず、これから説明するのはPythonに限定したいと思う。Capabilityに注力して設計された言語は既に存在して、ある程度の成功は収めているだろうし(例えばE)、その一方で、それらの言語が人気を獲得して、他の魅力的な機能が芽吹くまでには困難な時間を要すると思われるからである。ほとんどの開発者はセキュリティ=必要悪とみなしている。 こういった姿勢こそが、新しい言語を開発しないで、既存の言語にセキュリティ機能を追加しようという考え方になる理由である。これは、「薄汚れた(訳注:おそらくセキュリティ対策を考えていない、という意味)人々」を、彼らが既に知っている言語の少しだけ異なるバージョンにスイッチするほうが、完全に新しい言語を(一人で採用して)試行するのに比べてはるかに簡単である。もちろんこの説明は、熱狂的なセキュリティ狂信者の行動について否定をするものではない。同様のことは、一般的な「言語のマーケティング」という大きな世界でもいえる。C++はC言語と互換性を持たせる方針で設計され、これから外れるものは却下されている(訳注:実際は型チェックなどはより厳格な方向に変更されている)し、Javaは受け入れやすさを狙ってC/C++と類似するように設計されている。また、良く知られていることでいえば、Larry WallはPerlを設計するにあたり、初期のターゲットユーザがすでにsedとshを使っているという前提のもと、「ねじれた構文」を採用している。 私もPythonの設計においてこのような点から完全に自由であったとは言えないということは認める。私の場合は人気を取るためにそういうことわけではないが。私が他の言語からアイディアを借りてくるときには、そのアイディアがすばらしいものであると認めたときであって、現在のプラクティスに何かを追加するのを目的としていたわけではない。マーケットシェアについて心配はしていなかった。もし心配していたのであれば、グループを表現するためにインデントを使用することはしなかった。 とにかく、このような考えのメリットがあるにもかかわらず、何度も非互換な拡張の要求はやってきては、去り、というのをつづけている。一番最近転生してきたのは、Mark Seaborn氏による `CapPython `_ である。Wikiページをざっと読んでみると、このページの半分以上を「問題点」と書かれたセクションがあることから、Mark氏はセキュリティ機能追加による制約については良く気づいているように思える。もっとも最近の議論(Zooko氏のポストのトリガーとなった、と私が思っているもの)は、 `Tav氏が自分のブログに書いた内容 `_ から始まった。これには、CPythonの既存の制限実行モードへの、いくつかの謙虚な提案(これは私にとって励みになります!) と、この制限実行モードへのアタックのチャレンジが書かれていた。 `返信 `_ を見るとTav氏はこの分野の歴史に関して明るく、私が自分自身で提供するのよりも良いものを提供できそうに思える。 しかし、私はこの手法に関しては極めて疑わしいと思い続けている。Tav氏のスーパーバイザーコードに対するさまざまな攻撃によって、堅牢なスーパーバイザーを書くのがいかに信じられないほど微妙であるかということを物語っている。CPythonの制限実行モデルはサンドボックスの中の(信頼のない)コードが、スーパーバイザーの中へ、コールしにいくというモデルになっている。スーパーバイザーのPythonコードは完全な権限を持って実行されている。Tav氏のバージョンでは、スーパーバイザーがサンドボックス内にいくつかの関数オブジェクトを提供している。サンドボックスは、それらの関数を通じてのみ、スーパーバイザーへのアクセスが行えるというものである。Tav氏の目的としている変更により、いくつかのインスペクション(訳注:内省。Java用語のリフレクション=反省とほぼ同一)のための属性が関数から取り除かれる。また、スーパーバイザーがサンドボックス内から隠そうとしているデータや関数へのアクセスを提供するようなその他のクラスオブジェクトも取り除くとしている。この基本的な考え方はうまくいくだろうし、まだサンドボックスを直接突破する方法を見つけた人はいない。そのため、今のところサンドボックを堅牢に保つために、これ以上取り除く必要のある属性は存在しないように見える。 しかし、Tav氏のスーパーバイザーコードの中の脆弱性をたたく、いくつかの攻撃方法(不確かであるが)があきらかになっている。サンドボックス内のコードによって作成された、一見したところ安全なビルトイン関数(引数が設定される)の呼び出しにより、セキュリティを突破するのは難しそうに見えるが簡単である。この方法は、何年も前にSamuele Pedroni氏がPython 2.2以降の制限実行環境が危険ではないか、という疑念を明確にするのに使用された。 Samuele氏のアプローチは、(C)Pythonの二つの性質を結びつけるものである。ひとつはスーパーバイザーに使用されたビルトイン関数が、スーパーバイザーの権限で実行されてしまうということである。もうひとつは、Pythonの中では多くの場所、特にオブジェクトに渡される名前付きの属性で暗黙の変換が行われるということである。このような特性により、サンドボックスの抜け穴があると、ビルトイン関数にセットされるような「魔法の属性」を持つクラスを定義することができるようになり、スーパーバイザー権限でビルトイン関数が呼ばれるようになる。これは、いくつかの面白い引数をビルトイン関数に渡し結果を受け取ることができる知恵を持っている。詳しくは `Tav氏のブログ `_ に書いてある。 私がこのアプローチに対して心配しているのは、スーパーバイザーが提供しているそれなりに大きなPythonのサブセットがかなり複雑なことをしなければならないということである。例えば、モジュールのインポートの安全な仕組みの提供などである。複雑になればなるほど、私がスーパーバイザーのセキュリティに対して感じる信頼度は指数関数的に下がる。言い換えれば、Tav氏が"safelite.py"というスクリプトに書かれたおもちゃのスーパーバイザーコードに対し、クラックを試して、問題があればパッチを当てるという作業を何度か繰り返して進化させて、強固な防護壁を持つ完全な機能のスーパーバイザーを完成させるには、現実的な時間の枠内(10年単位)には収まるようには思えないのである。 それでは、他のもっと一般的な、堅牢なPythonのサブセットの話題に移ろうと思う。これらは、標準ライブラリに含まれる `制限実行機能 `_ 、あるいは属性参照に制限を加えたもの(例えばCapPythonや、ZopeのRestrictedPython)のことである。Pythonが褒められる場合、標準ライブラリが褒められることが多い。Pythonの開発スキルが上達することで、組み込みのリストと辞書だけを使って、効率の良いアルゴリズムを実装するのがどれぐらい良くなるか、ということは計測されていない。多くの場合、実装がどれぐらい効率的に行えるかどうかというのは標準ライブラリをどのぐらいマスターしているのか、ということに依存している。Pythonの標準ライブラリは多くの他の言語よりも大きい。唯一Javaは「いつでもそこにある」ということをやろうと思っているらしく、Pythonよりも多くのライブラリを持っている(ただし特定の組み込み環境を除く)。 "堅牢な"バージョンのPythonの成功のためには、ほとんど標準ライブラリのAPIのサポートが必要になると思われる。私はここでは、実装とAPIを区別している。理由としては、多くの標準ライブラリモジュールは、堅牢なサブセットによって使用できないようになっている言語機能を使用している可能性があるからである。これ は、堅牢なサブセットでのみ使用される別の実装が提供されるのであれば、大きな問題とはならない。 残念ながら、これらの要因が組み合わさると、堅牢なPythonサブセットにマッチした、十分な大きさの標準ライブラリを提供するということはとても実用的ではないと思う。ひとつの問題はPython自身にある。Pythonは高級な動的な言語であり、Cpythonにおけるバイトコードへのアクセスなど、実装固有の部分を含む、あらゆるレベルでのインスペクションをサポートしている(バイトコードアクセスはJythonやIronPythonや他の実装ではこれに相当する機能はない)。もちろん、言語の動的な機能やインスペクションの機能があるからといって、ほとんどの場合はモジュールAPIと、実装の間に直接の影響があるとは限らない。これは時々Pythonユーザのフラストレーションの原因となるが(例えば、最近のpython-devにおける `asyncoreについての議論 `_ )、ほとんどのケースでうまくいっており、いくつかの動的な機能を利用することでAPIをシンプルにできることも多い。例えば、動的なアトリビュート検索を利用して、APIを拡張する方法がいくつかある自動デリゲーションは、まさにその動的な機能の一般的な使用例の一つと言える。また、コマンドのディスパッチも有名である。堅牢なバージョンのPythonが十分な数のユーザをひきつけるほど完璧になるのは難しい。もちろん、この考えが間違っていると証明されて欲しいと思っているが、人々は追加的なセキュリティにより、手っ取り早く成功する方法を提供して欲しいという考えに惹かれているように思える。しかし、残念ながら、私には、この追加的なアプローチはショートカットになるとは思えないのである。 ここで、私がいくつかの経験をしている `Google App Engine `_ (現在私の時間のほとんどはこれの貢献に使用している)についても触れる必要があるだろう。Google App Engineでは標準ライブラリのサブセットをサポートした、"堅牢"に改良されたPythonを提供している。今、"堅牢"と、引用符でくくって書いたのには理由がある。App Engineのセキュリティのニーズはcapabilityのコミュニティいつも目的としているようなニーズとは多少異なる。Pythonアプリケーション全体が、ひとつの堅牢なドメインの中にあり、セキュリティはC/Pythonの境界やユーザ/カーネルの境界、仮想マシンの境界で強固に守ることで堅牢な環境が手に入れられる。信頼されていないプロセスとの堅牢な通信は提供されていない。スーパーバイザーのコードはC++で実装され、重要な部分は異なるプロセスとして活動している。 App Engineの場合、Pythonの言語としての方言はCPythonとして実装されたものと完全に同じである。唯一の違いはライブラリのレベルにある。App Engineのユーザはファイルシステムにデータを書き出すことは出来ない。また、ソケットやパイプ、スレッドやプロセスも作成することはできない。また、裏口となるようないくつかのビルトインモジュールも使用できなくなっている。モジュールに関しては、いくつかのケースでモジュールの堅牢性を崩すようなAPIのみが使用できなくなり、それ以外の安全だと思われる便利なAPIは残された。これらはすべてApp Engineの目標を達成するためには、極めて合理的な制約と言える。そして、ほとんどの場合で、この中のひとつの制約だけが、App Engineの `ユーザに苦痛 `_ をもたらしている。 App Engineのセキュリティの向上には、内部リソースをかなり使用しているが、まだ結果は大きく制限されている。App Engineのセキュリティモデルが、capability信者が好むものよりも、かなりシンプルであることを考えて欲しい。これは乱暴な開発者からの攻撃からGoogleを守るためのオール・オア・ナッシングのモデルである。一方で、開発者がお互いを攻撃しあうのを防ぐ効果もある。推測するに、capabilityをベースとしたPythonの場合は、セキュリティを守るためにもっと多くの努力が必要になったと思うし、開発者にはもっともっと多くの制限が課せられていたと思う。Google App Engineは開発者が使いたいと思うような、とても「魅力的な機能」を持たなければならないと思っている。