algorithm

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

나모찾기 2019. 7. 17. 12:16

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) 마크가 뜬다.

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