[Back-end] SOP, CORS, CSP 개념과 우회방법(Concept, Bypass)

Geun·2022년 4월 14일
0

Back-end

목록 보기
55/74
post-custom-banner

SOP (Same-Origin Policy)

동일 출처 정책, SOP는 웹 클라이언트(브라우저)에서 다른 출처의 리소스간 상호작용을 방지하는 정책이다.
동일 출처에서 출처는 Scheme(프로토콜), Host, Port 3가지를 의미한다.

SOP는 간단히 말하면 다른 origin에서 온 자원을 제한하는 정책이다.
현대 브라우저에서 지원하는 하나의 기능으로서 Javascript, Documents, Media 등을 하나의 origin에서 다른 origin으로 통신을 하지 못하게 막는 정책이다.
이런 통신을 막는 이유는 보안상의 이슈로 CSRF같은 요청이 난무하지 않도록 하기 위해서이다.

교차 출처에 대한 접근은 세가지 유형이 있다.

  • 쓰기 : 링크, 리다이렉트, 양식 제출은 보통 허용한다.
  • 삽입 : <script scr=..>, <link href=...>, <img/video/object/iframe src=..> 등 문서에 포함되는 리소스이다. 보통 허용한다.
  • 읽기 : 보통 허용하지 않는다.

다른 도메인에 있는 리소스를 사용하는 경우

  • jsonp 방식을 사용한다. (우회하는 방식)
  • 브라우저를 기동할 때 특정 옵션을 주거나, 설정을 한다. (서비스 운영 관점에서는 불가능하다.)
  • 리소스를 요청할 서버에서 CORS 설정을 한다.

CORS (Cross-Origin Resource Sharing)

CORS는 SOP로 인한 제약사항을 완화해주는 역할을 한다.
다른 Origin임에도 리소스를 공유할 수있도록 돕는다.

CORS를 허용해줄 때에는 크게 2가지 요청이 왔을 때 반응을 정의한다.

1. Simple Request : GET, HEAD, POST같은 Method와 Content-Type 헤더의 값이 text/plain, application/x-www-form-urlencoded 또는 multipart/form-data 일때

2. Non Simple Request : GET, HEAD, POST Method가 아닌 요청과 위의 1번에서 언급하지 않는 Content-Type으로 요청이 들어왔을 때

Simple Request CORS

HTTP Request Method가 GET, HEAD, POST 중 하나이며, Content-Type 헤더의 값이 text/plain, application/x-www-form-urlencoded 또는 multipart/form-data이면 Simple Request이다.
Simple Request를 보낼 때는 Origin이 Header에 자동으로 추가되며 전송된다.

GET /tmp HTTP/1.1
Host: dyrandy.io
Origin: http://example.com
...

Server는 요청이 들어온 Origin과 Access-Control-Allow-Origin 헤더에서 허용하고 있는 Origin과 일치하는지 판별하고, 다르다면 즉시 연결을 종료시킨다.

HTTP/1.1 200 OK  
Access-Control-Allow-Origin: http://example.com  
Content-Type: application/json
...

위와 같은 Header가 추가되면 exaple.com이라는 Origin으로부터 오는 모든 요청들을 허용해준다는 뜻이다.

Non Simple Request CORS

Simple Request가 아닌 것들은 전부 Non Simple Request로 분류된다.
DELETE Method를 보낸다고 가정하자.
GET, HEAD, POST Method가 아니기 때문에 브라우저는 Preflight Request라는 것을 아래와 같이 Server에 보낸다.

OPTIONS /test HTTP/1.1
Origin: http://example.com
Access-Control-Request-Method: DELETE
...

Server는 이 Preflight Request가 허용되었는지 판단하고 응답을 보낸다.

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Methods: GET,DELETE,HEAD,OPTIONS
...

이렇게 하면 이제 DELETE Request를 보낼 수 있으며, Simple Request와 동일하게 Header에 Origin 정보가 적혀있게된다.

JSONP

CORS만 SOP를 완화하는 것은 아니다.
JSONP(JSON With Padding)도 있지만, JSONP는 Read만 할 때 사용할 수 있으며 복잡한 웹 구성에는 적합하지 않다.


CSP (Content Security Policy)

소스 허용 목록

동일 출처 정책(SOP)를 우회하는 공격법들이 생겨나 최신 브라우저에는 방어책이 몇 가지 있다.

Content-Security-Policy HTTP 헤더를 정의하고 브라우저에는 이런 소스에서 받은 리소스만 실행하거나 렌더링할 것을 지시한다.

만약 apis.google.com이 신뢰할만한 주소라면
Content-Security-Policy: script-src 'self' https://apis.google.com

script-src 스크립트의 추렃가 self(현재 위치) 또는 https://apis.google.com일 경우에만 스크립트 실행을 허용한다.
여기서 script-src는 리소스 지시문으로 어떤 리소스에 대한 제한 정책인지를 의미한다.

  • 다양한 리소스 지시문
    • font-src : 웹 폰트의 출처
    • img-src : 이미지의 출처
    • connect-src : 연결할 수 있는 출처 (xhr, web socket, evenet source)

인라인 코드는 유해한 것으로 간주된다 (eval 포함)

소스 허용 목록으로는 인라인 코드(html 파일에 태그로 감싸진 코드)와 주입된 악의적인 코드를 구분할 수가 없다.
이때문에 소스 허용 목록으로는 인라인 스크립트를 완전히 금지하고 js 파일을 따로 나누도록 권고하고 있다.

꼭 인라인 코드를 사용해야 한다면
암호화 난스를 사용하면 된다.

<script nonce=EDNnf03nceIOfn39fn3e9h3sdfa>
  //Some inline code I cant remove yet, but need to asap.
</script>
Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'

참고자료

https://w01fgang.tistory.com/147
https://herdin.github.io/2020/04/22/content-security-policy

post-custom-banner

0개의 댓글