본문 바로가기

algorithm

[취약성] ReDoS (정규식을 이용한 서비스 거부)

DDos라는 용어는 언론에 많이 나와서 익숙하다. ReDos라는 것도 있다는 사실.

어제 SonarQube에서 아래와 같이

정규식이 ReDos에 취약하다고 경고를 보여줘서 재근님이 고민을 하셨다.

위의 정규식은 그리 취약하지 않으나 [ 나 * 나 { 가 2번 이상 나오면 취약하다고 판단해버린다.

https://github.com/SonarSource/SonarJS/blob/master/eslint-bridge/src/rules/regular-expr.ts#L90

const specialChars = ["+", "*", "{"];

function hasEnoughNumberOfSpecialChars(value: string) {
  let numberOfSpecialChars = 0;
  for (const c of value) {
    if (specialChars.includes(c)) {
      numberOfSpecialChars++;
    }
    if (numberOfSpecialChars === 2) {
      return true;
    }
  }
  return false;
}

문제가 되는 코드는 캡쳐와 매칭에 인접해 있는 + 나 * 같은 문자들이다.

예) (\S+)+

 

그런데 현실이 되었습니다.

어제 저녁 갑자기 CPU가 튀는 인스턴스들이 발생했다.

스레드 덤프를 떠서 보면 WAITING 상태에 있는 것들이 대부분 regex 쪽에 있었다.

java.lang.Thread.State: RUNNABLE
    at java.util.regex.Pattern$CharProperty$1.isSatisfiedBy(Pattern.java:3773)

이메일쪽 마스킹 처리에 정규식을 \b(\S+)+@(\S+.\S+) 형태를 썼던 것..

https://regex101.com/ 에서 테스트 해보면 파멸의 백트래킹(catastrophic backtracking) 마크가 뜬다.

미리 테스트를 거쳐서 파멸하는 길을 막는 것이 좋다.