[PHP-dev 1485] Re: mb_ereg_replace

Yasuo Ohgaki yohgaki @ ohgaki.net
2009年 5月 29日 (金) 15:44:32 JST


大垣です。

レスポンス悪くて済みません。
私もコレを最初に見た感想が「脆弱性??」でした。

2009/05/16 5:06 Moriyoshi Koizumi <mozo @ mozo.jp>:
> 小泉です。
>
> この件だいぶ前に知っていたのですが。
>
> そうですね、論点としては
>
> 1. 脆弱性と見なせるかどうか。
> 2. 現在の仕様のまま、これを実践的に、安全に利用することが可能かかどうか。
> 3. もし仕様を変更するとして、変更後の仕様が下位互換性を満たせるかどうか。
> 4. 下位互換性が満たせないとして、どのような代替案があるか。
>
> があると思います。
>
> 1. については、本来的には仕様であると言えるので、厳密な意味では脆弱ではないと考えます。そもそも、preg_replace() にも同様の問題があります。
>
> <?php var_dump(preg_replace("/.*/e", "\\0", "`sh`")); ?>
>
> mbregex でだけこの問題を取り上げることは正しいことなのでしょうか?

pcreではaddslashesがあったりするのでどうなのでしょうね?
この種の動作をする他の言語は何もしてないような気が...

最初に見た印象は「こんなので脆弱性と言うな」という考えでしたが、
仕様を知らない人には落とし穴にもなるのでどうすべきか私も判断しか
ねます。

>
> 2. について、ユーザが、正規表現の置換文字列を PHP
> のスクリプトを評価した結果としたいという状況下では、そのスクリプトのパラメータに置換対象文字列を指定することはごく自然です。安全に実践的に利用しようとすると、例えば特定文字列を乱数に置き換える、といった限定された問題領域にしか適用できなくなります。
>
> また、eオプション自体は Perl の正規表現演算子が発祥であると考えられますが、Perl
> ではバックリファレンスを変数で表すので、プレイスホルダによって発生するような脆弱性はありません。ユーザが類推によって、この動作の違いに気づかずに当該機能を利用してしまう可能性は低くありません。
>
> 3. について、e オプションが有効なときに、バックリファレンスを一時的に変数に格納し、バックリファレンスを表す文字列を変数を表す文字列に適宜置換してから
> eval するという実装が考えられます。しかし、これでは次のような呼び出しを行うスクリプトの動作が変わってしまいます。
>
> mb_ereg_replace(".*", "'***\\0***'", '$a', 'e');
>
> したがって、4. を考えるわけですが、3. の挙動を指定する新しいオプション文字列 (E) を導入し、旧来の方法は deprecated
> とする、などが一案として考えられます。

さすが小泉さん、この案は良いと思います。
少なくとも私は気に入りました。

いかがでしょう?

-- 
Yasuo Ohgaki
yohgaki @ ohgaki.net


>
> 2009/5/15 Yasuo Ohgaki <yohgaki @ ohgaki.net>:
>> 大垣です。
>>
>> PHP_5_2ブランチを見た限りまだ修正が入っていないようなので
>> メールします。
>>
>> http://www.milw0rm.com/exploits/8641
>>
>> この件、何方か作業されていますでしょうか?
>>
>> バックリファレンスで関数が実行できてしまう、という脆弱性なの
>> ですがSJISとかあるのでpregの様にエスケープする訳には行かない
>> です。
>>
>> --
>> Yasuo Ohgaki
>> yohgaki @ ohgaki.net
>> _______________________________________________
>> PHP-dev mailing list
>> PHP-dev @ php.gr.jp
>> http://ml.php.gr.jp/mailman/listinfo/php-dev
>>
> _______________________________________________
> PHP-dev mailing list
> PHP-dev @ php.gr.jp
> http://ml.php.gr.jp/mailman/listinfo/php-dev
>


PHP-dev メーリングリストの案内