フィルターとサニタイズ

ユーザー入力のサニタイズは、ソフトウェア開発の重要な部分です。 ユーザー入力を信頼したり無視してしまうと、アプリケーションのコンテンツ、主にユーザーデータ、またはアプリケーションがホストされているサーバーにも不正にアクセスさせてしまう可能性があります。

XKCD の完全なイメージ

Phalcon\Filter コンポーネントは、一般的に使用されるフィルターとデータサニタイズ用のヘルパーを提供します。 PHP フィルター拡張機能のオブジェクト指向ラッパーを提供します。

ビルトインフィルターの種類

このコンポーネントによって提供される、ビルドインフィルターを次に示します。

名前 説明
absint 値をintegerとしてキャストし、その絶対値を返す。
alphanum [a-zA-Z0-9] 以外のすべての文字を削除します。
email 文字・数字!#$%&*+-/=?^_{|}[email protected][]`以外のすべての文字を削除し、
float 数字、ドット、プラス記号、マイナス記号以外のすべての文字を削除します。
float! 数字、ドット、プラス記号、マイナス記号以外のすべての文字を削除し、残りを float としてキャストする。
int 数字、プラス記号、マイナス記号以外のすべての文字を削除します。
int! 数字、プラス記号、マイナス記号以外のすべての文字を削除し、残りを integer としてキャストする。
lower strtolower 関数を適用します。
string タグを除去し、シングルクォートとダブルクォートでHTML エンティティをエンコードします。
striptags strip_tags 関数を適用します。
trim trim 関数を適用します。
upper strtoupper 関数を適用します。

コンポーネントが内部的にfilter_var PHP の関数を使用することに注意してください。

定数が利用可能であり、必要なフィルタリングのタイプを定義するために使用できます:

<?php
const FILTER_ABSINT     = "absint";
const FILTER_ALPHANUM   = "alphanum";
const FILTER_EMAIL      = "email";
const FILTER_FLOAT      = "float";
const FILTER_FLOAT_CAST = "float!";
const FILTER_INT        = "int";
const FILTER_INT_CAST   = "int!";
const FILTER_LOWER      = "lower";
const FILTER_STRING     = "string";
const FILTER_STRIPTAGS  = "striptags";
const FILTER_TRIM       = "trim";
const FILTER_UPPER      = "upper";

データのサニタイズ

サニタイズは、ユーザーまたはアプリケーションに必要ではないまたは望まれていない、特定の文字を値から削除するプロセスです。 入力値のサニタイズによって、アプリケーションの整合性を確かめます。

<?php

use Phalcon\Filter;

$filter = new Filter();

// '[email protected]' を返す
$filter->sanitize('some(one)@exa\mple.com', 'email');

// 'hello' を返す
$filter->sanitize('hello<<', 'string');

// '100019' を返す
$filter->sanitize('!100a019', 'int');

// '100019.01' を返す
$filter->sanitize('!100a019.01a', 'float');

コントローラーからのサニタイズ

(リクエストオブジェクトを通じて)GET または POST の入力データにアクセスするとき、コントローラーから Phalcon\Filter オブジェクトにアクセスできます。 最初のパラメータは、取得する変数の名前です。 2番目はそれに適用されるフィルタです。

<?php

use Phalcon\Mvc\Controller;

class ProductsController extends Controller
{
    public function indexAction()
    {

    }

    public function saveAction()
    {
        // 入力されたpriceをサニタイズ
        $price = $this->request->getPost('price', 'double');

        // 入力されたemailをサニタイズ
        $email = $this->request->getPost('customerEmail', 'email');
    }
}

アクションパラメーターのフィルタリング

次の例では、コント ローラーのアクションの中でアクションパラメーターをサニタイズする方法を示します。

<?php

use Phalcon\Mvc\Controller;

class ProductsController extends Controller
{
    public function indexAction()
    {

    }

    public function showAction($productId)
    {
        $productId = $this->filter->sanitize($productId, 'int');
    }
}

データのフィルタリング

サニタイズに加えて、Phalcon\Filter は、入力データを私達が期待する形式に修正したり、削除したりすることで、フィルタリング機能を提供します。

<?php

use Phalcon\Filter;

$filter = new Filter();

// 'hello' を返す
$filter->sanitize('<h1>Hello</h1>', 'striptags');

// 'hello' を返す
$filter->sanitize('  Hello   ', 'trim');

フィルターの組合せ

2 番目のパラメーターとしてフィルターのIDの配列を渡すことによって、同時に複数のフィルターを文字列に対して実行することもできます:

<?php

use Phalcon\Filter;

$filter = new Filter();

// 'hello' を返す
$filter->sanitize(
    '   <h1> Hello </h1>   ',
    [
        'striptags',
        'trim',
    ]
);

フィルターの追加

Phalcon\Filter に、独自のフィルターを追加できます。 フィルター関数を匿名関数にできます。

<?php

use Phalcon\Filter;

$filter = new Filter();

// 無名関数を使う
$filter->add(
    'md5',
    function ($value) {
        return preg_replace('/[^0-9a-f]/', '', $value);
    }
);

// 'md5' フィルターでサニタイズ
$filtered = $filter->sanitize($possibleMd5, 'md5');

また、必要に応じて、クラス内にフィルタを実装することもできます:

<?php

use Phalcon\Filter;

class IPv4Filter
{
    public function filter($value)
    {
        return filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
    }
}

$filter = new Filter();

// オブジェクトを使う
$filter->add(
    'ipv4',
    new IPv4Filter()
);

// 'ipv4' フィルターでサニタイズ
$filteredIp = $filter->sanitize('127.0.0.1', 'ipv4');

複雑なサニタイズとフィルタリング

PHP 自体は、優れたフィルター拡張機能を提供します。 こちらのドキュメントを確認してください: PHPドキュメントのData Filtering

独自のフィルターを実装

Phalconが提供するフィルタリングサービスの代わりに独自のフィルタリングサービスを作成するには、Phalcon\FilterInterfaceインターフェイスを実装する必要があります。