正则expression式在RoR 4中进行了validation
有以下代码:
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
它的工作,但是当我尝试使用“耙testing”来testing它时,我会看到这个消息:
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?
这是什么意思? 我该如何解决?
^
和$
是开始行和结束行锚点。 \A
和\z
是string永久开始和string结束的锚点。
看到不同:
string = "abcde\nzzzz" # => "abcde\nzzzz" /^abcde$/ === string # => true /\Aabcde\z/ === string # => false
所以Rails告诉你:“你确定要使用^
和$
吗?你不想用\A
和\z
吗?
有更多的安全问题在这里产生这个警告。
此警告提出,因为您的validation规则是脆弱的JavaScript注入。
在你的情况下\.(gif|jpg|png)$
匹配直到行尾。 所以你的规则会validation这个值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
阅读电影:
警告告诉你像下面的string会通过validation,但它可能不是你想要的:
test = "image.gif\nthis is not an image" re = /\.(gif|jpg|png)$/i re.match(test) #=> #<MatchData ".gif" 1:"gif">
^
和$
匹配任何行的开始/结束,而不是string的开始/结束。 \A
和\z
匹配完整string的开始和结束。
re = /\.(gif|jpg|png)\z/i re.match(test) #=> nil
警告的第二部分(或忘记添加:multiline => true选项)告诉你,如果你真的想要^
和$
的行为,你可以简单地通过:multiline
选项来消除警告。
问题正则expression式不是在devise,而是生活在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
如果Ruby想要看到\z
而不是$
符号,为了安全起见,你需要把它交给他,那么代码将如下所示:
validates :image_url, allow_blank: true, format: {with: %r{\.(gif|jpg|png)\z}i, message: 'URL must point to GIF, JPG, PNG.'}