Regular expressions with validations in RoR 4

^ and $ are Start of Line and End of Line anchors. While \A and \z are Permanent Start of String and End of String anchors.
See the difference:

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

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

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

So Rails is telling you, "Are you sure you want to use ^ and $? Don't you want to use \A and \z instead?"

There is more on the rails security concern that generates this warning here.


This warning raises because your validation rule is vulnerable for javascript injection.

In your case \.(gif|jpg|png)$ matches till the end of the line. So your rule will validate this value pic.png\nalert(1); as 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 acticles:

  • http://caiustheory.com/validating-data-with-regular-expressions-in-ruby
  • http://guides.rubyonrails.org/security.html#regular-expressions

The problem regexp is not in devise, but rather lives 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

The warning is telling you that strings like the following will pass validation, but it 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 $ matches the start/end of any line, not the start/end of the string. \A and \z matches the start and the end of the full string, respectively.

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

The second part of the warning (“or forgot to add the :multiline => true option”) is telling you that if you actually want the behaviour of ^ and $ you can simply silence the warning passing the :multiline option.