Estou vendo este episódio do Railscast e me perguntando por que a chamada para escape_javascript
é necessária aqui:
$("#reviews").append("<%= escape_javascript(render(:partial => @review)) %>");
Para que é escape_javascript
utilizado?
De acordo com a documentação do Rails :
escape_javascript (javascript)
Retorna a operadora de escape e aspas simples e duplas para segmentos JavaScript.
Mas isso não significa muito para mim.
Respostas:
Como você não deseja que os usuários postem JavaScript que o navegador realmente executa?
fonte
É mais fácil entender se você dividir o código em duas partes.
A primeira parte
$("#reviews").append("<%= ... %>");
é javascript com erb. Isso significa que o<%= ... %>
será substituído por qualquer que seja o código rubi dentro dele. O resultado dessa substituição deve ser um javascript válido, caso contrário, ocorrerá um erro quando o cliente tentar processá-lo. Então essa é a primeira coisa: você precisa de um javascript válido .Outra coisa a considerar é que tudo o que o ruby gera deve estar contido em uma string javascript com aspas duplas - observe as aspas duplas ao redor do
<%= ... %>
. Isso significa que o javascript gerado terá a seguinte aparência:Agora vamos examinar a parte do ruby dentro do
<%= ... %>
. O querender(:partial => @review)
faz? Está renderizando um parcial - o que significa que poderia renderizar qualquer tipo de código - html, css ... ou ainda mais javascript!Então, o que acontece se o nosso parcial contiver algum html simples, como este?
Lembre-se de que seu javascript estava usando uma string de aspas duplas como parâmetro? Se simplesmente substituirmos o
<%= ... %>
código pelo parcial, teremos um problema - imediatamente após ahref=
aspas duplas! O javascript não será válido:Para que isso não aconteça, você deseja escapar desses caracteres especiais para que sua string não seja cortada - você precisa de algo que gere isso:
É isso que
escape_javascript
faz. Ele garante que a string retornada não "quebre" o javascript. Se você usá-lo, obterá a saída desejada:Saudações!
fonte
escape_for_javascript
, já que muitas vezes você está escapando de outro código (html por exemplo) para que ele não quebre o javascript.escape_javascript()
agora tem um método mais curto: simpleyj()
(pelo menos no Rails 4).os usuários podem publicar códigos maliciosos (usuários mal-intencionados) que, se deixados sem escape, serão executados potencialmente, permitindo que os usuários controlem seu aplicativo.
tente isto:
Não estou realmente familiarizado com a sintaxe dos trilhos, mas se você não escapar
variable
, uma caixa de alerta será exibida, e não acho que esse seja o comportamento pretendido.fonte
Se você olhar a fonte aqui , será muito mais claro.
Essa função realiza as duas coisas a seguir:
Ele substitui os caracteres na sequência de entrada pelos definidos em JS_ESCAPE_MAP
O objetivo disso é garantir que o código javascript seja serializado corretamente, sem interferir na cadeia externa na qual está sendo incorporado. Por exemplo, se você tiver uma string javascript entre aspas duplas, todas as aspas para literais de string deverão estar entre aspas simples para evitar a quebra do código.
Quando você está usando escape_javascript, ele geralmente está sendo incorporado dentro de outra string ou html existente dinamicamente. Você precisa garantir que isso não faça com que sua página inteira não seja renderizada.
Alguns aspectos dessa resposta foram apontados em outras respostas, mas eu queria reunir todos os itens, incluindo a diferença entre escape de javascript e escape de html. Além disso, algumas respostas aludem que essa função ajuda a evitar a injeção de scripts. Não acho que esse seja o objetivo dessa função. Por exemplo, em sua revisão, se ela tiver um alerta ('oi'), apenas anexá-lo ao nó não acionará o pop-up. Você não está incorporando-o a uma função que é acionada no carregamento da página ou através de algum outro evento. Apenas ter o alerta ('oi lá') como parte do seu html não significa que ele será executado como javascript.
Dito isto, não estou negando que a injeção de script não seja possível. Mas, para evitar isso, é necessário tomar medidas ao coletar os dados do usuário e armazená-los em seu banco de dados. A função e o exemplo que você está fornecendo estão relacionados à renderização das informações, que já foram salvas.
Espero que isso ajude e responda à sua pergunta.
fonte