Create  Edit  Diff  FrontPage  Index  Search  Changes  RSS  Login

セキュアモード回避技

@secure = trueでもファイルアクセスするには

セキュアモードとは

tdiary.confで「@secure = true」にしてある状態の通称です。この状態で運用されているtDiaryでは、プラグインの中でできることが大きく制限されます。例えばサーバにあるファイルを読み書きしたり、ネットワーク接続をしたりといったことができません。 このため、見ず知らずの人に日記スペースを貸し出すような場合にも安心して運用できるのです(tDiary.Netが好例)。tDiaryのプラグイン記述は任意のRubyスクリプトが書けてしまうので、これがないとたいへん怖いことになってしまいます。

しかしこの制限があるせいでいろいろ苦労することがあります。

セキュアモードが発動するのはいつか

プラグインが動作するまでには、tDiary内部で以下の2つのステップを踏みます。

  1. プラグインファイルの読み込みと解釈: プラグインファイル内で定義された各種プラグインをPluginオブジェクトに追加していきます。tDiaryのセキュリティモデルでは、プラグインファイル内に書かれたコードは信用できることにしているので、この時点ではセキュアモードは発動していません
  2. プラグインの実行: 読み込んだプラグインを、日記に適用します。文中やヘッダ・フッタにあるの<%=〜%>の部分を解釈するわけです。セキュアモードが発動するのはこの段階です

ということは、最初の段階でうまいことすれば、セキュアモードを回避しつつ、安全なプラグインを記述することが可能ということになります。

なお、update_procなどのコールバック系プラグインには、日記ユーザによるコードが混入しえないので、セキュアモードが発動しません。これらの中では基本的になんでもできます。ただし日記本文などを再びプラグインに通すために使うappley_pluginメソッドを呼び出す場合は、その中のみセキュアモードが適用されます。

@modeを活用する

例えば日記の最新表示時にファイルから何かを読み出して表示するプラグインを書くとします。サイドバーに何かを埋め込む時によくある話です。普通にプラグインを定義してしまうと、その中ではセキュアモードが適用されてしまいます。

そこで、プラグインファイルの読み込み時に実行されるように、プラグインファイルの「地の部分」にそのまま処理を書きます。

open( 'hoge' ) do |f|
   @hoge_buff = f.read
end

これで、プラグインファイルが読み込まれるたびにファイルの内容が@hoge_buffに読み込まれます。あとはこの@hoge_buffを通常のプラグインの中で使えばいいわけです。

が、このままでは更新時だろうとなんだろうと、常時読み出し処理が走ってしまいます。使いもしない処理が走るのは良くないですね。「最新表示時」のみにするにはどうしたらいいのでしょうか。

これを避けるために使えるのが、インスタンス変数@modeです。@modeに関してはマニュアルでも詳しい解説がなされていませんが、その正体は現在処理中のTDiaryHogefuga系クラス名の後半部分文字列です。例えば日記の最新表示時に使われるクラスはTDiaryLatestなので、@modeは'latest'という文字列になります。

これを使えば、先のプラグインはこう書けることがわかります。

if @mode == 'latest' then
   open( 'hoge' ) do |f|
      @hoge_buff = f.read
   end
end

ただし、この技を使うときは、なぜセキュアモードで動かしたいのか、もし危険なことをされてもシステムに影響がないかどうかをきちんと考えてからにしましょう。例えばユーザが入力した情報をそのままファイルに保存するような場合、既存の大切なファイルを置き換えてしまったりすることがないように注意する必要があります。

付録: @modeの種類

よく使われるのはこのあたりでしょうか。

  • 表示時の@mode
    • latest: 最新表示
    • day: 日別表示
    • month: 月別表示
    • category.month/year/latest: それぞれ月別/年別/最新カテゴリー表示
  • 更新時の@mode
    • append: 追加時
    • replace: 編集(置換)時
    • comment: ツッコミがあった時
    • trackbackreceive: トラックバックを受けとった時
  • その他
    • preview: プレビュー表示
    • showcomment: コメント表示状態変更
    • form: 追加のフォーム表示
    • edit: 編集のフォーム表示
    • formplugin: form_proc内のフォームに入力があった時
Last modified:2006/05/09 23:27:44
Keyword(s):
References:[プラグイン開発Tips]