[PHP-users 12746] Re: null byte attack

Yasuo Ohgaki php-users@php.gr.jp
Wed, 22 Jan 2003 18:02:00 +0900


Osamu Shigematsu wrote:
> 私が筋違いな考えなのかもしれないですが、
> そもそも NUL (\0) を文字列にきちんと含めて、
> すべての関数で、それをハンドリングできるようにするのが、
> 本筋だと思うのですが。

私も基本的にはそう思いますが、今すぐ対処したい、と言うニーズも
あるので両方の手法、pregからeregへの変更とphp_stream_open_wrapper
へのパッチ、の両方を書いたつもりです

# 私はpregはバイナリセーフなので勘(あまり良く考えずに
# 危険かもと思った)で、ユーザーからも入力できるファイ
# ル名チェックにはeregを使っていました ;)

もちろん他の関数でも危ない物があると思います。
中にはphp streamと全く関係ない物、basename等、はファイル
(ストリーム)を全く開かない物にはphp streamでは対応できま
せん。

> 
> 少なくとも、PHP の文字列変数には NUL を含むことができますから、
> 一部の C のライブラリを wrap しただけの関数が動かないのでしょう。
> 
> これらは、マニュアルに NUL を文字列の終わりとみなすため、
> 予期せぬ動作をすることがある、と明記する必要があると思います。

好運な事に、PHP4.3.0からはベースとほとんどのメジャーなモ
ジュールではphp streamsを使っています。パッチが必要な箇
所は比較てき少なくなります。

# Cプログラマの方は、php_stream_open_wrapperのキーワード
# があれば、すぐに対処できると思います。

ただ、他にも検討が必要な箇所が多く残っている事には変わり
ありません。

> 大垣さんのおっしゃること、場当たり的対処としては、
> きわめてもっともですが、
> 私は、ereg を使って逃げるのには賛成しかねます。
> 
> 問題の本質を理解しようとしないユーザに、小手先の回避策を示しても、
> 同様の問題ですべて尻拭いをしてあげないと、
> 自ら穴をふさぐことを覚えない気がするのですが。
> 
> 今回問題視すべきは、性能の良い pcre ではなくて、
> readfile 関数に他ならないと思いますが、いかがでしょうか。

これも多分、php_stream_open_wrapperを呼んでいると
思います。

> 場当たり的対処をするならば、strlen() と php が知っている
> 文字列の長さが異なるときは、不正なファイル名 (or URL) ということで、
> はじくとか、NSString (Mac OS X) のように、ファイルシステムに
> 基づいた path 操作ができるような関数郡を用意してあげる、
> などの対策が思いつきます。

BugTraqにfopenのパッチが載っていましたが、それも文字列の長さ
とzvalの文字列の長さを比較する物でした。まだ、あまり良く考えて
いませんがphp_stream_open_wrapperでチェックするのが良いと
思いますが問題もあります。ワイド文字をどうするか等です。根本的な
対策をPHP内部で行なうにはもっと良く考える必要があります。

# 多分、他のだれかがパッチをすぐに作るだろうと
# 他力本願モードになっていたりします  :)

ここにで話題になっている脆弱性はURLから攻撃可能かある程度判別で
きるので心あたりのある方は、場あたり的な対処策でも早めに対応する
ことをお勧めします。

--
Yasuo Ohgaki