RoR 4에서 유효성 검사가 포함 된 정규식


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.
sawa

네,하지만 그것은 도움이되지 않았다
malcoauri

1
@wukerplank 우리가 추측하는 이유는 무엇입니까? 우리가 가지고있는 루비 irb: 우리가 확실히 알고 도움
mlibby

3
이 항목이 마지막 항목임을 나타내는 png 뒤의 $를 제거하고 \ z
Gary

답변:


158

^그리고 $시작되어 및 최종 라인의 앵커. 동안 \A\z영구 시작이다 문자열의 및 종료 문자열의 앵커.
차이점보기 :

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

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

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

레일 그래서 "당신은 당신이 사용 하시겠습니까, 당신을 말하고있다 ^하고 $그래서? 당신이 사용하지 \A하고 \z대신?"

여기 에이 경고를 생성하는 레일 보안 문제가 더 있습니다 .


3
불필요한 coloquialism을 고정
xaxxon

2
무엇을 요구하는지 설명하지만 해결 방법에 대해서는 답변하지 않습니다. ^ 및 $를 사용하려는 경우이를 수정하는 방법은 클래스 맨 위에 : multiline => true를 추가하는 것입니다.
isimmons 2013 년

@isimmons 추가 :multiline => true하면 Rails라는 경고 만 수정할 수 있습니다.
oldergod

6
대답은 거기에 있습니다. Ruby에서 ^ 및 $는 문자열의 시작 및 끝이 아닌 개행 문자 만 일치하므로 자바 스크립트 공격이 테스트를 통과 할 수 있기 때문에 ^ 및 $ 대신 \ A 및 \ z를 사용하는 것입니다.
JohnMerlino 2014-08-15

31

이 경고는 유효성 검사 규칙이 자바 스크립트 삽입에 취약하기 때문에 발생합니다.

귀하의 경우 \.(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

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

경고의 두 번째 부분은 ( "또는 추가하는 것을 잊었다 : 여러 => 진정한 옵션"참조) 실제로의 동작을 원한다면 당신을 말하고있다 ^그리고 $당신은 단순히 지나가는 경고를 침묵 수있는 :multiline옵션을 선택합니다.


그래서 어디를 지나가 :multiline나요?
Pithikos

-1

루비가 보안을 위해 기호 \z대신 보길 원한다면 $코드는 다음과 같을 것입니다 :

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.