it-swarm.dev

تعبيرات منتظمة مع عمليات التحقق في 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 الأمنية التي تنشئ هذا التحذير هنا .

150
oldergod

يثير هذا التحذير لأن قاعدة التحقق من الصحة عرضة لحقن جافا سكريبت.

في حالتك ، تطابق الدالة \.(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

قراءة acticles:

29
ole

مشكلة إعادة الاسترداد ليست قيد الإعداد ، ولكنها تعيش في 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

يخبرك الجزء الثاني من التحذير ("أو نسيت إضافة:: multiline => true option") أنه إذا كنت تريد بالفعل سلوك ^ و $ ، فيمكنك ببساطة إسكات التحذير الذي يمر بخيار :multiline.

1
yonosoytu