Expresiones regulares con validaciones en RoR 4


83

Existe el siguiente código:

class Product < ActiveRecord::Base
  validates :title, :description, :image_url, presence: true
  validates :price, numericality: {greater_than_or_equal_to: 0.01}
  validates :title, uniqueness: true
  validates :image_url, allow_blank: true, format: {
      with: %r{\.(gif|jpg|png)$}i,
      message: 'URL must point to GIT/JPG/PNG pictures'
  }
end

Funciona, pero cuando intento probarlo usando "rake test", captaré este mensaje:

rake aborted!
The provided regular expression is using multiline anchors (^ or $), which may present a security risk. Did you mean to use \A and \z, or forgot to add the :multiline => true option?

Qué significa eso? ¿Cómo puedo arreglarlo?


¿Usted ha intentado /\.(gif|jpg|png)$/i? Quizás %r{}agregue el suyo $al final.
Wukerplank

@Wukerplank No lo creo. %r{\.(gif|jpg|png)$}i #=> /\.(gif|jpg|png)$/i, %r{\.(gif|jpg|png)}i #=> /\.(gif|jpg|png)/i.
sawa

Sí, pero no ayudó
malcoauri

1
@wukerplank, ¿por qué estamos adivinando? en ruby ​​tenemos irbque ayudarnos a saberlo con certeza :)
mlibby

3
Debe eliminar $ después de png) que indica que este es el último elemento y reemplazarlo con \ z
Gary

Respuestas:


158

^y $son anclas de inicio de línea y final de línea . Mientras \Ay \zson anclajes permanentes de inicio de cadena y final de cadena .
Ver la diferencia:

string = "abcde\nzzzz"
# => "abcde\nzzzz"

/^abcde$/ === string
# => true

/\Aabcde\z/ === string
# => false

Entonces Rails te está diciendo: "¿Estás seguro de que quieres usar ^y $? ¿No quieres usar \Ay en su \zlugar?"

Hay más preocupación por la seguridad de los rieles que genera esta advertencia aquí .


3
arreglando el coloquialismo innecesario
xaxxon

2
explica lo que pregunta pero no responde cómo solucionarlo. Supongo que si desea usar ^ y $, la forma de solucionarlo es agregar: multiline => true en la parte superior de la clase.
isimmons

@isimmons Al agregar :multiline => trueque solo corrige la advertencia que dice Rails, sabe lo que está haciendo.
dios mayor

6
La respuesta está ahí: es usar \ A y \ z en lugar de ^ y $ porque en Ruby, ^ y $ coinciden solo con una nueva línea, no el comienzo y el final de la cadena, lo que permite que un exploit de javascript pase la prueba.
JohnMerlino

31

Esta advertencia surge porque su regla de validación es vulnerable a la inyección de JavaScript.

En su caso, \.(gif|jpg|png)$coincide hasta el final de la línea. Entonces su regla validará este valor pic.png\nalert(1);como verdadero:

"test.png\n<script>alert(1)</script>" === /\.(gif|jpg|png)$/i
# => true

"test.png\n<script>alert(1)</script>" === /\.(gif|jpg|png)\z/i
# => false

Lea los artículos:


Lo mejor del grupo, ojalá pudiéramos hacer de esta la respuesta aceptada.
mlibby

2

El problema regexp no está en devise, sino que vive en config / initializers / devise.rb. Cambio:

# Regex to use to validate the email address
config.email_regexp = /^([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})$/i

a:

# Regex to use to validate the email address
  config.email_regexp = /\A([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})\Z/i

1

La advertencia le dice que cadenas como las siguientes pasarán la validación, pero probablemente no sea lo que desea:

test = "image.gif\nthis is not an image"
re = /\.(gif|jpg|png)$/i
re.match(test) #=> #<MatchData ".gif" 1:"gif">

Ambos ^y $coincide con el inicio / final de cualquier línea, no con el inicio / final de la cadena. \Ay \zcoincide con el inicio y el final de la cadena completa, respectivamente.

re = /\.(gif|jpg|png)\z/i
re.match(test) #=> nil

La segunda parte de la advertencia ("u olvidé agregar la opción: multiline => true") le dice que si realmente desea el comportamiento de ^y $puede simplemente silenciar la advertencia pasando la :multilineopción.


Entonces, ¿por dónde pasas :multiline?
Pithikos

-1

Si Ruby quiere ver en \zlugar del $signo del símbolo, por seguridad, debe dárselo, entonces el código se vería así:

validates :image_url, allow_blank: true, format: {with: %r{\.(gif|jpg|png)\z}i, message: 'URL must point to GIF, JPG, PNG.'}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.