在RoR 4中使用验证的正则表达式

时间:2013-07-20 07:11:41

标签: ruby-on-rails ruby activerecord

有以下代码:

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

它有效,但是当我尝试使用“rake test”测试它时,我会发现这条消息:

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?

这是什么意思?我该如何解决?

5 个答案:

答案 0 :(得分:149)

^$是行和行锚点。虽然\A\z是永久开始的字符串,但是结束的字符串锚点。
看到差异:

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

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

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

所以Rails告诉你,“你确定要使用^$吗?难道你不想使用\A\z吗?”

有关rails安全问题的更多内容会产生此警告here

答案 1 :(得分:28)

此警告会引发,因为您的验证规则很容易被javascript注入。

在你的情况下,\.(gif|jpg|png)$匹配到行尾。因此,您的规则会将此值pic.png\nalert(1);验证为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

阅读以下内容:

答案 2 :(得分:2)

问题regexp不是设计,而是存在于config / initializers / devise.rb中。变化:

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

到:

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

答案 3 :(得分:1)

警告告诉你像下面这样的字符串会通过验证,但它可能不是你想要的:

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

^$都匹配任何行的开头/结尾,而不是字符串的开头/结尾。 \A\z分别匹配完整字符串的开头和结尾。

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

警告的第二部分(“或忘记添加:multiline =&gt; true选项”)告诉您,如果您确实想要^$的行为,您可以简单地通过:multiline选项使警告静音。

答案 4 :(得分:-1)

如果Ruby希望看到selection-multi而不是\z符号,为了安全起见,您需要将其提供给他,然后代码将如下所示:

$