2013-07-20 25 views
74

Có đoạn mã sau:Regular expressions với kiểm chứng thực trong 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 

Nó hoạt động, nhưng khi tôi cố gắng để kiểm tra nó sử dụng "kiểm tra cào" Tôi sẽ bắt thông điệp này:

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? 

Điều đó có nghĩa là gì? Làm thế nào tôi có thể sửa chữa nó?

+0

Bạn đã thử '/ \. (Gif | jpg | png) $/i'? Có thể '% r {}' thêm '$' của chính nó vào cuối. – Wukerplank

+0

@Wukerplank Tôi không nghĩ vậy. '% r {\. (gif | jpg | png) $} i # =>/\. (gif | jpg | png) $/i','% r {\. (gif | jpg | png)} i # =>/\. (gif | jpg | png)/i'. – sawa

+0

Có, nhưng nó không giúp được – malcoauri

Trả lời

132

^$ là Bắt đầu của Dòng và End của Dòng neo. Trong khi \A\z là bắt đầu vĩnh viễn của chuỗi và kết thúc của chuỗi neo.
Thấy sự khác biệt:

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

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

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

Vì vậy, Rails là nói cho bạn, "Bạn có chắc chắn bạn muốn sử dụng ^$ Đừng bạn muốn sử dụng \A\z thay?"

Có nhiều vấn đề về bảo mật đường ray tạo ra cảnh báo này here.

+3

sửa chữa chủ nghĩa coloquialism không cần thiết – xaxxon

+1

giải thích nó là gì hỏi nhưng không trả lời cách khắc phục. Tôi cho rằng nếu bạn muốn sử dụng^và $ cách sửa nó là thêm: multiline => true ở đầu lớp? – isimmons

+0

@isimmons Bằng cách thêm ': multiline => true' bạn chỉ sửa chữa cảnh báo nói Rails bạn biết bạn đang làm gì. – oldergod

27

Cảnh báo này sẽ tăng vì quy tắc xác thực của bạn dễ bị tấn công do tiêm javascript.

Trong trường hợp của bạn \.(gif|jpg|png)$ phù hợp cho đến cuối dòng. Vì vậy, quy tắc của bạn sẽ xác nhận giá trị này pic.png\nalert(1); là đúng:

"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 

Đọc tin cũ hơn:

+0

Tốt nhất của bó, muốn chúng tôi có thể làm cho câu trả lời này được chấp nhận. – mlibby

1

Cảnh báo cho bạn biết là chuỗi như ý chí sau vượt qua xác thực, nhưng có lẽ không phải là những gì bạn muốn:

test = "image.gif\nthis is not an image" 
re = /\.(gif|jpg|png)$/i 
re.match(test) #=> #<MatchData ".gif" 1:"gif"> 

Cả ^$ khớp với đầu/cuối của bất kỳ dòng nào, không phải là đầu/cuối của chuỗi. \A\z khớp với phần đầu và cuối của chuỗi đầy đủ, tương ứng.

re = /\.(gif|jpg|png)\z/i 
re.match(test) #=> nil 

Phần thứ hai của các cảnh báo (“hay quên thêm: multiline => tùy chọn true”) đang nói với bạn rằng nếu bạn thực sự muốn hành vi của ^$ bạn chỉ có thể im lặng cảnh báo đi qua các :multiline tùy chọn.

+0

Vì vậy, nơi nào bạn vượt qua ': multiline'? – Pithikos

1

Regexp vấn đề không được đưa ra, mà là sống trong config/initializers/devise.rb.Thay đổi:

# Regex to use to validate the email address 
config.email_regexp = /^([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})$/i 

tới:

# Regex to use to validate the email address 
    config.email_regexp = /\A([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})\Z/i 
-1

Nếu của Ruby muốn nhìn thấy \z thay vì dấu $ biểu tượng, để bảo mật, bạn cần phải cung cấp cho nó với anh ta, sau đó mã sẽ trông như thế này:

validates :image_url, allow_blank: true, format: {with: %r{\.(gif|jpg|png)\z}i, message: 'URL must point to GIF, JPG, PNG.'} 
Các vấn đề liên quan