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


17

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

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

出力のサニタイズについては、変数をHTMLテンプレートにエコーするときなどにesc_html()、常に関数を使用する必要があることを知っていますesc_attr()。しかし、テンプレートタグを使用する場合はどうでしょうか。それらはすべて既に出力をサニタイズしますか?その場合、どのコンテキスト(一般的なHTML、タグ属性など)ですか?一部の関数には、さまざまなコンテキストのバリアントがあります(などthe_title_attribute()ですが、ほとんどはありません

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

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

APIの検証/サニタイズ

  • 投稿メタを保存 update_postmeta()
  • ユーザーメタを保存 update_user_meta()
  • 投稿タイトルの出力-コンテキストに応じた適切なバリアントを使用します the_title()

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

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

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


この質問が好きです。私はあなたと同じ考えを持っています。手動で検証/サニタイズする必要がある場合のようなリストがあれば、それは素晴らしいと思います。+1。
アントラン

1
@Rilwis、私の答えをご覧ください。常に検証する必要があります。「安全」はコンテキストに依存するため、サニタイズはより複雑です。一般的に、(ワードプレス知られているデータでWordPressのAPIを使用している場合the_title()the_permalink()など)(例えば、あなたは大丈夫ですが、カスタムデータであなたはそうではありませんget_post_meta())。疑わしい場合は、自分自身を消毒してください -傷つけることはできません。
スティーブンハリス

@StephenHarris:コメントを読みました。私もそれを知っています。しかし、私はイアン・ダンと同じ意見を持っています。彼が尋ねる主な理由は、「十分なこと、それ以上、それ以下」です。
アントラン

1
私は実際、注意を怠って検証/衛生管理をしすぎることを気にしませんが、物事を2回エスケープすることが問題になる場合があると思います。
イアン・ダン

回答:


15

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

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

検証は、ほとんど例外なく、あなた次第です。ユーザーにどのデータを要求しているかを知っていて、期待しているデータを知っている-WordPressはそうではない。検証は、たとえば、でsave_postデータベースに保存する前にフックで実行されるか、update_post_metaWordPressがデータを保存する直前に呼び出される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の場合-注意を怠って、自分でエスケープします -できるだけ遅くこれを行います。

最後に-データの保存はどうですか?あなたはそれを安全にする必要がありますか?あなたが言及したデータが有効であることを確認する必要があります。しかし、WordPressのAPI(使用している場合wp_insert_post()update_post_meta()など)を、あなたがデータをサニタイズする必要はありません-データを保存するときにのみ、あなたがやってする必要があるため消毒すると、SQL文を脱出することである-とWordPressはこれを行います。直接SQLステートメントを実行している場合(カスタムテーブルからデータを読み書きする場合)、$wpdbクラスを使用してクエリをサニタイズする必要があります。

データのサニタイズと検証に関するこのブログ記事を作成しましたが、これは役立つと思います。この点で、あなたに期待されることについてお話します。


ステファン、説明してくれてありがとう。それは少しよく理解するのに役立ちましたが、私が本当に探しているのは、私が与えた例のような包括的なリストです。あなたのアプローチは、WPがそれを処理するかどうかを知識に基づいて推測すること、または注意を払って常にサニタイズすることのようです。私の理解に頼るのではなく、権威のある包括的なリストがあれば、私はそれについてより自信を持っていると思います。また、二重エスケープが問題を引き起こす可能性があることも心配しています。
イアン・ダン

また、質問を更新して、いくつかのことを明確にしました。
イアン・ダン

0

徹底的かどうかはわかりませんが、プラグインやテーマを使用する場合は、ユーザー入力をサニタイズする必要があります。データベース操作は、$ wpdb->メソッドを使用して実行する必要があります。すべての$ _GETおよび$ _POSTデータをサニタイズする必要があります。

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

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

曖昧すぎる場合は、より具体的な質問をしてください。


3
私はそれを常に消毒する必要があることを理解していますが、問題は各特定の状況で誰が消毒を行うかについてです。WordPressが自動的に行う場合もあれば、手動で行う必要がある場合もあります。より明確にするために、質問を更新しました。
イアン・ダン

update_user_meta()を使用する場合でも、更新された値は公開されたフォームまたはユーザーの入力から取得される可能性があるため、それを検証する必要があります。if / elseループからの内部決定などのスクリプトからの値である場合は、サニタイズしないでください。
シプリアン

1
あなたがに渡す値はupdate_user_meta()通過しますstripslashes_deep()sanitize_meta()update_metadata()、その後$wpdb->prepare()の中で$wpdb->update()。だから、あなたはそれを消毒する必要はないと思う。何か不足していますか?
イアン・ダン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.