공개 웹 페이지에 정규식 검색 기능을 추가하고 싶습니다. 출력을 HTML로 인코딩하는 것 외에 악의적 인 사용자 입력을 막기 위해 어떤 조치를 취해야합니까?
Google 검색은 내가 관심이없는 악의적 인 입력을 탐지하기 위해 정규식을 사용하여 대화 문제를 해결하는 사람들로 인해 혼란에 빠졌습니다. 내 시나리오에서 사용자 입력 은 정규식입니다.
.NET (C #)에서 Regex 라이브러리를 사용할 것 입니다.
공개 웹 페이지에 정규식 검색 기능을 추가하고 싶습니다. 출력을 HTML로 인코딩하는 것 외에 악의적 인 사용자 입력을 막기 위해 어떤 조치를 취해야합니까?
Google 검색은 내가 관심이없는 악의적 인 입력을 탐지하기 위해 정규식을 사용하여 대화 문제를 해결하는 사람들로 인해 혼란에 빠졌습니다. 내 시나리오에서 사용자 입력 은 정규식입니다.
.NET (C #)에서 Regex 라이브러리를 사용할 것 입니다.
답변:
정규병에 대한 가장 일반적인 관심사는 기하 급수적 또는 심지어는 기하 급수적 인 병리학 적 패턴을 통한 서비스 거부 공격입니다! 따라서 해결하는 데 영원히 걸리는 것처럼 보입니다. 이들은 특정 입력 데이터에만 나타날 수 있지만 일반적으로 중요하지 않은 데이터를 생성 할 수 있습니다.
어느 것이 컴파일 타임 동안 감지 될 수 있기 때문에 사용중인 정규식 컴파일러가 얼마나 똑똑한 지에 따라 어느 것이 달라집니다. 재귀를 구현하는 정규식 컴파일러에는 일반적으로 비 진행을 확인하기위한 재귀 깊이 카운터가 내장되어 있습니다.
정규 표현식 일치 에 대한 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은 보간 된 모든 문자열에서 기본적으로 코드 설명문을 비활성화하므로 다시 사용하도록 설정해야합니다.
같은 - 유니 코드 - 스타일의 호텔과 관련된 또 하나의 보안이 중요한 문제가 남아있다 \pM
, \p{Pd}
, \p{Pattern_Syntax}
, 또는 \p{Script=Greek}
- 그 수 몇 가지 정규식 컴파일러 지원하는 그 표기법에 존재는.
문제는 이러한 속성 중 일부에서 가능한 속성 집합이 사용자 확장 가능하다는 것입니다. 즉, \p{GoodChars}
또는 과 같은 특정 네임 스페이스에서 명명 된 함수에 대한 실제 코드 콜 아웃 인 사용자 지정 속성을 가질 수 있습니다 \p{Class::Good_Characters}
. 당신의 언어가 그러한 것을 다루는 방법은 가치가 있습니다.
Perl에서 Safe
모듈을 통한 샌드 박스 구획 은 네임 스페이스 가시성을 제어합니다. 다른 언어는 유사한 샌드 박싱 기술을 제공합니다. 이러한 장치를 사용할 수있는 경우 신뢰할 수없는 코드의 제한된 실행을 위해 특별히 설계되었으므로 해당 장치를 살펴볼 수 있습니다.
tchrist의 훌륭한 대답에 덧붙여서 : "Regular Expression"페이지를 쓴 동일한 Russ Cox도 코드를 공개했습니다! re2 는 O (length_of_regex) 런타임 및 구성 가능한 메모리 사용 제한을 보장하는 C ++ 라이브러리입니다. Google 코드 검색에 정규식을 입력 할 수 있도록 Google에서 사용되므로 전투 테스트를 거쳤습니다.
예.
정규식을 사용하여 DOS 공격을 수행 할 수 있습니다 .
간단한 해결책은 없습니다.
이 논문을 읽고 싶을 것이다 :
안전하지 않은 컨텍스트 전환 : 생존을위한 정규 표현식 접종 이 백서에서는 정규 표현식 엔진 (예 : PCRE)에서 잘못 될 수있는 사항에 대해 자세히 설명하지만 자신이 무엇을 반대하는지 이해하는 데 도움이 될 수 있습니다.
보안 문제 (적어도 Windows의 경우)에 대해 RegEx를 테스트하는 좋은 방법은 최근에 Microsoft에서 출시 한 SDL RegEx 퍼징 도구 입니다. 이것은 병적으로 나쁜 RegEx 구성을 피하는 데 도움이 될 수 있습니다.