Regular expressions with checks in RoR 4

The following code exists:

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 

This works, but when I try to test it with the "rake test", I will catch this message:

 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? 

What does it mean? How can i fix this?

+68
ruby ruby-on-rails activerecord
Jul 20 '13 at 7:11
source share
5 answers

^ and $ begin with lines and End lowercase . While \A and \z are Start string and End string constants.
See the difference:

 string = "abcde\nzzzz" # => "abcde\nzzzz" /^abcde$/ === string # => true /\Aabcde\z/ === string # => false 

So, Rails tells you: "Do you really want to use ^ and $ ? Instead, you do not want to use \A and \z ?

For safety reasons related to rails, there is more than this warning here .

+125
Jul 20 '13 at 7:57
source share

This warning occurs because your validation rule is vulnerable to javascript injection.

In your case, \.(gif|jpg|png)$ matches to the end of the line. Thus, your rule will check this pic.png\nalert(1); like true:

 "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 

Read the steps:

+27
Jul 20 '13 at 8:10
source share

A warning tells you that lines like the ones below will pass the test, but this is probably not what you want:

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

Both ^ and $ correspond to the beginning / end of any line, not the beginning / end of a line. \A and \z correspond to the beginning and end of a full line, respectively.

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

The second part of the warning ("or you forgot to add: multiline => true option") tells you that if you really want the ^ and $ behavior, you can simply turn off the warning that sends :multiline .

+1
Jul 20 '13 at 8:15
source share

The regexp problem is not in development, but rather in config / initializers / devise.rb. Change:

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

to:

 # Regex to use to validate the email address config.email_regexp = /\A([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})\Z/i 
+1
Dec 10 '15 at 17:19
source share

If Ruby wants to see \z instead of the $ sign, for security, you need to pass it to it, then the code will look like this:

 validates :image_url, allow_blank: true, format: {with: %r{\.(gif|jpg|png)\z}i, message: 'URL must point to GIF, JPG, PNG.'} 
-one
Jul 31 '16 at 13:51
source share



All Articles