악성 코드를 정규식에 넣을 수있는 방법이 있습니까?


138

공개 웹 페이지에 정규식 검색 기능을 추가하고 싶습니다. 출력을 HTML로 인코딩하는 것 외에 악의적 인 사용자 입력을 막기 위해 어떤 조치를 취해야합니까?

Google 검색은 내가 관심이없는 악의적 인 입력을 탐지하기 위해 정규식을 사용하여 대화 문제를 해결하는 사람들로 인해 혼란에 빠졌습니다. 내 시나리오에서 사용자 입력 정규식입니다.

.NET (C #)에서 Regex 라이브러리를 사용할 것 입니다.


4
사용하는 언어 및 / 또는 정규식 라이브러리에 따라 달라질 수 있습니다.
aschepler

좀 더 읽을 거리 : OWASP에 ReDoS , ReDoS 위키 백과
joeytwiddle

답변:


216

서비스 거부 문제

정규병에 대한 가장 일반적인 관심사는 기하 급수적 또는 심지어는 기하 급수적 인 병리학 적 패턴을 통한 서비스 거부 공격입니다! 따라서 해결하는 데 영원히 걸리는 것처럼 보입니다. 이들은 특정 입력 데이터에만 나타날 수 있지만 일반적으로 중요하지 않은 데이터를 생성 할 수 있습니다.

어느 것이 컴파일 타임 동안 감지 될 수 있기 때문에 사용중인 정규식 컴파일러가 얼마나 똑똑한 지에 따라 어느 것이 달라집니다. 재귀를 구현하는 정규식 컴파일러에는 일반적으로 비 진행을 확인하기위한 재귀 깊이 카운터가 내장되어 있습니다.

정규 표현식 일치 에 대한 Russ Cox의 우수한 2007 논문은 간단하고 빠를 수 있지만 (Java, Perl, PHP, Python, Ruby 등에서는 느리다) Henry Sencer의 코드에서 파생 된 것으로 보이는 대부분의 최신 NFA에 대해 이야기합니다. , 톰슨 스타일 NFA에 이러한 문제가없는 경우 성능이 크게 저하됩니다.

DFA로 해결할 수있는 패턴 만 인정하면 그와 같이 컴파일 할 수 있으며 패턴이 더 빠르게 실행됩니다. 그러나 이렇게하려면 시간 이 걸립니다 . Cox 논문은 이러한 접근 방식과 그에 따른 문제점을 언급합니다. 이 모든 것이 고전적인 시공간 트레이드 오프로 귀결됩니다.

DFA를 사용하면 DFA를 구축하고 더 많은 상태를 할당하는 데 더 많은 시간을 소비하는 반면 NFA를 사용하면 동시에 여러 상태가 될 수 있으며 역 추적을 통해 점심과 CPU를 먹을 수 있기 때문에 더 많은 시간을 소비합니다.

서비스 거부 솔루션

아마도 우주의 열사로 레이스가 끝나는 패턴을 해결하는 가장 합리적인 방법은 실행을 위해 최대 시간을 효과적으로 배치하는 타이머로 패턴을 감싸는 것입니다. 일반적으로 이것은 대부분의 HTTP 서버가 제공하는 기본 시간 초과보다 훨씬 적습니다.

alarm(N)C 레벨에서 간단한 형태로 try {}, 어획 유형 경보 유형 예외를 차단하는 다양한 방법이 있으며, 타이밍 제약 조건으로 특별히 작성된 새 스레드를 생성하는 모든 방법이 있습니다.

코드 설명 선

코드 콜 아웃을 허용하는 정규식 언어에서는 컴파일 문자열에서 코드를 허용하거나 허용하지 않는 메커니즘 이 제공 되어야 합니다. 코드 설명 선이 사용중인 언어로만 코드를 작성하더라도 제한해야합니다. 외부 코드를 호출 할 필요는 없지만 가능하면 훨씬 더 큰 문제가 있습니다.

예를 들어, Perl use re "eval";에서는 현재 범위에서 활성화 된 특수 어휘 범위 프라그 마가 아닌 한 문자열 보간에서 생성 된 정규 표현식에 코드 콜 아웃을 가질 수 없습니다 (이것은 런타임 중에 컴파일되는 것처럼) .

이런 식으로 아무도 코드 콜 아웃을 몰래 들어와 같은 시스템 프로그램을 실행할 수 없습니다 rm -rf *. 코드 설명 선은 보안에 매우 민감하기 때문에 Perl은 보간 된 모든 문자열에서 기본적으로 코드 설명문을 비활성화하므로 다시 사용하도록 설정해야합니다.

사용자 정의 \ P {roperties}

같은 - 유니 코드 - 스타일의 호텔과 관련된 또 하나의 보안이 중요한 문제가 남아있다 \pM, \p{Pd}, \p{Pattern_Syntax}, 또는 \p{Script=Greek}- 그 몇 가지 정규식 컴파일러 지원하는 그 표기법에 존재는.

문제는 이러한 속성 중 일부에서 가능한 속성 집합이 사용자 확장 가능하다는 것입니다. 즉, \p{GoodChars}또는 과 같은 특정 네임 스페이스에서 명명 된 함수에 대한 실제 코드 콜 아웃 인 사용자 지정 속성을 가질 수 있습니다 \p{Class::Good_Characters}. 당신의 언어가 그러한 것을 다루는 방법은 가치가 있습니다.

샌드 박싱

Perl에서 Safe모듈을 통한 샌드 박스 구획 은 네임 스페이스 가시성을 제어합니다. 다른 언어는 유사한 샌드 박싱 기술을 제공합니다. 이러한 장치를 사용할 수있는 경우 신뢰할 수없는 코드의 제한된 실행을 위해 특별히 설계되었으므로 해당 장치를 살펴볼 수 있습니다.


4
NFA-> DFA 변환은 지수 상태 폭발을 생성하여 시간 DoS를 공간 DoS로 전환하고 지수 수의 상태를 생성하는 시간 비용을 발생시킵니다.
Barry Kelly

그러나 그는 전체 정규 표현식 기능이 필요하지 않을 것입니다. Google과 같은 정규 표현식의 힘을 제한하는 것에 대해 어떻게 생각하십니까? google.com/intl/ko/help/faq_codesearch.html#regexp
systemsfault

1
@Barry 아주 그렇습니다. 나는 NFA의 일부를 동등한 DFA로 점진적으로 컴파일하지만 너무 커지면 버릴 수 있다는 그의 논문 중 하나에서 Russ Cox의 전략을 생각하고있었습니다. 그러나 톰슨이 NFA와 동등한 것으로 판명 했더라도 DFA에는 실버 총알이 없습니다. 파이퍼에게 어떤 시점에서 지불해야하기 때문입니다. 더 많은 공간을 확보하기 위해 운영 체제를 구걸하는 데 소요 된 시간과 수행자 페이지 테이블 설정 비용은 때때로 다른 방법으로 밸런싱 스케일을 조금씩 이동시켜 시간에서 공간으로의 변환이 예상보다 덜 매력적으로 만들 수 있습니다.
tchrist

20

tchrist의 훌륭한 대답에 덧붙여서 : "Regular Expression"페이지를 쓴 동일한 Russ Cox도 코드를 공개했습니다! re2 는 O (length_of_regex) 런타임 및 구성 가능한 메모리 사용 제한을 보장하는 C ++ 라이브러리입니다. Google 코드 검색에 정규식을 입력 할 수 있도록 Google에서 사용되므로 전투 테스트를 거쳤습니다.


2
실제로 그렇습니다. 모듈을 사용하여 re2를 Perl의 정규식 엔진으로 바꿀 수 있으며 가능하면 re2를 사용하고 그렇지 않은 경우 Perl을 사용합니다. 아주 잘 작동합니다.
tchrist


6

이 논문을 읽고 싶을 것이다 :

안전하지 않은 컨텍스트 전환 : 생존을위한 정규 표현식 접종 이 백서에서는 정규 표현식 엔진 (예 : PCRE)에서 잘못 될 수있는 사항에 대해 자세히 설명하지만 자신이 무엇을 반대하는지 이해하는 데 도움이 될 수 있습니다.


1
다음은 GNU libc regcomp (3) 코드에 대한 보안 권고입니다. securityreason.com/achievement_securityalert/93 얼마나시의 적절한 지! 리눅스에서 적어도,이 취약점을 증명하기 쉬운 : GREP -E를 "* {10} {10} {10} {10} {10}."
브루스 Ediger

5

일치 자체에 대해 걱정할 필요는 없지만 일치하는 방법에 대해 걱정해야합니다. 예를 들어, 입력이 정규식 엔진으로가는 도중에 일종의 평가 단계 또는 명령 대체를 거치면 패턴 내부에서 실행되는 코드가있을 수 있습니다. 또는 정규식 구문이 내장 명령을 허용하는 경우에도주의해야합니다. 질문에 언어를 지정하지 않았기 때문에 모든 보안 관련 사항이 무엇인지 확실히 말하기는 어렵습니다.


1

보안 문제 (적어도 Windows의 경우)에 대해 RegEx를 테스트하는 좋은 방법은 최근에 Microsoft에서 출시 한 SDL RegEx 퍼징 도구 입니다. 이것은 병적으로 나쁜 RegEx 구성을 피하는 데 도움이 될 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.