web-dev-qa-db-ja.com

WordPress関数を使用して$ _GETまたは$ _REQUESTからデータを正しく検証する方法

私はコンテンツ出力のオンザフライ操作を必要とするプラグインに取り組んでいます。これは現在の$_GET変数または$_REQUEST変数にのみ依存します。

変数の設定内容に応じて、特定のクラスメソッドを呼び出してユーザーの要求を処理し、適切な内容を表示します。

私はWordPressコーデックスの データ検証 ページを十分に認識していますが、私のシナリオ、または$_GET変数または$_REQUEST変数をサニタイズするシナリオのための最善のアプローチが何であるかわからないです。

特定のクラスメソッドを呼び出すために照合される文字列の$_GET変数または$_REQUEST変数にWordPress関数を使用してサニタイズする方法を教えてください。

次のコードが与えられた場合、これは悪用される可能性があるか、失敗する可能性がありますか?

public function display_admin_page(){
    if(is_admin() && isset($_GET['page'])){
        global $content;
        $page = sanitize_title($_GET['page']);
        $method_name = 'page_'.str_replace('-', '_', $page);
        if(method_exists('content', $method_name)){
            // Display requested page from content class
            $thePage = $content->$method_name();
        } else{
            $thePage = $content->error(404);    
        }
        echo $thePage;
    }
}
4
Michael Ecklund

WordPressはSUPERGLOBALSに特定のデータ検証機能を提供していません。

私はPHP filter_input 関数を使い、信頼できない変数と同じようにそれをエスケープします。

$url = filter_input( INPUT_GET, 'some_query_string', FILTER_VALIDATE_URL );

echo '<a href="'. esc_url( $url ). '">Click Me</a>';

PHP filter入力は以下のものを受け入れます。

3
Chris_O

あなたの具体的な例に:

$ _GETデータを適切にサニタイズしました(私はsanitize_keyの代わりにsanitize_titleを使用すると思いました - 違いはあまりないとは言えませんが、sanitize_titleはURLでの使用を意図しています)。

method_exists関数はプライベートメソッドと保護されたメソッドに対してtrueを返すので、ユーザーがプライベートメソッドまたは保護されたメソッドを呼び出そうとすると、404に移動しないで失敗します(display_admin_pageメソッドが同じクラスにない限り)。

これにより、潜在的な悪用が可能になります。つまり、絶対に誰でもあなたのクラスのパブリックメソッドを実行させることができます。可能であれば、受け入れることができるものを具体的にホワイトリストに登録することをお勧めします。そうすれば、次のように検証できます。

if ( !in_array( $_GET['page'], array( 'accepted_method', 'another_accepted_method' ) ) )
     $content->error(404);
2
SeventhSteel

$_GETをサニタイズすることは、ほとんどコンテキスト特有です。どのような価値があり、どのように検証するかによって異なります。

この質問に対するすべての答えが一致するものはありません。それは非常に文脈特有です。たとえば、入力からすべてのタグとスラッシュを削除する関数を作成することは非常に安全ですが、pタグを保存したい場合はどうすればよいですか。害はありません。 wp_kses()ファミリーは興味深い研究ですが、コンテキスト、ユーザーレベルなどを考慮しているため、優れた解決策ではありません。たとえば、管理ユーザーとしては、投稿タイトルと投稿コンテンツにJavaScriptを保存できますが、それより低いロールとしてはできません。

その値が既知の数量である場合は、in_array( $array_valid_strings )かどうかを確認して、それらについてさらに確認することもできます。

そうは言っても、消毒の程度はさまざまなので、最終目標を念頭に置いておくことが重要です。私はこのリストを調べて、あなたのニーズに合った機能または機能の組み合わせを見つけてください。 esc_ではなく、ここで使用する必要があるのは特にsanitize_関数です。消毒とエスケープは混乱し続けています...

私の場合は、 sanitize_text_field() を使用します。これは、ユーザー入力またはデータベースからの文字列をサニタイズするためです。

  • 無効なUTF-8をチェックします。
  • 単一の<文字をエンティティに変換します
  • すべてのタグを削除
  • 改行、タブ、余分な空白を削除します
  • ストリップオクテット

がんばろう :)。

P.Sこの回答は、3つの異なる開発者の視点(Josh、Michal、Kevin)を引用しています。

0
Ahmad Awais

GETリクエストにはmysql_real_escape_string($_GET)を使うことをお勧めします。これは非常に強力なPHP機能です。

str_replace()を使って不要な文字を置き換えることができます。

0
Ciprian