AWS 기술 블로그

AWS WAF의 지능형 위협 완화 기능을 사용하여 교차 출처 API 액세스 처리

이글은 AWS Security Blog에 게시된 Using AWS WAF intelligent threat mitigations with cross-origin API access by Kartik Bheemisetty and Achraf Souk 을 한국어로 번역 및 편집하였습니다.

AWS WAF는 봇 제어 및 사기 제어과 같이 원치 않는 웹 애플리케이션 트래픽을 필터링하는 고급 기능을 제공합니다.이러한 지능형 위협 완화에는 JavaScript 챌린지 또는 CAPTCHA를 사용한 클라이언트 측 심문 및 행동 분석과 같은 기술이 포함됩니다.

동시 출처 액세스가 가능한 웹 페이지에서 이러한 기술을 구현하는 것은 간단합니다. 교차 도메인 액세스가 필요한 경우, (예를들어 API가 웹 페이지와 다른 도메인에 노출되는 경우) AWS WAF의 지능형 위협 완화를 구성하려면 추가 단계가 필요합니다. 이 게시물에서는 단일 페이지 애플리케이션 (SPA) 예제를 사용하여 이러한 추가 단계에 대해 알아봅니다.

그림 1: 내 주소는 무엇입니까? 예제 단일 페이지 애플리케이션 (SPA)

먼저 API를 사용하여 최종 사용자의 국가 및 IP 정보를 표시하는 동일 출처 액세스 권한이 있는 SPA를 배포합니다. SPA는 AWS 서버리스 구성 요소 (예: Amazon CloudFront, Amazon Simple Storage Service (Amazon S3), Amazon API Gateway, and AWS Lambda) 를 사용하여 구축되며, API는 AWS WAF 봇 제어에 의해 보호됩니다.클라이언트 봇 제어에서 의심스러운 신호를 감지하면 해당API 를 API Gateway에 전달하기 전에 사용자가 CAPTCHA를 해결하도록 강제시킵니다.

다음으로 SPA를 변경하여 다른 도메인에서 API를 호스팅합니다. 봇 제어가 교차 출처 액세스를 통해 API를 보호하는 데 필요한 변경 사항에 대해 알아봅니다.

사용된 웹 개념에 대한 입문서

단일 페이지 애플리케이션 (SPA) 은 하나의 웹 페이지 내에서 작동합니다. SPA에서는HTML, CSS 및 JavaScript 파일이 초기에 페이지가 열리면서 한 번 로드됩니다. 후속 상호 작용 및 데이터 검색은 일반적으로 AJAX 또는 Fetch와 같은 API를 사용하여 서버에 대한 비동기 요청을 통해 처리됩니다. 다음으로 새 URL로 이동하지 않고도 검색된 데이터가 동적으로 렌더링되어 기존 페이지 구조에 삽입됩니다.

동일 출처 요청은 웹 페이지에서 웹 페이지 자체와 동일한 도메인에서 호스팅되는 API에 대한 HTTP 요청입니다. 교차 출처 요청은 한 도메인의 웹 페이지에서 다른 도메인에 호스팅된 API로 전송됩니다. 브라우저의 동일 출처 정책은 JavaScript 요청을 동일한 도메인, 프로토콜 및 포트로 제한합니다. 브라우저는 허용된 도메인을 지정하기 위한 간단한 요청에 Access-Control-Allow-Origin 헤더를 추가하는 것과 같은 CORS 기법을 사용하여 출처 간 통신을 활성화해야 합니다. CORS에 따라 요청이 간단하지 않은 경우 (예: 비공통 헤더가 있거나 JSON 데이터를 게시하는 경우) HTTP OPTIONS 동사를 사용하는 예비 요청을 API에 미리 전송하여 실제 요청을 허용하는지 확인해야 합니다.

시나리오 1: 동일 출처 액세스를 사용하는 SPA 예제

AWS 클라우드 개발 키트 (AWS CDK) 는 코드로 클라우드 인프라를 정의하고 AWS CloudFormation을 통해 프로비저닝하는데 사용되는 오픈 소스 소프트웨어 개발 프레임워크입니다. 명령줄에서 다음 단계에 따라 AWS CLI에 구성된 계정 정보를 사용하여 AWS CDK와 함께 SPA를 배포하십시오. CLI에서 구성된 AWS 리전을 us-east-1로 설정합니다.

git clone https://github.com/aws-samples/aws-waf-bot-control-api-protection-with-captcha.git
cd aws-waf-bot-control-api-protection-with-captcha 
npm install
npm run build 
cdk bootstrap
cdk deploy

AWS CDK 배포가 몇 분 내에 완료되면 다음과 같은 리소스가 생성됩니다:

그림 2: 동일 출처 API 액세스 아키텍처

그림 3: 시나리오 1 CDK 출력

SPA의 진입점은 CloudFront 배포이며, SPA 테스트를 위해 AWS CDK 출력에 도메인 이름 (YOURDISTRIBUTION.cloudfront.net) 이 표시되어 있습니다. 배포에는 두 개의 출처를 가리키는 두 가지 캐시 동작이 있습니다.

1.     캐싱을 비활성화한 첫 번째 캐시 동작인 CloudFront는 /api/ * 경로 패턴을 사용하여 모든 요청을 API Gateway의 리전 엔드포인트로 프록시합니다. 그러면 모든 API 호출에 대해 Lambda 함수가 트리거됩니다. Lambda는 특수한 헤더를 사용하여 CloudFront에서 전송한 최종 사용자 위치 및 IP 주소를 읽고 이를 JSON 응답으로 다시 보냅니다.

2.     캐싱이 활성화된 상태에서 두 번째 동작은 기본값입니다. 그러면 나머지 요청이 index.html 파일이 저장된 S3 버킷으로 라우팅됩니다. CloudFront가 정기적으로 최신 버전의 HTML 파일을 확인하도록 하기 위해 5초 캐시 TTL과 함께 업로드됩니다.

AWS WAF WebACL은 CloudFront 배포와 연결되어 있습니다. WebACL에는 지능형 위협 완화 기능의 이점을 활용할 수 있도록 표적 검사 수준으로 구성된 봇 제어 관리 규칙 그룹이 포함되어 있으며 SPA HTML에 포함된 봇 제어 SDK가 포함되어 있습니다.이 규칙 그룹의 비용을 최적화하기 위해 /api/ * API 요청으로 범위를 좁혔습니다. 참고로 이 샘플 WebACL에서는 지능형 위협 완화와 관련된 규칙만 구성됩니다. 프로덕션 시나리오의 경우 다양한 위협으로부터 API를 보호하기 위해 속도 제한 및 IP 평판과 같은 다른 규칙을 추가하는 것이 좋습니다.

합법적인 최종 사용자의 경우 SPA로 전달되는 요청 흐름은 다음과 같습니다.

1.     먼저 S3 버킷에서 index.html 파일을 다운로드하는 페이지로 이동합니다.

2.     페이지가 로드되면 봇 제어 SDK는 JavaScript 챌린지 (즉, 작업 증명) 를 다운로드하여 브라우저를 확인하고 의심스러운 속성 (예: 브라우저 자동화 프레임워크를 사용하는 경우) 을 수집한 다음 세션 토큰을 획득하여 SPA 도메인에 쿠키로 배치하여 세션 동작을 추적합니다.

3.     다음으로 “Lookup IP” 버튼을 클릭하면 봇 제어 SDK의 AwsWafIntegration Fetch 래퍼 라이브러리를 사용하여 API에 HTTP 요청을 보냅니다. 자세한 내용은 “통합 fetch 래퍼 사용 방법”을 참조하십시오. HTTP 요청은 세션 토큰이 포함된 쿠키와 함께 전송됩니다. 라이브러리는 HTTP 요청을 보내기 전에 토큰이 획득되었는지 확인합니다. 그렇지 않으면 WebACL의 요청 차단 (누락 포함) 또는 거부된 토큰 레이블 구성 규칙에 의해 차단될 수 있습니다.

그림 4: 유효한 토큰 없이 직접 API 요청을 차단하는 AWS WAF

4.     AWS WAF가 API 요청을 수신하면 봇 제어 규칙을 트리거합니다. 이 규칙은 요청을 API Gateway에 전달하거나 405 HTTP 오류 코드로 응답하여 의심스러운 신호가 감지되면 클라이언트 측 CAPTCHA 검증을 트리거합니다.

5.     CAPTCHA 확인이 필요한 경우 HTML 코드는 405 응답 코드를 감지하고 봇 제어 SDK를 사용하여 페이지에 보안 문자를 렌더링합니다. 자세한 내용은 “CAPTCHA 퍼즐을 렌더링하는 방법”을 참조하십시오. 이는 SPA 도메인 이름을 허용하는 API 키가 필요한 CAPTCHA API를 사용하여 수행됩니다. API 키는 AWS CDK 배포 중에 자동으로 생성되어 SPA HTML에 삽입됩니다.

AwsWafIntegration.fetch(apiURL).then(response => { 
    if (response.status == 405) { 
        showMyCaptcha(); 
        } 
        else { 
            response.json().then(myJson => { 
                renderResponse(myJson) }); 
            } 
        });

먼저 “Lookup IP” 버튼을 선택하여 합법적인 사용자 워크플로를 테스트합니다. CAPTCHA 워크플로를 테스트하려면 브라우저의 사용자 에이전트를 봇 제어에서 의심스러운 신호로 선택할 수 있는 임의의 값으로 변경해야 합니다. 요청 흐름을 이해하려면 브라우저에서 개발자 도구를 열고 네트워크 탭으로 이동한 다음 애플리케이션에 액세스합니다.

그림 5: SPA 페이지 로드의 HTTP 요청 흐름과 CAPTCHA 워크플로를 트리거한 선택 항목을 보여주는 브라우저 개발자 도구

그림 6: 요청이 SignalNonBrowserUserAgent 규칙과 일치할 때 CAPTCHA를 트리거하는 AWS WAF

시나리오 2: 교차 출처 액세스를 사용하는 SPA 예제

다음 명령어를 실행하여 교차 출처 API 액세스 시나리오로 아키텍처를 업데이트합니다:

cdk deploy -c CROSS_DOMAIN_ENABLED=true

아키텍처는 다음 다이어그램에 설명된 대로 몇 분 내에 업데이트됩니다:

그림 7: 교차 출처 API 액세스 아키텍처

그림 8: 시나리오 2 CDK 출력

이 아키텍처에서는 API가 AWS CDK 출력에서 찾을 수 있는 다른 도메인 이름을 가진 별도의 CloudFront 배포에서 제공됩니다.브라우저에서 직접 이 API에 액세스하는 경우, Block-Requests-With-Missing-Or-Rejected-Token-Label 구성 규칙 덕분에 AWS WAF에 의해 차단됩니다.

이전 섹션과 동일한 테스트를 수행하여 교차 출처 API 액세스 시나리오에서 봇 제어를 사용하여 API가 보호되는지 확인할 수 있습니다.제대로 작동하도록 하기 위해 AWS CDK에서 AWS WAF WebACL, CloudFront 및 API Gateway의 구성을 수정했습니다.

첫째, WebACL의 구성된 토큰 도메인 목록이 SPA의 도메인 이름을 포함하도록 수정됩니다. 기본적으로 AWS WAF는 웹 ACL과 연결된 리소스의 호스트 도메인과 정확히 일치하는 도메인 설정을 가진 토큰만 허용합니다. 동일 출처 API 액세스 시나리오의 경우도 마찬가지였습니다. 새 아키텍처에서는 WebACL이 API CloudFront 배포에 연결됩니다. 따라서 WebACL의 토큰 도메인 목록에서 SPA CloudFront 배포의 도메인 이름을 명시적으로 허용해야 합니다. 자세한 내용은 “토큰 도메인 및 도메인 목록”을 참조하십시오.참고로 CAPTCHA API 키는 초기 SPA 도메인 이름으로 생성되었으므로 변경되지 않습니다.

둘째, AwsWafIntegration 라이브러리는 출처 간 가져오기를 감지하고 특수 헤더 X-Aws-Waf-Token에 토큰을 자동으로 전송합니다. 도메인 간에 쿠키를 전송할 수 없기 때문입니다. 이 토큰은 이제 일반적이지 않은 HTTP 헤더에 전달되므로 HTTP OPTIONS를 사용하여 예비 요청을 가능하게 하는 적절한 CORS로 API가 구성됩니다. 변경은 API의 여러 위치에서 수행됩니다.

  1. HTTP OPTIONS 메서드를 허용하도록 API CloudFront 배포가 업데이트되었습니다.
  2. API CloudFront 배포는 다음과 같은 CORS 헤더를 추가하는 헤더 응답 정책으로 구성됩니다.
    • Access-Control-Allow-Origin: <SPA의 도메인 이름>
    • Access-Control-Allow-Methods: GET, OPTIONS
    • Access-Control-Allow-Headers: X-Aws-Waf-Token
    • Access-Control-Max-Age: 600
    • Access-Control-Allow-Credentials: false
  3. API Gateway는 CORS 예비 요청 OPTIONS에 응답하도록 구성되었습니다.
  4. AWS WAF WebACL은 CORS 예비 요청 OPTIONS이봇 제어 규칙 그룹 및 Block-Requests-With-Missing-Or-Rejected-Token-Label 규칙 검사에서 제외하도록 구성되어 있습니다.

교차 출처 액세스 시나리오를 테스트하려면 아키텍처를 업데이트한 후 얻은 AWS CDK 출력의 “SPAURL”을 사용하여 URL에 액세스합니다.시나리오 1과 마찬가지로 CAPTCHA 워크플로를 테스트하려면 브라우저의 사용자 에이전트를 봇 제어에서 의심스러운 신호로 선택한 임의의 값으로 변경해야 합니다. 요청 흐름을 이해하려면 브라우저에서 개발자 도구를 열고 네트워크 탭으로 이동한 다음 애플리케이션에 액세스합니다.

그림 9: 교차 출처 API 요청에 대한 SPA 페이지 로드의 HTTP 요청 흐름 및 CAPTCHA 워크플로를 트리거한 선택 항목을 보여주는 브라우저 개발자 도구

그림 10: CAPTCHA가 해결된 후 교차 출처 API에 대한 HTTP 요청을 보여주는 브라우저 개발자 도구

그림 11: 요청이 SignalonBrowserUserAgent규칙과 일치할 때 CAPTCHA를 트리거한 교차 출처 요청에 대한 AWS WAF 샘플 로그 항목

리소스 정리

AWS CDK에서 생성한 리소스를 제거하려면 다음 명령을 실행합니다:

cdk destroy

결론

이 게시물에서는 동일 출처 및 교차 출처 액세스 시나리오 모두에서 API를 보호하기 위해 단일 페이지 애플리케이션 (SPA) 에서 CAPTCHA API와 함께 AWS WAF 봇 제어 규칙 그룹을 구현하는 방법을 배웠습니다.

AWS WAF를 사용한 지능형 위협 완화에 대해 자세히 알아보려면 이 설명서 페이지를 참조하십시오.

Jaebo Kim

Jaebo Kim

김재보 솔루션즈 아키텍트는 금융 고객을 대상으로 클라우드 마이그레이션을 제안하고 고객과 함께 최적의 아키텍처를 만드는 작업을 지원하는 역할을 하고 있습니다.