이 문서는 GitLab 코드베이스에서 일반적으로 필요한 보안 Ruby 프로그래밍 관행에 대한 설명과 가이드라인을 포함합니다. 이 가이드라인은 개발자가 처음부터 안전한 Ruby 코드를 작성하고, 개발 프로세스 초기에 잠재적 보안 취약점을 식별하며, Ruby 관련 모범 사례를 따르도록 돕기 위한 것입니다. 이러한 표준을 준수함으로써 Ruby의 내장 보안 기능을 효과적으로 활용하면서 시간이 지남에 따라 출시되는 보안 취약점 수를 줄이는 것을 목표로 합니다. 정규 표현식 가이드라인 # Ruby에서의 앵커 / 멀티라인 # 다른 프로그래밍 언어(예: Perl 또는 Python)와 달리 Ruby에서는 정규 표현식이 기본적으로 멀티라인을 매칭합니다. 다음 Python 예시를 살펴보세요: import re text = "foo\nbar" matches = re.findall( "^bar$" ,text) print (matches) Python 예시는 매처가 줄바꿈( \n )을 포함한 전체 문자열 foo\nbar 를 고려하므로 빈 배열( [] )을 출력합니다. 반면 Ruby의 정규 표현식 엔진은 다르게 동작합니다: text = "foo\nbar" p text.match /^bar $/ 이 예시의 출력은 # 입니다. Ruby가 입력 text 를 줄 단위로 처리하기 때문입니다. 전체 문자열 을 매칭하려면 Regex 앵커 \A 와 \z 를 사용해야 합니다. 영향 # 이 Ruby Regex의 특성은 보안에 영향을 미칠 수 있습니다. 정규 표현식은 종종 유효성 검사나 사용자 입력에 대한 제한을 부과하는 데 사용되기 때문입니다. 예시 # GitLab 관련 예시는 다음 경로 탐색 및 오픈 리다이렉트 이슈에서 찾을 수 있습니다. 또 다른 예시로는 다음 가상의 Ruby on Rails 컨트롤러가 있습니다: class PingController < ApplicationController def ping if params[ :ip ] =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/ render :text => `ping -c 4 #{params[ :ip ]} ` else render :text => "Invalid IP" end end end 여기서 params[:ip] 는 숫자와 점 이외의 것을 포함하면 안 됩니다. 그러나 Regex 앵커 ^ 와 $ 를 사용하고 있어 이 제한을 우회할 수 있습니다. 결국 params[:ip] 에 줄바꿈을 사용하여 ping -c 4 #{params[:ip]} 에서 셸 명령 인젝션으로 이어집니다. 완화 # 대부분의 경우 ^ 와 $ 대신 텍스트 시작을 위한 \A 와 텍스트 끝을 위한 \z 앵커를 사용해야 합니다. 서비스 거부(ReDoS) / 재앙적 역추적 # 정규 표현식(regex)이 문자열을 검색하다가 일치하는 항목을 찾지 못할 때, 다른 가능성을 시도하기 위해 역추적할 수 있습니다. 예를 들어 regex .*!$ 가 문자열 hello! 를 매칭할 때, .* 가 먼저 전체 문자열과 매칭하지만 regex의 !