web-dev-qa-db-ja.com

`get_template_directory_uri()`をエスケープするべきですか?

get_template_directory_uri()esc_url()を使ってエスケープすべきですか?

デフォルトのテーマ「二十五十五」から同じ関数が2つの異なる場所で使用されているが、エスケープされているのは1つだけであるため、例を挙げて説明します。

wp_enqueue_style( 'twentyfifteen-ie', get_template_directory_uri() . '/css/ie.css', array( 'twentyfifteen-style' ), '20141010' );

-

<script src="<?php echo esc_url( get_template_directory_uri() ); ?>/js/html5.js"></script>

URLを外部から操作することはできないため、get_template_directory_uri()を生成する必要はないと思います。

6
grappler

その関数にはフックがあります。

return apply_filters( 
    'template_directory_uri', 
    $template_dir_uri, 
    $template, 
    $theme_root_uri
);

つまり、URIはプラグインによって変更される可能性があるため、その戻り値をエスケープする必要があります。

同じ原則が、get_home_url()get_site_url()などのすべてのWordPress URI関数に適用されます。良いプラグイン開発者だけがそこにいるわけではないことを覚えておいてください。いくつかの間違いを犯すこともありますが、状況によっては非常に小さな間違いもあります。

wp_enqueue_style()の場合、WordPress doesはデフォルトでURLをエスケープします。しかしそれはglobalWP_Stylesインスタンスのラッパーです、そしてこれは順番に 簡単に置き換えることができます - もっと安全でなくともそうではありませんが、この可能性を知っておく必要があります。

残念ながら、WP自体は申し訳ありませんが安全の指示には従っていません。翻訳から逃れることすらありません。私のアドバイスは、ベストプラクティスの中心的なテーマを検討することではありません。常にデータの出所を調べ、それが危険にさらされる可能性があるかどうかを確認してください。

4
fuxia

Swissspidyのコメントを答えにしようとします。ショートバージョン - それは異なります。

ダブルエスケープは意図したURLと一致しないURL(またはあらゆる種類のコンテンツ)を生成する可能性があるため、エスケープはランダムに適用しないでください。エスケープ処理は出力前にのみ適用されるべきです。そのため、コンテキストはURLを計算する特定の関数よりも重要です。

あなたの例では、最初のスニペットは単にURLをエンキューしてそれを出力しません。エスケープの責任は実際にそれを出力するコードにwordpressスタックに委任されています、そしてそれはそれがエスケープされない理由です。

2番目のスニペットは出力を行います、そしてそれはURLがエスケープされている理由です。

では、{not _エスケープする必要があるときにどのようにして知っていますか?うまくいけば、将来どこかにwordpress APIのドキュメントにその情報が含まれるようになるでしょうが、今のところは実際の出力まで完全なコードパスをたどるか、または "変な" URLでテーマをテストしてください

2
Mark Kaplun

これが問題の私たちの機能です。

File: wp-includes/theme.php
320: /**
321:  * Retrieve theme directory URI.
322:  *
323:  * @since 1.5.0
324:  *
325:  * @return string Template directory URI.
326:  */
327: function get_template_directory_uri() {
328:    $template = str_replace( '%2F', '/', rawurlencode( get_template() ) );
329:    $theme_root_uri = get_theme_root_uri( $template );
330:    $template_dir_uri = "$theme_root_uri/$template";
331: 
332:    /**
333:     * Filters the current theme directory URI.
334:     *
335:     * @since 1.5.0
336:     *
337:     * @param string $template_dir_uri The URI of the current theme directory.
338:     * @param string $template         Directory name of the current theme.
339:     * @param string $theme_root_uri   The themes root URI.
340:     */
341:    return apply_filters( 'template_directory_uri', $template_dir_uri, $template, $theme_root_uri );
342: }
343: 

あなたはあなたのプラグインでこのようなものを書きます:

add_filter('template_directory_uri',function(){ return 'http://badserver.com/'; });

そして、あなたはウェブサイト上でこのようなものを持つでしょう:

enter image description here 

WP_ThemeクラスがWP_Theme::get_template_directory_uri()メソッドでフィルタを実装していないのを見るので、明るいのは未来です。 WordPressがどんどん良くなっていってカプセル化されてきているのがわかります。

File: wp-includes/class-wp-theme.php
898:    /**
899:     * Returns the URL to the directory of a theme's "template" files.
900:     *
901:     * In the case of a child theme, this is the URL to the directory of the
902:     * parent theme's files.
903:     *
904:     * @since 3.4.0
905:     * @access public
906:     *
907:     * @return string URL to the template directory.
908:     */
909:    public function get_template_directory_uri() {
910:        if ( $this->parent() )
911:            $theme_root_uri = $this->parent()->get_theme_root_uri();
912:        else
913:            $theme_root_uri = $this->get_theme_root_uri();
914: 
915:        return $theme_root_uri . '/' . str_replace( '%2F', '/', rawurlencode( $this->template ) );
916:    }

その他のメモ

誰かがテーマの中で次のように定義するのを見ます:

define( 'TEMPL_URI', get_template_directory_uri() );

彼らは'TEMPL_URI'をフィルタリング不可能にしたいからです。彼らは間違ってる。プラグインが悪いフィルタを設定している場合、これはテーマの前に起こりますので、'TEMPL_URI'は汚いでしょう。

しかし、定数を定義しても構いません。定数はあなたを保護するものではないと言いたかっただけです。


私がTwenty Seventeenで見つけたもう一つのこと。そこに私はget_theme_file_uri関数を見ました(@since 4.7)

File: wp-includes/link-template.php
4026: /**
4027:  * Retrieves the URL of a file in the theme.
4028:  *
4029:  * Searches in the stylesheet directory before the template directory so themes
4030:  * which inherit from a parent theme can just override one file.
4031:  *
4032:  * @since 4.7.0
4033:  *
4034:  * @param string $file Optional. File to search for in the stylesheet directory.
4035:  * @return string The URL of the file.
4036:  */
4037: function get_theme_file_uri( $file = '' ) {
4038:   $file = ltrim( $file, '/' );
4039: 
4040:   if ( empty( $file ) ) {
4041:       $url = get_stylesheet_directory_uri();
4042:   } elseif ( file_exists( get_stylesheet_directory() . '/' . $file ) ) {
4043:       $url = get_stylesheet_directory_uri() . '/' . $file;
4044:   } else {
4045:       $url = get_template_directory_uri() . '/' . $file;
4046:   }
4047: 
4048:   /**
4049:    * Filters the URL to a file in the theme.
4050:    *
4051:    * @since 4.7.0
4052:    *
4053:    * @param string $url  The file URL.
4054:    * @param string $file The requested file to search for.
4055:    */
4056:   return apply_filters( 'theme_file_uri', $url, $file );
4057: }

やはりこのフィルタtheme_file_uriget_template_directory_uriで説明された@toschoのようなセキュリティ問題を強いるかもしれません。

結論

セキュリティが問題になっているとき、私たちは非常に注意する必要があります。ここでの問題は、単一のURLをエスケープするだけではないということです。 WordPressプラグインセキュリティモデル 全体を考慮します。

プラグインは、悪いことをするためにget_template_directory_uri()関数とそこにあるフィルタを必要としません。 WordPressコアと同じ権限で実行できます - 何でもできます。

悪いプラグインが注入するかもしれない悪意のあるJavaScriptはあなたがタイプしている間あなたのパスワードを読むかもしれません。

0
prosti