RoR4で検証された正規表現


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?

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


試しました/\.(gif|jpg|png)$/iか?たぶん最後に%r{}それ自身$を追加します。
Wukerplank 2013

@Wukerplankそうは思いません。%r{\.(gif|jpg|png)$}i #=> /\.(gif|jpg|png)$/i%r{\.(gif|jpg|png)}i #=> /\.(gif|jpg|png)/i
さわ

はい、しかしそれは役に立ちませんでした
malcoauri 2013

1
@wukerplankなぜ私たちは推測しているのですか?ルビーではirb、私たちは確実に知るのを手伝わなければなりません:)
mlibby 2014年

3
これが最後のアイテムであることを示すpngの後の$を削除し、\ zに置き換える必要があります
Gary

回答:


158

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

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

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

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

そのため、Railsは、「本当に使用^$ますか?代わりに使用しませんか?」\Aと言っています\z

ここで、この警告を生成するセキュリティ上の懸念がさらにあります


3
不必要なコロキアリズムの修正
xaxxon 2013

2
それが何を求めているかを説明しますが、それを修正する方法には答えません。^と$を使用したい場合、それを修正する方法は、クラスの先頭に:multiline => trueを追加することだと思いますか?
isimmons 2013

@isimmons追加する:multiline => trueことで、Railsが何をしているか知っているという警告のみを修正します。
oldgod 2013

6
答えはそこにあります。Rubyでは^と$は文字列の開始と終了ではなく改行のみに一致するため、^と$ではなく\ Aと\ zを使用することで、javascriptエクスプロイトがテストに合格できるようにします。
JohnMerlino 2014

31

この警告は、検証ルールが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

アクティクルを読む:


何よりも、これを受け入れられた答えにできたらいいのにと思います。
mlibby 2014年

2

問題の正規表現はデバイスではなく、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

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

警告の2番目の部分(「:multiline => trueオプションを追加するのを忘れた」)は、の動作が実際に必要で^あり$:multilineオプションを渡す警告を単に消音できる場合に通知します。


それで、あなたはどこを通過し:multilineますか?
ピティコス2016年

-1

Rubyがシンボル記号の\z代わりに表示したい場合$は、セキュリティのために、Rubyに渡す必要があります。そうすると、コードは次のようになります。

validates :image_url, allow_blank: true, format: {with: %r{\.(gif|jpg|png)\z}i, message: 'URL must point to GIF, JPG, PNG.'}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.