68 votes

Pourquoi escape_javascript avant le rendu d'un partiel ?

Je regarde cet épisode de Railscast et se demandant pourquoi l'appel à escape_javascript est nécessaire ici :

$("#reviews").append("<%= escape_javascript(render(:partial => @review)) %>");

Qu'est-ce que escape_javascript utilisé pour ?

Selon la documentation Rails :

escape_javascript(javascript)

Les retours des transporteurs d'évasion et le simple et doubles pour les segments JavaScript.

Mais ça ne veut pas dire grand-chose pour moi.

170voto

kikito Points 23229

Il est plus facile de comprendre si vous divisez le code en deux parties.

La première partie $("#reviews").append("<%= ... %>"); est javascript avec erb. Cela signifie que le <%= ... %> sera remplacé par ce que le code ruby qu'il contient renvoie. Le résultat de ce remplacement doit être un javascript valide, sinon une erreur se produira lorsque le client essaiera de le traiter. Donc c'est la première chose : vous avez besoin de javascript valide .

Une autre chose à prendre en compte est que tout ce que ruby génère doit être contenu dans une chaîne javascript avec des guillemets doubles - remarquez les guillemets doubles autour de l'élément <%= ... %> . Cela signifie que le javascript généré ressemblera à ceci :

$("#reviews").append("...");

Maintenant, examinons la partie ruby à l'intérieur de l'élément <%= ... %> . Que fait render(:partial => @review) faire ? Il effectue un rendu partiel - ce qui signifie qu'il peut rendre n'importe quel type de code - html, css ... ou même plus de javascript !

Alors, que se passe-t-il si notre partiel contient un simple html, comme celui-ci ?

<a href="http://stackoverflow.com/mycontroller/myaction">Action!</a> 

Vous vous souvenez que votre javascript prenait une chaîne de caractères entre guillemets comme paramètre ? Si nous remplaçons simplement le <%= ... %> avec le code de ce partiel, alors nous avons un problème - immédiatement après le href= il y a un guillemet double ! Le javascript ne sera pas valide :

// Without escaping, you get a broken javascript string at href
$("#reviews").append("<a href="http://stackoverflow.com/mycontroller/myaction">Action!</a>");

Pour que cela ne se produise pas, vous devez s'échapper ces caractères spéciaux afin que votre chaîne ne soit pas coupée - vous avez besoin de quelque chose qui génère ceci à la place :

<a href=\"/mycontroller/myaction\">Action!</a>

Ce qui escape_javascript fait. Il s'assure que la chaîne retournée ne "casse" pas le javascript. Si vous l'utilisez, vous obtiendrez le résultat souhaité :

$("#reviews").append("<a href=\"/mycontroller/myaction\">Action!</a>")

Salutations !

8voto

Azeem.Butt Points 5418

Parce que vous ne voulez pas que les utilisateurs postent des JavaScript que le navigateur exécute réellement ?

6voto

barkmadley Points 3526

Les utilisateurs peuvent poster du code malveillant (utilisateurs malveillants) qui, s'il n'est pas encodé, sera potentiellement exécuté, permettant ainsi aux utilisateurs de contrôler votre application.

Essayez ceci :

<% variable = '"); alert("hi there' %>
$("#reviews").append("<%= variable %>");

Je ne suis pas vraiment familier avec la syntaxe des rails, mais si vous ne vous échappez pas variable alors une boîte d'alerte s'affichera, et je ne pense pas que ce soit le comportement souhaité.

3voto

Tabrez Points 942

Si vous regardez la source ici ce sera beaucoup plus clair.

Cette fonction accomplit les deux choses suivantes :

  1. Il substitue les caractères de la chaîne d'entrée avec ceux définis dans JS_ESCAPE_MAP

    Le but de cette opération est de s'assurer que le code javascript est sérialisé correctement sans interférer avec la chaîne de caractères externe dans laquelle il est intégré. Par exemple, si vous avez une javascript entre guillemets doubles, tous les guillemets de la chaîne de caractères doivent être entre guillemets simples pour éviter que le code ne se brise. se rompe.

  2. La fonction vérifie également si la chaîne résultante est compatible avec le langage HTML. Si ce n'est pas le cas, elle effectue l'échappement nécessaire pour s'assurer que que la chaîne devienne compatible avec le html et renvoie le résultat.

Lorsque vous utilisez escape_javascript, il est généralement intégré à une autre chaîne ou à un fichier html existant de manière dynamique. Vous devez vous assurer que cette opération n'empêchera pas l'affichage de la page entière.

Certains aspects de cette réponse ont été signalés dans d'autres réponses, mais je voulais rassembler tous les éléments, notamment la différence entre l'échappement javascript et l'échappement html. De plus, certaines réponses font allusion au fait que cette fonction permet d'éviter l'injection de script. Je ne pense pas que ce soit l'objectif de cette fonction. Par exemple, si votre revue contient alert('hi there'), le simple fait de l'ajouter au nœud ne déclenchera pas la pop-up. Vous ne l'intégrez pas dans une fonction qui est déclenchée au chargement de la page ou par un autre événement. Le simple fait d'avoir alert('hi there') dans votre html ne signifie pas qu'il sera exécuté en tant que javascript.

Cela dit, je ne nie pas que l'injection de script n'est pas possible. Mais pour éviter cela, vous devez prendre des mesures lorsque vous prenez les données de l'utilisateur et les stockez dans votre base de données. La fonction et l'exemple que vous fournissez sont liés au rendu de l'information, qui a déjà été enregistrée.

J'espère que cela vous aidera et répondra à votre question.

0voto

Il échappe les caractères spéciaux de ce que vous rendez.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X