web-dev-qa-db-ja.com

URLパラメータキーの非表示と難読化は、改ざんに対する保護ですか?

mod_rewrite make PHP配列インジェクション( ウェブパラメータキーの改ざん ))は、キーが不明(および推測が難しい)の場合、使用できませんか?

次のURLがあるとします。

https://example.com/product.php?id=1&action=show

example.comは、URLを次のようなよりきれいなバージョンに書き直すことにしました。

https://example.com/product/1

そのため、次のRewriteRuleを使用します。

RewriteRule ^/product/(.*)$ /product.php?id=$1&action=show [L]

現在、キーはidおよびactionであり、これらの値は1およびshowです。 値が書き換えられることを理解しています。保護は何ら関係ありません。注入はまだ可能です。しかし、キーが不明であることを前提として、キーを変更することはできません。この例では、推測可能なキーidactionを使用しましたが、完全に長い2つのランダムなキーにすることもできます。

さて、私の質問は鍵についてです。パラメータに1つまたは複数の[]を挿入して、その値を文字列ではなくid an PHP配列にすることができます。次のようにします。

https://example.com/product.php?id[]=1&action=show

書き換えられたURLについては、キーを知らない限り、その方法はありません。私は正しいですか?この例では、キーが簡単に推測できるため、次のことが可能です。以下の例では、URLはキーidを2回持っていることを認識し、挿入された[]で最後のキーを使用します。

https://example.com/product/1?id[]=1

しかし、キーが知られておらず、簡単に推測できると仮定します。まあ言ってみれば:

RewriteRule ^/product/(.*)$ /product.php?7b8d164d7820713ef5be524d2bde7828999c78d6=$1&28c4abba80b7a2038328e54a81f51367ead9172a=show [L]

その場合、キーを知らずに[]を注入する方法はないと思います。

さらに、あなたのPHPスクリプトで文字?&の現在のURLを確認すると、https://example.com/product/1?id[]=1のようなバイパスを防ぐことができます。私の意見では、配列注入またはキーを変更することはもはや不可能で、値を変更することができます。よろしいですか?

4
Bob Ortiz

スクリプトの実際の場所を難読化しますが、それ自体では、攻撃者がproduct.phpファイルを推測/ dirbustings/etcして直接アクセスすることを妨げるものはありません。その後、攻撃者は正しいパラメータ名(IDとアクション)を特定する必要があります。攻撃者がファイルに直接アクセスすると、書き換えルールは適用されません。

したがって、スクリプトを攻撃するために必要な最小の労力を潜在的に上げることができますが、ルールを書き換える必要があり、それらはパフォーマンスにあまり適していないため、プロセスでサービス拒否の状態を引き起こす可能性があります。

1
wireghoul

これにアプローチする良い方法は、リクエストが呼び出された直後に専用のPHPメソッドでユーザー入力をサニタイズすることです。

これにはいくつかの利点があります。

  • 正しい形式の引数のみが送信されることを常に確信しています。 intsはintsで、stringsは通常とは異なる文字列です
  • 正しい数の引数が渡されるため、たとえば、別の引数を追加してスクリプトに他のことをさせる方法はありません。

上記の2つを一致させることができれば、引数の不完全なリストを渡したり、変数を適切に初期化しないなど、いくつかの既存のバグを削除できる可能性があります。

PHPコード、そして実際に必須の入力検証です。

入力の検証は通常、標準のメソッドによって行われますが、リクエストをルーティングする前に、1つの場所でサニタイズすることをお勧めします。これは、他の複数のメソッドが呼び出される前に入力をサニタイズすることが重要であるため、適切で有効なメソッドです。

したがって、最善の方法は、常に1つのコントローラーメソッドを呼び出して、すべての引数が一致(既存)であり、必要なタイプであるかどうかを確認することです(主にチェックを行い、その後他のサービスを呼び出すコントローラーメソッドで)。 (コントローラーのロジックを表示するためのセミコードです):

//router
if($_GET['action'] === 'showItem') {
    showItemController();
}

//controller
function showItemController() {
    try {
        $id = $_GET['id'];
        if(!isint($id)) {
           throw new Exception("id '{$id} is wrong");
        }
        $output = showItem($id);
        render($output);
    } catch(Exception $e) {
      logError($e);
      displayGenericFail();
    }
}

//service
function service($id) {
    $item = new Item($id);
    return $item->getHtml();
}
0
Aria