83

有以下代码:

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?

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

4

5 回答 5

158

^并且是线$的起点和线的终点锚。While和是字符串的永久开始和字符串的结束锚点。 看到不同:\A\z

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

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

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

所以 Rails 告诉你,“你确定要使用^and$吗?你不想使用\Aand\z代替吗?”

此处还有更多的在轨安全问题会产生此警告。

于 2013-07-20T07:57:02.947 回答
31

出现此警告是因为您的验证规则容易受到 javascript 注入的影响。

在你的情况下\.(gif|jpg|png)$匹配到行尾。因此,您的规则将验证此值是否pic.png\nalert(1);为真:

"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

阅读文章:

于 2013-07-20T08:10:22.597 回答
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
于 2015-12-10T17:19:25.613 回答
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 => true 选项”)告诉你,如果你真的想要的行为,^你可以简单地通过选项$使警告静音。:multiline

于 2013-07-20T08:15:37.510 回答
-1

如果 Ruby 想看符号\z而不是$符号,为了安全起见,你需要把它给他,那么代码应该是这样的:

validates :image_url, allow_blank: true, format: {with: %r{\.(gif|jpg|png)\z}i, message: 'URL must point to GIF, JPG, PNG.'}
于 2016-07-31T13:51:17.330 回答