web-dev-qa-db-ja.com

どのコンテキストでプラグインがデータ検証/サニタイズを担当していますか?

データベースに入る前、そしてブラウザに出力される前に、私のプラグイン/テーマのすべてのデータが安全に扱われるようにしたいです。私の問題は、投稿メタフィールドを保存するときのようにAPIがサニタイズを処理する状況や、カスタム設定を保存するときのようにプラグイン/テーマの作成者が完全に責任を負う状況があることです。

この質問の範囲では、ドメインレベルでデータを検証することについては心配していません。たとえば、フォームのAgeフィールドが0から120の間であること、または電子メールアドレスが有効であることの確認などです。私はセキュリティについてのみ心配しています - たとえば、データベースに保存するときにSQLインジェクションを回避するためにSQLクエリをエスケープすること、またはXSSを回避するためにHTMLテンプレートに出力されるデータをサニタイズすることです。

出力をサニタイズするためには、変数をHTMLテンプレートにエコーするときは常にesc_html()esc_attr()のような関数を使う必要があることを私は知っています。しかし、 テンプレートタグ を使用するとどうなりますか?彼ら全員はすでにアウトプットをサニタイズしていますか?もしそうなら、どのコンテキスト(一般的なHTML、タグ属性など)について?いくつかの関数は異なるコンテキストのための変種を持っています(the_title_attribute()のような、しかしほとんどは持っていません)。

入力をサニタイズするには、手動でクエリを行うときに$wpdb->prepare()を使用する必要があることを知っていますが、Settings APIを使用してプラグイン設定ページを作成するとき、またはカスタム投稿タイプの投稿メタフィールドを保存するときはどうですか。

今のところ、関数を使ってサニタイズするかどうかを調べるたびにCoreを掘り下げてチュートリアルを読んでいるところですが、エラーが発生しやすく時間がかかります。私は、考えられるすべての状況と、APIがそれを処理するかどうかについて、何らかの種類の包括的なリストを見つけることを望んでいます。例えば。、

APIによる検証/サニタイズ

  • update_postmeta()による投稿メタの保存
  • update_user_meta()を使ったユーザーメタの保存
  • 役職の出力 - 文脈上適切なthe_title()の変種を使用します

手動で検証/サニタイズする必要があります

  • Settings APIを使ってプラグインオプションを保存する。コールバックをregister_setting()の3番目のパラメータとして渡します。
  • 直接データベースクエリ:クエリを$wpdb->prepare()で囲みます。
  • HTMLで変数を出力するesc_attr()esc_html()などを使う

私はまた、APIが特定の状況でなぜそれを提供するのか、他の状況では提供しないのかを理解したいと思います。私はそれがデータの未知の性質と関係があると思いますが、徹底的な説明を聞きたいです。

16
Ian Dunn

ここには2つの概念があります。

  • 検証-データがvalidであることを確認します。つまり、整数は整数で、日付は日付(正しい形式など)です。これは、データを保存する直前に行う必要があります。
  • sanitisation-現在のコンテキストで使用するために日付safeを作成します(SQLクエリのエスケープ、出力でのHTMLのエスケープなど)。

検証は、ほぼ普遍的に、あなた次第です。ユーザーにどのデータを要求しているかを知っていて、どのデータを期待しているのかを知っています-WordPressはそうではありません。検証は、たとえば、save_postを使用してデータベースに保存する前にupdate_post_metaフックで実行されるか、WordPressがデータを保存する直前に呼び出されるSettings APIでコールバック関数を指定することで実行できます。

消毒はもう少し複雑です。 WordPressがネイティブに知っているデータ(たとえば、投稿のタイル)を扱う場合、WordPressが既にデータを安全にしていることを確認できます。ただし、「安全」はコンテキストに依存します。ページ上で安全に使用できるものは、要素属性として必ずしも安全ではありません。したがって、WordPressには、コンテキストごとに異なる関数があります(例 the_title()the_title_rss()the_title_attribute() )-したがって、正しいものを使用する必要があります

ほとんどの場合、プラグインはポストメタを処理するか、カスタムテーブルのイベントデータを処理します。 WordPressは、このデータが何であるか、または何のためにあるのかを知らないので、安全にする方法を確実に知りません。 これはあなた次第です。これは、悪意のある入力によるコードの埋め込みを防ぐために esc_url()esc_attr()esc_textarea() などを使用する場合に特に重要です。 WordPressは、next_posts()がページにURLを印刷することを想定しているので、esc_url()を適用しますが、投稿メタでは、たとえば、URLが格納されていることを知りません-またはそれをどうするか(印刷する場合、esc_url()、リダイレクトする場合 esc_url_raw()dobutの場合-注意を怠って自分でエスケープする-できるだけ遅くこれを行います。

最後に-データの保存はどうですか?あなたはそれを安全にする必要がありますか?前述のように、doはデータが有効であることを確認する必要があります。ただし、WordPress AP​​I(wp_insert_post()update_post_meta()など)を使用している場合、データをサニタイズする必要はありません-データを保存するときは、SQLステートメントをエスケープすることがサニタイズのみであるため-およびWordPressがこれを行います。直接SQLステートメントを実行している場合(カスタムテーブルからデータを読み書きする場合)、 $wpdb クラスを使用して、クエリをサニタイズする必要があります。

私はこれを書いた データのサニタイズと検証に関するブログ記事 これはあなたが役に立つと思うかもしれない-その中で、私はこの点であなたに期待されることについて話す。

15
Stephen Harris

それが徹底的であることを確信していない、しかしどんなプラグインやテーマでも、ユーザー入力はサニタイズされるべきです。データベース操作は$ wpdb->メソッドを使って行われるべきです。すべての$ _GETおよび$ _POSTデータはサニタイズする必要があります。

これはWordPressよりもPHPプログラミングのベストプラクティスです。

したがって、結論として、WordPress関数がある場合はそれを使用し、そうでない場合は変数をサニタイズして自分で入力します。

私が曖昧すぎるなら、もっと具体的な質問をしてください。

0
Ciprian