forked from eifion/asciicasts.com-translations
/
es.html
executable file
·156 lines (114 loc) · 9.66 KB
/
es.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
<p>En el episodio 27 [<a href="http://railscasts.com/episodes/27-cross-site-scripting">verlo</a>, <a href="http://asciicasts.com/episodes/27-cross-site-scripting">leerlo</a>] tratábamos acerca del <em>cross-site scripting</em> (XSS), que es una importante cuestión para cualquier desarrollador web. Uno de los momentos en los que las aplicaciones web son vulnerables a ataques XSS es cuando muestran información introducida por los usuarios. Es muy importante, por tanto, escapar toda esta información, lo que en Rails se hace por lo general con el método <code>h</code>.</p>
<pre class="ruby">
<%= h comment.content %>
</pre>
<p class="title">Uso del método h para escapar la salida.</p>
<p>Sin embargo en Rails 3 la salida de nuestra aplicación es escapada automáticamente de forma que no hay que poner el método <code>h</code> en nuestras vistas. En este episodio veremos como gestiona Rails este escapado automático.</p>
<p>Para ver como funciona todo esto vamos a utilizar una aplicación sencilla de <em>blog</em> escrita con Rails 3. En esta aplicación tendremos artículos y cada artículo puede tener un número de comentarios asociados. Vamos a comprobar la reacción del sistema de comentarios ante un intento de XSS introduciendo <code><script>alert('I steal cookies!')</script></code> en cada campo del formulario de comentarios y enviando este malvado comentario.</p>
<div class="imageWrapper">
<img src="/system/photos/338/original/E204I01.png" alt="Introduciendo un comentario malvado." height="527" width="815" />
</div>
<p>Cuando enviamos este comentario y se visualiza en la página veremos que Rails 3 automáticamente ha escapado las etiquetas HTML en los campos que hemos enviado. Veamos cómo lo ha hecho.</p>
<div class="imageWrapper">
<img src="/system/photos/339/original/E204I02.png" alt="Los comentarios en HTML se escapan automáticamente." height="331" width="815" />
</div>
<p>El código que muestra cada comentario se encuentra en un parcial, y si examinamos dicho código veremos que la salida no está siendo protegida utilizando <code>h</code>.</p>
<p class="codeFilePath">/app/views/comments/_comment.html.erb</p>
<pre class="ruby">
<div class="comment">
<strong><%= link_to comment.name, comment.url %></strong>
<p><%= comment.content %></p>
</div>
</pre>
<p>Esto quiere decir que con este código de vista en Rails 2 los mensajes de alerta se habrían mostrado. En Rails 3 toda la salida del parcial es escapada incluso a través de <em>helpers</em> como <code>link_to</code> así que ya no hay que utilizar el método <code>h</code>.</p>
<p>¿Qué ocurre si, por ejemplo, estamos migrando una aplicación de Rails 2 y nuestras vistas sí que están utilizando el método <code>h</code>? Podemos averiguarlo haciendo ese cambio en el parcial anterior y recargando la página.</p>
<p class="codeFilePath">/app/views/comments/_comment.html.erb</p>
<pre class="ruby">
<div class="comment">
<strong><%= link_to h(comment.name), comment.url %></strong>
<p><%= h comment.content %></p>
</div>
</pre>
<p>Si recargamos la página veremos que tiene el mismo aspecto y que la salida no ha sido escapada por partida doble. Rails es inteligente aquí, aún si usamos el método <code>h</code>.</p>
<p> Podríamos pensar a la vista de esto que el método <code>h</code> es inocuo en Rails 3, pero no es así; más adelante veremos cuál es su propósito pero de momento veamos una funcionalidad relacionada. Si bien es muy interesante tener la salida escapada automáticamente puede ser que a veces queramos mostrar el contenido en bruto: si confiamos en el contenido que ha introducido el usuario (por ejemplo
se trata de un usuario administrador) y queremos mostrar exactamente lo que ha introducido podemos utilizar el nuevo método <code>raw</code>.</p>
<pre class="ruby">
<div class="comment">
<strong><%= link_to comment.name, comment.url %></strong>
<p><%= raw comment.content %></p>
</div>
</pre>
<p>Si recargamos la página esta vez sí que se ejecutará el código Javascript que hemos introducido en el comentario.</p>
<div class="imageWrapper">
<img src="/system/photos/340/original/E204I03.png" alt="Cuando se usa el método raw se muestra la alerta." height="332" width="819" />
</div>
<p>Por tanto en Rails podemos usar el método <code>raw</code> cuando no queramos escapar el contenido en HTML. ¿Pero cómo funciona esto, cómo es Rails tan inteligente como para saber cuándo tiene que escapar y cuándo no?.</p>
<p>Esto lo veremos en la consola, que en Rails 3 se invoca con el comando <code>rails c</code>.</p>
<pre class="terminal">
$ rails c
Loading development environment (Rails 3.0.0.beta)
ruby-1.9.1-p378 >
</pre>
<p>Rails 3 introduce el concepto de cadenas con HTML seguro. Esto significa que podemos comprobar si es seguro mostrar una cadena como HTML invocando el método <code>html_safe?</code> sobre ella.</p>
<pre class="terminal">
> "foo".html_safe?
=> false
</pre>
<p>Con el método <code>html_safe</code> se puede marcar una cadena como segura.</p>
<pre class="terminal">
> safe = "safe".html_safe
=> "safe"
> safe.html_safe?
=> true
</pre>
<p>Aún no hemos efectuado ninguna modificación al contenido. Lo único que hacemos es cambiar una propiedad booleana
de la cadena que se usará para determinar si debe ser escapada antes de ser visualizada.</p>
<p>A la hora de aplicar esto a nuestra vista, Rails examinará cada cadena y mirará si está marcada como HTML seguro. Si no lo es, será automáticamente convertida mientras que si lo es se mostrará sin procesar. Si se usa el método <code>h</code> en una cadena, realizará la conversión y la marcará como segura, lo que significa que Rails 3 considerará que la cadena es segura y no la volverá a escapar.</p>
<p>Cuando se usa el método <code>raw</code> en una cadena, se marcará como segura pero su contenido seguirá intacto de forma que la cadena pasará sin alteración.</p>
<p>Es importante entender esto cuando usamos <em>helpers</em>. Como ejemplo crearemos un método llamado <code>strong</code> que rodea lo que se le
pase con un par de etiquetas <code><strong></code>. En nuestra vista lo utilizaremos así:</p>
<p class="codeFilePath">/app/views/comments/_comment.html.erb</p>
<pre class="ruby"><div class="comment">
<%= strong link_to(comment.name, comment.url) %>
<p><%= raw comment.content %></p>
</div>
</pre>
<p>Crearemos en <code>ApplicationHelper</code> el método <code>strong</code>:</p>
<p class="codeFilePath">/app/helpers/application_helper.rb</p>
<pre style="display: none;" class="ruby">
module ApplicationHelper
def strong(content)
"<strong>#{content}</strong>"
end
end
</pre>
<p>Pero veremos que este método no ha funcionad como esperábamos si recargamos la página.</p>
<div class="imageWrapper">
<img src="/system/photos/341/original/E204I04.png" alt="La etiqueta strong en nuestro método ha sido escapada." height="552" width="815" />
</div>
<p>El escapado automático de Rails 3 ha modificado la etiqueta <code><strong></code> porque nuestro <em>helper</em> no ha creado una cadena HTML segura.</p>
<p>Sólo hay que seguir dos reglas muy sencillas cuando definamos <em>helpers</em> que devuelvan HTML. Primero tenemos que asegurarnos de que las cadenas que devolvamos estén marcadas como seguras.</p>
<p class="codeFilePath">/app/helpers/application_helper.rb</p>
<pre class="ruby">
module ApplicationHelper
def strong(content)
"<strong>#{content}</strong>".html_safe
end
end
</pre>
<p>Esto corrige el problema de que la etiqueta <code><strong></code> aparezca escapada pero ahora resulta que el contenido entre las etiquetas
no será escapado. Para esto podemos escapar el contenido con nuestro viejo amigo el método <code>h</code>:</p>
<p class="codeFilePath">/app/helpers/application_helper.rb</p>
<pre class="ruby">
module ApplicationHelper
def strong(content)
"<strong>#{h(content)}</strong>".html_safe
end
end
</pre>
<p>Así que para que todo se muestre correctamente tenemos que escapar cualquier contenido introducido por el usuario con
el método <code>h</code> y marcar la cadena resultante como segura con <code>html_safe</code>. Si recargamos la página, ahora veremos que la etiqueta <code><strong></code> no ha sido escapada pero el contenido del segundo comentario, que incluye el Javascript peligroso, sí que ha sido escapado.</p>
<div class="imageWrapper">
<img src="/system/photos/342/original/E204I05.png" alt="El helper se escapa correctamente." height="552" width="815" />
</div>
<p>Y con esto termina nuestro episodio. El escapado automático es una nueva funcionalidad de Rails 3 que elimina la necesidad de tener que acordarse de escapar cualquier fragmento de salida con <code>h</code>, reduciéndose de esta forma las posibilidades de que seamos víctimas de un ataque XSS.</p>