本当は緩いCodeIgniterのvalid_urlバリデーションルール

この記事は CodeIgniter Advent Calendar 2022 - Qiita の2日目です。まだ、空きがありますので、興味のある方は気軽に参加してください。

動作確認環境

  • CodeIgniter 4.3 ブランチ (f414d79c5d1212cf8a06b26b1aaf809efd998e71)
  • CodeIgniter 3.1-stable ブランチ (45576ef6e62b5ff59da67f1697ee8c57809c7719)

URLの検証ルール

CodeIgniterのバリデーションには、URLを検証する valid_url ルールがあります。

なお、このルールは値の形式的なチェックであり、実際にそのURLが存在するかどうかは確認しません。

実際のコードで確認してみましょう。

$validation = Services::validation();

$validation->setRules([
    'url' => 'valid_url',
]);

$data = [
    'url' => 'https://codeigniter.com/',
];
dd($validation->run($data));

結果:

$validation->run(...) boolean true
⧉ Called from .../app/Controllers/Home.php:20 [dd()]

上記のように、https://codeigniter.com/ に対して true が返りました。いいですね。

不正なURL

検証するデータを以下のように変更してみます。

$data = [
    'url' => 'xhttps://codeigniter.com/',
];

結果:

$validation->run(...) boolean false
⧉ Called from .../app/Controllers/Home.php:20 [dd()]

xhttps://codeigniter.com/ はURLとして正しくないため false が返りました。

プロトコルなし

では、以下はどうでしょうか?

$data = [
    'url' => 'codeigniter.com/',
];

これも true が返ります。プロトコルがなくても許容されるようです。

URLとは思えない文字列

それでは、以下はどうでしょうか?

$data = [
    'url' => 'foo.bar',
];

これも true です。形式としてドメイン名だと言えなくもありませんが。

$data = [
    'url' => 'foo',
];

?! 何とこれも true です。

valid_url は、ブラウザのアドレスバーに入力してOKなものはOKという仕様らしく、ホスト名のみの入力も可能なため、これも妥当な値だとされています。

さて、では次の値はどうでしょう?

$data = [
    'url' => 'http:8080//abc.com',
];

これも true です。もはや訳がわかりません。これは流石にバグと言わざるを得ない気がしますが。

上記は、CodeIgniter4での結果ですが、CodeIgniter3でも全く同じです。 CodeIgniter3のルールがそのまま4にポートされています。

valid_url_strict

CodeIgniter v4.1.5 より、より厳密にURLを検証できる valid_url_strict ルールが追加されています。 このルールはPHPの FILTER_VALIDATE_URL を利用します。

$validation = Services::validation();

$validation->setRules([
    'url' => 'valid_url_strict',
]);

$data = [
    'url' => 'http:8080//abc.com',
];
dd($validation->run($data));

結果:

$validation->run(...) boolean false
⧉ Called from .../app/Controllers/Home.php:20 [dd()]

きちんと false になりました。

valid_url_strict ルールはデフォルトでは、プロトコルとして httphttps が許可されています。 パラメータとして許可するプロトコルを指定できます。プロトコルを指定する場合は許可するものをすべて記載します。

$validation->setRules([
    'url' => 'valid_url_strict[mailto,http,https]',
]);

上記は、mailtohttphttps だけを許可します。

まとめ

  • CodeIgniterの valid_url ルールは、URLっぽいものはOKという緩いルールです。
  • URLの形式妥当性を厳密にチェックしたい場合は、CodeIgniter4では valid_url_strict を使います。

この記事は CodeIgniter Advent Calendar 2022 - Qiita の2日目です。まだ、空きがありますので、興味のある方は気軽に参加してください。

参考

Date: 2022/12/02

Tags: codeigniter, codeigniter4, security, validation