CodeIgniter1.7.3に合わせてSeezooもFIXしました
連日の記事となりますが、ご報告まで。
今日の朝来たら、CodeIgniter1.7.3がリリースされてました。
早速DL、Change Log — CodeIgniter 3.1.10 documentationを見てみると、
Version 1.7.3 is a security maintenance release, including a previously patched file Upload class, and a new security fix to prevent possible directory traversal in certain circumstances. There are no other significant changes.
ということらしいです。どうやらRouterのセキュリティFIXがあったようですね。
$config['enable_query_strings']がTRUEの時のディレクトリトラバーサル問題の解決らしいです。
というわけで、早速Diffをとって中身を見ると、
310c310< $this->class = str_replace(array('/', '.'), '', $class);
-
- -
> $this->class = $class;
369c369< $this->directory = str_replace(array('/', '.'), '', $dir).'/';
-
- -
> $this->directory = $dir.'/';
ふむふむ、Router::set_class()とRouter::set_directory()のコードが変わってるみたいですね。
これくらいならパパッと修正して〜…と思ってよく考えたらマズイことに気が付きました。
これだとディレクトリにパス(/)が含められない
早速Seezooに導入してみると、予想通り、3階層まで掘るルーティングができなくなってしまってます;;
Seezooはディレクトリを掘り進めて、その都度のディレクトリパスを「/」でつないでるので、2回目にset_directory()が
呼ばれると、それまであった「/」がstr_replace()によって消されてしまう、という状態でした。
解決策の模索
あ〜でもないこ〜でもないとうんうんうなりながら昼食していたら閃きました。
つまるところ、Directory Traversalの危険性のある文字を削除してる訳だよね
つまり、「/」と「.」が含まれるのがマズイ。でも階層を掘るなら「/」は付けないといけない。
ということなら、
格納する時点では付けず、最後にまとめてつければいいよね?
というわけで、ルーティング中はディレクトリデータ階層をstr_replace()した上で配列に格納、
最後にfetch_directroy()を呼び出す時にimplode()というやや強引な方法で解決しました。
具体的には、SZ_Router::fetch_directroy()をOverRideして処理変更。
コード
以下のように変更しました。
system/application/libraries/SZ_Router.php
var $directory = array() // override
var $directory_reg = array() // 拡張ルーティング用パス.
.
.
// override CI_Router::set_directory
function set_directroy($dir)
{
// パスが含まれた最後のディレクトリ名を取得
$exp = explode('/', $dir);
$dir = str_replace(array('/', '.'), '', end($exp));$this->directory[] = $dir;
}.
.
.
// override CI_Router::fetch_directory
function fetch_directory()
{
$prefix = '';
if ($this->is_packaged_directory === TRUE) // 拡張ルーティング用
{
$prefix = '../../../' . SZ_EXT_DIR . 'controllers/';
}
return (count($this->directory) === 0)
? $prefix
: $prefix . (implode('/', $this->directory) . '/');
}
これで3階層+拡張パッケージからのルーティングを確認しました。
やや強引な方法だけど、Directory Traversalは怖いですからね><
感想
ルーティング部分の変更って意外とキツイ。
Seezooではquery_stringは使わないので影響はないだろうけど、コアのメソッドが変わってるのには影響を受けてしまいます。
でも拡張してOverrideで解決できるのもCodeIgniterの素晴らしいところですね。
1.7.3パッケージ導入後のSeezooは次のバージョンからです。
もし現行のSeezooをCI1.7.3にする場合は、上記のような修正をお願いします。
でもこれってコアでは「コントローラは2階層まで!」って事実上決められてしまったような気がします…