是否应该转义`GET_TEMPLATE_DIRECTORY_URI()`?

时间:2016-12-24 作者:grappler

应该get_template_directory_uri() 使用转义esc_url()?

我这样问是因为以默认主题“二十一五”为例,相同的函数在两个不同的地方使用,但只有一个地方是转义的。

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>
我可以这么说get_template_directory_uri() 不需要生成,因为URL无法在外部操纵。

3 个回复
最合适的回答,由SO网友:fuxia 整理而成

在该函数中,我们找到一个钩子:

return apply_filters( 
    \'template_directory_uri\', 
    $template_dir_uri, 
    $template, 
    $theme_root_uri
);
所以,是的,URI可以由插件更改,您应该转义它的返回值。

相同的原则适用于所有WordPress URI函数,如get_home_url(), get_site_url() 等等请记住,不仅有优秀的插件开发人员。有些人会犯错误,可能只是在某些情况下才会发生的很小的错误。

如果wp_enqueue_style(), WordPressdoes 默认情况下,转义URL。但这是对global WP_Styles 实例,而这反过来can be replaced easily – 即使使用不太安全的版本。这不太可能,但你应该意识到这种可能性。

不幸的是,WP本身并没有遵循“比抱歉更安全”的指令。它甚至无法逃避翻译。我的建议是不要把核心主题作为最佳实践。始终查看数据的来源,看看它是否可以被泄露。

SO网友:Mark Kaplun

将尝试将swissspidy的评论变成一个答案。简短版本-视情况而定。

不应随机应用转义,因为双重转义可能会产生与预期url不匹配的url(或任何类型的内容)。仅应在输出之前应用转义。因此,上下文比计算URL的特定函数更重要。

在您的示例中,第一个代码段只是将URL排队,而不输出它。转义的责任被进一步委托给wordpress堆栈中实际输出它的代码,这就是它没有转义的原因。

第二个代码段执行输出,这就是url被转义的原因。

那么你怎么知道什么时候应该not 逃跑希望将来wordpress API的文档中会包含这些信息,但现在要么遵循完整的代码路径直到实际输出,要么在“有趣的”URL下测试主题

SO网友:prosti

这是我们正在讨论的功能。

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 函数(@自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_uri 可能会造成像@toscho解释的安全问题get_template_directory_uri.

结论当安全性受到质疑时,我们需要非常小心。这里的问题不仅仅是转义单个URL。它考虑整体WordPress plugins security model.

插件不需要get_template_directory_uri() 函数和过滤器在那里做坏事。它们可以使用与WordPress核心相同的权限执行-它们可以做任何事情。

错误插件可能注入的恶意JavaScript可能会在您键入密码时读取您的密码。