AWS WAF Not Statement 규칙의 이해

JIPA
11 min readJan 29, 2022

--

제가 참여하고 있는 커뮤니티에서 “우아한 형제들”에서 진행한 아래의 동영상을 본 후 문의사항이 하나 있었는데요. 이 문의 사항이 다른 분들도 충분히 궁금해하실 수 있는 내용인 것 같아 포스팅합니다.

먼저, 훌륭한 컨텐츠를 제공해주신 발표자분께 감사를 드리며 질문하신 분이 궁금해 하는 내용을 살펴보도록 하겠습니다. 동영상의 뒷부분에서 언급된 내용 중 일부분을 보면 AWS WAF Classic 에서 AWS New WAF 로 규칙을 Migration 하는 과정에서 뜻밖의 예상하지 못한 규칙의 동작을 확인하게 되었고 이를 해결했던 사례에 대한 것이었는데요.

예상외의 결과가 나타난 AWS WAF 설정

질문자가 궁금해했던 시나리오는 다음과 같습니다.

  1. AWS WAF Classic 에서 사용했던 규칙이 아래의 그림과 같은 상황이었습니다.
WAF Classic 의 규칙

이 규칙의 목적은 Host Header 에 example1. 이나 example2.com 을 포함하지 않는 Host 정보가 있다면 규칙을 위반하는 것으로 판단하고 차단하겠다는 것인데요. 예를 들면 AWS WAF 로 example.com, www.example2.com 과 같이 example1. 과 example2. 를 포함하지 않는 Host 요청에 대해서는 차단하겠다는 겁니다.

2. AWS new WAF 로 이 규칙을 Migration 했고 첫번째 시행착오(?)를 겪은 후 new WAF 에서 제공하는 “OR Statement” 와 “Negate Statement” 옵션을 이용하여 아래와 같이 “Host” Header 값이 “example1.” 을 포함하지 않거나 “example2.” 을 포함하지 않으면 차단되도록 구성하였습니다.

New WAF 의 규칙

3. 위와 같이 AWS New WAF 에서 “OR Statement” 와 “Negate Statement” 옵션을 이용하여 “example1.” 과 “example2.” 을 포함하지 않는 요청에 대해서는 차단하도록 구성을 하였는데 실제로 규칙을 적용해보니 “www.exampl1.com” 이나 “www.example2.com” 과 같은 모든 정상 트래픽들도 차단이 되었습니다.

4. 그래서 이 문제를 해결하기 위한 방안으로 String Match 가 아닌 정규 표현식을 사용하였습니다.

의문점. 무엇이 문제인가?

이 과정에서 질문하신 분이 궁금했던 부분은 New WAF 에서 “OR Statement” 와 “Negate Statement” 옵션을 이용해서 규칙을 생성했는데 왜 정상적인 트래픽들조차 차단이 되었고 왜 정규표현식을 사용할 수 밖에 없었는가? 이것은 AWS New WAF 의 Bug 인가? 인데요.

결론을 먼저 말씀드리면 이건 AWS New WAF 의 Bug 가 아니라 설정한대로 잘 동작을 한 것입니다.

그럼 이해를 돕기 위해 WAF Classic 의 내용과 New WAF 의 규칙을 한 번 살펴보도록 하겠습니다.

AWS WAF Classic 규칙 분석

먼저, WAF 관리자의 목적을 정리하겠습니다.

규칙의 목적 : Request 의 Host Header 에 example1. 이나 example2. 이 포함되어 있지 않은 요청은 모두 차단한다.

WAF Classic 의 규칙 설명

WAF Classic 의 규칙

위 그림의 WAF Classic 규칙을 보면 이렇게 동작하도록 설정되어 있습니다.

Filter 부분을 보면 “Request Header 의 “Host” 값이 “example1.” 을 포함하고 있지 않거나 “example2.” 을 포함하고 있지 않으면 매칭한다.”

그리고 이런 문구가 또 있습니다.

When a request does not match at least one of the filters in the string match condition”

즉, Filter 에 있는 두 가지 조건 중 하나라도 매칭되지 않은 경우 조건을 매칭하는 것으로 판단한다.

그리고 관리자는 이 규칙의 Action 을 아마 다음과 같이 Block 으로 설정하였을 것입니다.

WAF Classic 의 규칙 액션

이 상황에서 여러가지 요청이 유입되었을 때 AWS WAF Classic 은 어떻게 동작하게될지 살펴보겠습니다.

  1. www.example1.com = Host 에 example1. 이 포함되어 있으므로 Filter 의 조건 중 1개는 만족을 합니다. 즉, Condition 은 만족할 수 없습니다. 왜냐하면 Condition 을 만족하려면 Filter 에 만족하는 조건이 하나도 없어야 하니까요. 따라서, 결과적으로 이 요청은 차단되지 않습니다.
  2. www.example2.com = Host 에 example2. 이 포함되어 있으므로 Filter 의 조건 중 1개는 만족을 합니다. 즉, Condition 은 만족할 수 없습니다. 왜냐하면 Condition 을 만족하려면 Filter 에 만족하는 조건이 하나도 없어야 하니까요. 따라서, 결과적으로 이 요청은 차단되지 않습니다.
  3. www.example.com = Host 의 값이 어떤 Filter 도 만족하지 않습니다. 즉, Condition 을 만족할 수 있는 조건이 되었습니다. 따라서, 이 요청은 차단됩니다.
  4. www.example3.com = Host 의 값이 어떤 Filter 도 만족하지 않습니다. 즉, Condition 을 만족할 수 있는 조건이 되었습니다. 따라서, 이 요청은 차단됩니다.

설명드린 바와 같이 이 규칙의 내용을 살펴보면 관리자가 의도했던대로 잘 동작하는 구조임을 알 수 있습니다.

AWS New WAF 규칙 분석

그럼 이번에는 New WAF 에서 사용했던 규칙을 살펴보도록 하겠습니다.

New WAF 의 규칙

참고. 이 화면에는 보이지 않지만 관리자는 이 규칙의 Action 도 Block 으로 구성하였을 것입니다.

New WAF 의 설정된 규칙을 살펴보면 내용은 다음과 같습니다.

NOT Statement1 = Request Header 의 Host 값이 example1. 을 포함하고 있지 않으면 매칭된다.

혹은

NOT Statement2 = Request Header 의 Host 값이 example2. 을 포함하고 있지 않으면 매칭된다.

따라서, 이 규칙의 Action 이 Block 이라면 이 규칙의 내용을 말로 풀어서 설명하면

“사용자가 요청한 Request 의 Host Header 가 exampl1. 을 포함하고 있지 않거나 example2. 를 포함하고 있지 않으면 차단한다.”

입니다.

여기까지만 들으면 마치 New WAF 의 이 규칙도 WAF Classic 에서 사용했던 규칙과 동일하게 동작할 것만 같은 느낌인데요. 사실 그럴까요?

WAF Classic 의 경우처럼 몇 가지 상황을 예를 들어 적용해보도록 하겠습니다.

  1. www.example1.com = Host 에 example1. 이 포함되어 있으므로 두 가지 “Not Statement” 중 첫번째는 매칭되지 않습니다. 하지만 “example2.” 를 포함하고 있는 것은 아니므로 두번째 “Not Statement” 는 매칭되게 됩니다. 그리고 이 규칙은 두 가지 “Not Statement” 중 하나라도 매칭되면 차단될 수 있도록 “OR” 조건을 사용하였습니다. 따라서, 결과적으로 이 요청은 차단됩니다.
  2. www.example2.com = Host 에 example2. 이 포함되어 있으므로 두 가지 “Not Statement” 중 두번째는 매칭되지 않습니다. 하지만 “example1.” 를 포함하고 있는 것은 아니므로 첫번째 “Not Statement” 는 매칭되게 됩니다. 따라서, 이 요청은 차단됩니다.
  3. www.example.com = Host 의 값이 두 가지 “Not Statement” 를 모두 만족합니다. 따라서, 이 요청은 차단됩니다.
  4. www.example3.com = Host 의 값이 두 가지 “Not Statement” 를 모두 만족합니다. 따라서, 이 요청은 차단됩니다.

보시는 바와 같이 이번에는 어떤 요청을 하더라도 모두 차단되는 결과가 나오는 것을 확인할 수 있습니다.

왜 그런걸까요?

아마 여기까지 읽으셨다면 모두 이해하셨겠지만 이 예제에 있는 규칙은 일반적으로 만족할 수 없는 상반된 규칙을 OR 조건으로 구성을 하였기때문입니다.

즉, Host Header 에 example1. 이 없어도 차단하고 example2. 가 없어도 차단한다는 의미와 같기 때문에 example1. 이 포함된 경우에는 example2. 가 없다는 이유로 차단되고 example2. 가 포함된 경우에는 example1. 이 없다는 이유로 차단이 되어버린 것입니다.

따라서, 이 규칙은 얼핏 보기에는 Bug 처럼 보일 수도 있지만 설정된 규칙에 따라 잘 동작한 것임을 알 수 있습니다.

AWS New WAF 에서의 규칙 적용 방법

그렇다면 New WAF 에서는 어떻게 규칙을 구성해야 WAF Classic 에서 사용하던 규칙을 구현할 수 있을까요?

동영상의 예시처럼 정규 표현식을 사용하는 것도 하나의 방법입니다.

즉 “|” 옵션을 정규 표현식에 사용하여 “|” 로 구분되는 String 값을 “OR” 로 선택되도록 하는 방법입니다.

또다른 방법은 여러개의 “Not Statement” 규칙을 위의 예와 같이 “OR” 로 묶지 않고 별도의 규칙으로 구분해서 생성하는 방법입니다.

아래와 같이 “Not Statement” 를 갖는 규칙을 별도로 구분하여 작성하는 것입니다.

분리된 New WAF 규칙1
분리된 New WAF 규칙2

Not Statement + OR 의 활용방법

어떤 분은 이런 궁금증이 생기실 수도 있을 것 같습니다.

“그럼 “Not Statement” 를 “OR” 조건으로 묶어서 사용하는 경우는 어떤 경우인가?”

이런 경우를 생각해볼 수 있을 것 같습니다.

example.com 으로 접속하는 모든 사용자 요청은 User-Agent 로 Chrome 을 사용하여야 하고 WAF 에서는 example. 을 포함하지 않는 Host 에 대한 요청은 차단하여야 한다.

이런 요구 사항이라면 두 개의 “Not statement” 를 “OR” 로 조합하여 구성하여 만족할 수 있겠죠.

Not Statement 1 = Host 에 example. 이 포함되어 있지 않은 경우 매칭

OR

Not Statement 2= User-Agent 에 Chrome 이 포함되어 있지 않은 경우 매칭

Action = Block

이렇게 구성되어 있다면 다음과 같은 시나리오가 될 겁니다.

www.example.com (Chrome) = Not Statement 1매칭 안됨, Not Statement 2 매칭 안됨. 따라서, 허용

www.example1.com (Chrome) = Not Statement 1매칭됨, Not Statement 2 매칭 안됨. 따라서, 차단

www.example.com (Safari) = Not Statement 1매칭 안됨, Not Statement 2 매칭 됨. 따라서, 차단

www.example1.com (Safari) = Not Statement 1매칭됨, Not Statement 2 매칭 됨. 따라서, 차단

보시는 바와 같이 Not Statement 2개를 OR 로 구성하였을 경우 기대했던 대로 동작할 수 있는 것을 확인할 수 있습니다.

위 동영상에서도 언급되었지만 WAF 에서의 규칙 적용은 조심스러운 작업일 수 밖에 없습니다. 따라서, 새로운 규칙을 적용할 때에는 Sandbox 환경이나 별도의 테스트 환경에서 해당 규칙을 검증한 후 적용하거나 Count Mode 로 적용하여 새로운 규칙으로 인한 영향도를 파악한 후에 Block Mode 로 전환하는 것을 추천드립니다.

감사합니다.

--

--

JIPA
JIPA

Written by JIPA

Always Day 1. Security is job zero.

No responses yet