Contaoと入力の検証に関する不十分な検証
(コメント: 0)
HASHコンサルティング株式会社の徳丸さんのブログでCMS四天王のバリデーション状況を調査したところ意外な結果になったという記事が出ています。Concrete5でもCMS四天王から外れたconcrete5 のユーザーID長さと使える文字という記事が出ていましたので、少し刺激を受けてContaoの場合も見てみましょう。
Contaoでのユーザー
まず、CMS四天王やConcrete5と異なり、Contaoではユーザーはコンテンツの管理を行うバックエンドのユーザーと、公開しているウェブサイト(フロントエンド)上のユーザーであるメンバーで扱いが異なります。
- ユーザーは権限のあるバックエンドのユーザーによってだけ新規の登録ができます。
- メンバーは権限のあるバックエンドのユーザーが登録するか、フロントエンドに設置した「登録」のフロントエンドモジュールを介して登録ができます。
ユーザーのDCAでの定義
いずれにしても、バックエンドのデータ格納配列(DCA)に基づいて入力は検証されます。ユーザ名のような入力項目は、フォームの入力形式やデータベースの定義はDCAに記述されています。ユーザーの場合の定義部分をsystem/modules/core/dca/tl_user.php
から抜き出します:
'username' => array
{
'label' => &$GLOBALS['TL_LANG']['tl_user']['username'],
'exclude' => true,
'search' => true,
'sorting' => true,
'flag' => 1,
'inputType' => 'text',
'eval' => array('mandatory'=>true, 'rgxp'=>'extnd', 'nospace'=>true, 'unique'=>true, 'maxlength'=>64),
'sql' => "varchar(64) COLLATE utf8_bin NULL"
),
ここで入力フォームに関係する部分はinputtype
とeval
の部分です。
inputtype
:text
でテキスト入力eval
:mandatory
:true
を指定して必須の項目rgxp
: 正規表現のextnd
で入力値を検証nospace
:true
を指定して空白文字の入力を禁止unique
:true
を指定して値の重複を禁止maxlength
: 入力できる最大長を64に制限
extnd
による検証は、次の文字を禁止しています。
#&()/<=>;
Contaoでのユーザー名の状況
以上を踏まえて徳丸さんの記事の項目を考えてみましょう。
シングルクォート
シングルクォートは上記のextnd
で禁止している文字ではありません。従って、シングルクォートを含んだユーザーを作成でき、バックエンドからログインもできました。
タグ
タグは上記のextnd
で禁止している文字です。このため、タグの文字を含んだユーザーを登録しようとした時点で入力エラーとなり、登録できません。
バックスラッシュ
バックスラッシュは上記のextnd
で禁止している文字ではありません。従って、シングルクォートを含んだユーザーを作成でき、バックエンドの(管理者ユーザーからの)ユーザー切り替えで、登録したユーザになれました。
しかし、バックエンドのログイン画面からログインはできませんでした。完全にコードを追いかけきれてはいませんが、ユーザー名をデータベースから探せていないようです。
最長な文字列
登録時はきっちりとフォームで制限されていますし、データベースのレコード長の64文字を越えるユーザー名は登録されようがありません。
一方、ログイン時は特に長さの最大長を気にした処理はしていないようで、徳丸さんの記事の四天王のCMSと同様なようです。
不正な文字エンコーディング
不正な文字エンコーディングの文字列を旨いこと渡す方法を、限られた時間内で用意できなかったので割愛します。
ナルバイト
これはバックスラッシュを含めたユーザーのログイン時の処理を調べる過程で、Input::xssClean()
できっちりとナル文字(0x00)を削除していることを確認できました。エンコードされたナル文字も何段階に渡って削除をしています。
改行
Input::xssClean()
で復帰(0x0d)は削除しています。改行(0x0a)については調べきれませんでした。
配列
こちらも時間切れです。
まとめにならないまとめ
さて、たいへん大雑把に見てみました。バックエンドのユーザーも、フロントエンドのメンバーも、どちらのログインのフォームで長さの検査はしていないことは思わぬ結果でした。もちろん、フォームで行ったとしても直接HTTPで送り付けられる可能性は避けられません。しっかりとリクエストトークンを処理して送らないと受け付けられないのでハードルは高そうに思えますが。
Copyright © 2011-2024 Takahiro Kambe all rights reserved.
コメント
コメントを追加