web-dev-qa-db-ja.com

RoR 4で検証された正規表現

次のコードがあります。

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 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?

どういう意味ですか?どうすれば修正できますか?

82
malcoauri

^および$は、開始および終了アンカーです。 \Aおよび\zは永続的な開始文字列のおよび終了文字列のアンカーです。
違いを見ます:

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

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

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

Railsは、「^$を使用してよろしいですか?\A\z代わりに?」

Railsこの警告を生成するセキュリティ上の懸念 here

151
oldergod

検証ルールは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

アクティクルを読む:

30
ole

問題の正規表現は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
2
mcr

警告は、次のような文字列が検証に合格することを示していますが、おそらくあなたが望むものではありません:

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

警告の2番目の部分(「:multiline => trueオプションを追加するのを忘れた」)は、実際に^および$は、単に:multilineオプション。

1
yonosoytu