web-dev-qa-db-fra.com

`Get_template_directory_uri ()` devrait-il être échappé?

get_template_directory_uri() devrait-il être échappé avec esc_url()?

Je demande parce que, prenant un exemple du thème par défaut Twenty Fifteen, la même fonction est utilisée à deux endroits différents mais elle n’est échappée qu’à un seul.

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>

Je dirais que cette fonction get_template_directory_uri() n'a pas besoin d'être générée, car l'URL ne peut pas être manipulée en externe.

6
grappler

Dans cette fonction, nous trouvons un crochet:

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

Donc, oui, l'URI peut être modifié par des plugins et vous devriez échapper à sa valeur renvoyée.

Le même principe s’applique à toutes les fonctions WordPress URI, telles que get_home_url(), get_site_url() et ainsi de suite. Gardez à l'esprit qu'il n'y a pas que de bons développeurs de plugins. Certains font des erreurs, peut-être juste de toutes petites erreurs qui n'arrivent que dans certaines circonstances.

Dans le cas de wp_enqueue_style(), WordPress échappe-t-il à l'URL par défaut. Mais c’est un wrapper pour l’instance globalWP_Styles, et cela à son tour peut être remplacé facilement - même avec une version moins sûre. Ce n'est pas très probable, mais vous devriez être conscient de cette possibilité.

Malheureusement, WP lui-même ne suit pas la directive mieux vaut prévenir que guérir. Cela n'échappe même pas aux traductions. Mon conseil est de ne pas regarder les thèmes de base pour les meilleures pratiques. Regardez toujours la source des données et voyez si elles peuvent être compromises.

4
fuxia

Nous allons essayer de faire en sorte que le commentaire de swissspidy soit une réponse. Version courte - ça dépend.

Escaping ne doit pas être appliqué de manière aléatoire, car une double fuite pourrait produire une URL (ou tout type de contenu) ne correspondant pas à l'URL souhaitée. L'échappement doit être appliqué uniquement avant la sortie. Par conséquent, le contexte est plus important que la fonction spécifique qui calcule l’URL.

Dans votre exemple, le premier extrait met simplement l'URL en file d'attente et ne le sort pas. La responsabilité de s’échapper est déléguée plus loin dans la pile wordpress au code qui la produit réellement, et c’est la raison pour laquelle elle n’est pas échappée.

Le deuxième extrait fait la sortie et c'est pourquoi l'url est échappé.

Alors, comment savez-vous quand vous devriez pas vous échapper? Espérons que quelque part dans le futur, la documentation des API wordpress inclura ces informations, mais pour l'instant, suivez le chemin d'accès complet au code jusqu'à la sortie réelle, ou testez votre thème sous des URL "drôles".

2
Mark Kaplun

Voici notre fonction en question.

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: 

Vous écrivez quelque chose comme ça dans votre plugin:

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

Et vous aurez quelque chose comme ça sur un site web:

 enter image description here 

Bright est le futur parce que je vois qu'une classe WP_Theme n'implémente pas le filtre dans la méthode WP_Theme::get_template_directory_uri(). Nous savons que lentement WordPress devient de mieux en mieux et plus encapsulé.

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:    }

Plus de notes

Vous voyez quelqu'un définir dans le thème quelque chose comme ceci:

define( 'TEMPL_URI', get_template_directory_uri() );

Ils disent que c’est parce qu’ils aimeraient rendre 'TEMPL_URI' non filtrable. Ils ont tort. Si un plugin définit un mauvais filtre, cela se produira avant le thème, donc le 'TEMPL_URI' sera sale.

Cependant, il est correct de définir les constantes, je voulais juste dire que la constante ne vous protégera pas.


Une autre chose que j'ai trouvée dans Twenty Seventeen. Là, j'ai vu la fonction 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: }

Encore une fois, ce filtre theme_file_uri peut imposer un problème de sécurité tel que @toscho expliqué pour get_template_directory_uri.

Conclusion

Lorsque la sécurité est en cause, nous devons faire très attention. Le problème ici est plus profond que d'échapper à l'URL unique. Il considère l’ensemble modèle de sécurité des plugins WordPress .

Les plugins n'ont pas besoin de la fonction get_template_directory_uri() et du filtre pour faire le mauvais choix. Ils peuvent exécuter avec les mêmes privilèges que le noyau WordPress - ils peuvent tout faire.

Un code JavaScript malveillant que de mauvais plugins peuvent injecter peut lire vos mots de passe pendant que vous tapez.

0
prosti