はじめに
PHPで広く利用されているテンプレートエンジン Smarty は、表示ロジックをクリーンに分離できる便利な仕組みを提供します。しかしその反面、「テンプレートからPHP関数を呼び出せる」という強力な機能が、設定次第で Server-Side Template Injection(SSTI) の入口になります。
なぜSmartyでSSTIが起きるのか
Smartyはテンプレート内に以下のような構文を書くことができます。
{'Hello'|upper}-
{system("ls")}※本来は危険な例
これらはテンプレートエンジンによって解釈され、PHPコードとして実行されることがあります。
攻撃者が入力欄にテンプレート構文を埋め込める状況だと、「ユーザー入力がコードとして扱われる」という最悪のパターンに近づきます。
動作確認の典型例
{'Hello'|upper} と入力して HELLO が返ってくれば、アプリケーションが実際にSmartyを使用し、テンプレート構文を処理していることがわかります。
ここまで確認できる環境で保護設定が甘い場合、攻撃者はテンプレート内からシステム関数を呼び出す余地を持つことになり、SSTI経由で不正な動作をさせられる可能性があります。
典型的なリスク
- 任意のPHP関数呼び出し
- サーバー上のファイル列挙
- コマンド実行(設定が脆弱な場合)
- テンプレートの改ざん・ファイル生成
- アプリケーション内部情報の漏洩
特に Smarty の {php} タグや system() のような関数呼び出しが許可されていると、一気に攻撃難易度が下がります。
安全に使うための対策
1. セキュリティモードを有効化する
Smartyには「Security Policy」が用意されています。
これを有効にし、使用可能な関数・タグをホワイトリスト化することが重要です。
2. ユーザー入力をテンプレートとして解釈させない
もっとも基本的で、もっとも大切なポイント。
ユーザーが入力した文字列を 生のまま **fetch()** や **display()** に渡さない ようにする。
3. {php} タグや危険な関数を禁止
Smarty 3 系では {php} タグはデフォルトで無効ですが、再度有効化しないこと。
4. テンプレートファイルを読み取り専用にする
攻撃者がテンプレートファイルを書き換えられる環境は、もはや本末転倒。
書き込み権限の管理がとても重要。
5. ログとテンプレートキャッシュの監視
テンプレートのコンパイル結果に怪しい内容が混入していないか定期的に確認する。
まとめ
Smartyは便利なテンプレートエンジンですが、その柔軟さゆえに不正なコード実行の危険性も抱えています。
SSTIは“テンプレートに見せかけたコードがサーバー側で実行されてしまう”攻撃なので、入力の扱い・テンプレートの権限管理・Smartyのセキュリティ設定が極めて重要です。
チューニング次第で安全にも危険にも振れるため、使うならしっかり構成と監視を行うことが大切です。