드림핵 - WHA(Client Side)

Content Security Policy

김가윤 2023. 4. 13. 19:51

1. 서론

 

Content Security Policy(CSP)는

페이지의 컨텐츠에서

사용하는 자원들이 모두

웹 서버에서 의도한 자원이 맞는지

확인하기 위해 탄생


2. Content Security Policy

 

CSP는

XSS나 데이터를 삽입하는 류의

공격이 발생했을 때 피해를 줄이고

웹 관리자가 공격 시도를 보고 받을 수 있도록

새롭게 추가된 보안 계층

 

이러한 공격을 방지하기 위해

웹 페이지에 사용될 수 있는

자원의 위치, 출처 등에

제약을 걸 수 있다.

 

XSS 등 공격의 피해를

완전히 무력화하기 위한 수단은 아니기 때문에

XSS에 대한 자체적인 방어가 필요하다.

 

CSP 헤더는

1개 이상의 정책 지시문

세미콜론(;)으로 분리된 형태로 이루어져 있다.

 

정책 지시문은

지시문(default-src, script-src 등)

1개 이상의 출처('self', https:, *.dreamhack.io 등)

공백으로 분리된 형태로 지정

 

Figure 1. 같거나 특정 오리진을 명시한 CSP 구문

default-src 'self' https://example.dreamhack.io

-> 페이지 자원들이 같은 오리진 혹은 https://example.dreamhack.io에서만

로드되어야 함을 나타내는 예시

 

Figure 2. Content-Security-Policy 예시

Content-Security-Policy: <policy-directive>; <policy-directive>

 

Figure 3. Content-Security-Policy를 적용한 예시

Content-Security-Policy: default-src 'self' https://example.dreamhack.io

 

Figure 4. meta 태그로 정의한 모습

<meta http-equiv="Content-Security-Policy" content="default-src 'self' https://example.dreamhack.io">

HTTP 헤더 외에

meta 태그의 엘리먼트로도 정의가 가능하다.

 

CSP를 올바르게 정의하였는지 

검사하기 위해 구글은 CSP Evaluator를 제공한다.

https://csp-evaluator.withgoogle.com/

 

CSP Evaluator

 

csp-evaluator.withgoogle.com


1-1 CSP 기본 정책 - Inline Code

 

CSP는

인라인 코드(Inline Code)를

유해하다고 간주한다.

 

따라서 CSP를 사용할 때에는

기본적으로 인라인 코드를 사용할 수 없다.

 

인라인 코드란,

태그의 src 속성으로 코드를 로드하지 않고

태그 내에 직접 코드를 삽입하는 것을 의미

<script> alert(1) </script> -> 인라인 코드(지양)

<script src="alert.js"></script> -> 권장

 

<script> 태그 내에 코드 삽입,

on* 이벤트 핸들러 속성,

javascript: URL 스킴 또한

인라인 코드로 간주하고 허용되지 않는다.

 

CSS 스타일시트 또한

인라인 코드를 허용하지 않는다.

 

style 속성과 style 태그 모두

외부 스타일시트로 통합하는 것을 권장


1-2 CSP 기본 정책 - Eval

 

CSP는

문자열 텍스트를 실행 가능한

자바스크립트 코드 형태로 변환하는 매커니즘 또한

유해하다고 간주한다.

 

eval 함수와 같이

문자열로부터 코드를 실행하는 경우,

의도와 다르게 XSS 공격을 통해

삽입된 공격 코드로 변조되어

실행될 가능성이 있기 때문이다.

 

eval, new Function(), setTimeout([string], ...), setInterval([string], ...)과

같이 문자열 형태로 입력받는 함수의 실행은 모두 차단

 

다만,

함수에 문자열 입력이 아닌

인라인 함수 형태로 파라미터가 전달 될 때에는

차단되지 않는다.

차단
setTimeout("alert(1)", ...) 

허용
setTimeout(function(){alert(1)}, ...)

1-3 Policy Directive

 

<Policy-directive>

<directive> <value>로 구성

 

<directive>지시문이라고 부르며,

콘텐츠 내에서 로드하는 리소스세분화

어떤 리소스에 대한 출처를 제어할지 결정

지시문 설명
default-src -src로 끝나는 모든 리소스의 기본 동작을 제어한다.
만약 CSP 구문 내에서 지정하지 않은 지시문이 존재한다면
default-src의 정의를 따라간다.
img-src 이미지를 로드할 수 있는 출처를 제어한다.
script-src 스크립트 태그 관련 권한과 출처를 제어한다.
style-src 스타일시트 관련 권한과 출처를 제어한다.
child-src 페이지 내에 삽입된 프레임 콘텐츠에 대한 출처를 제어한다.
base-uri 페이지의 <base> 태그에 나타날 수 있는 URL을 제어한다.

 

<value>에서는

<directive>에서 정의한

리소스의 출처를 정의

 

<value>에는

여러 개의 출처가 정의될 수 있고,

공백을 통해 구분

출처 설명
*://example.com 출처의 shceme은 와일드카드를 이용해 표현할 수 있다.
https://*.example.com 출처의 호스트 서브도메인은 와일드카드를 이용해 표현할 수 있다. (단, 와일드카드는 호스트의 중간에 들어갈 수 없다)
-> https://www.*.com, https://*.example.*

또한 서브도메인을 와일드카드로 표현할 시, 서브도메인이 붙어있지 않은 도메인은 포함되지 않는다.
-> https://*.example.com으로 출처를 표기할 경우, https://example.com은 은 포함 안됨
https://example.com:* 출처의 포트는 와일드카드를 이용해 표현할 수 있다.
none 모든 출처를 허용하지 않는다.
self 페이지의 현재 출처 (Origin) 내에서 로드하는 리소스만 허용한다.
unsafe-inline 예외적으로 인라인 코드의 사용을 허용한다.
unsafe-eval 예외적으로 eval과 같은 텍스트-자바스크립트 변환 메커니즘의 사용을 허용한다.
nonce-<base64-value> nonce 속성을 설정하여 예외적으로 인라인 코드를 사용한다.
<base64-value>는 반드시 요청마다 다른 난수값으로 설정해야 한다. 해당 출처를 설정하면 unsafe-inline은 무시된다.
<hash-algorithm>-<base64-value> script 혹은 style 태그 내 코드의 해시를 표현한다.
해당 출처를 설정하면 unsafe-inline은 무시된다.

1-4 CSP Examples

Content-Security-Policy: default 'self'
모든 리소스의 출처를 현재 페이지와 같은 출처로 제한한다.

Content-Security-Policy: default 'self' https://googleapis.com https://*.googleapis.com
모든 리소스의 출처를 현재 페이지와 같은 출처와 https://googleapis.com, 
https://*.googleapis.com으로 제한한다.

Content-Security-Policy: default 'self'; img-src *; script-src static.dreamhack.io
모든 리소스의 출처를 현재 페이지와 같은 출처로 제한하고, 이미지의 출처는 모든 호스트를 허용한다.
또한 스크립트 태그의 출처는 static.dreamhack.io로 제한한다.

Content-Security-Policy: child-src 'self' frame.dreamhack.io
페이지 내에 삽입된 프레임 컨텐츠 URL은 frame.dreamhack.io 내의 컨텐츠만 로드할 수 있다.

Content-Security-Policy: base-uri 'none'
base 태그의 URL은 어느 것도 허용하지 않는다.

Content-Security-Policy: script-src 'unsafe-eval'
자바스크립트 코드 내에 eval과 같은 텍스트-자바스크립트 변환 메커니즘의 사용을 허용한다.

Content-Security-Policy: script-src 'unsafe-inline'
스크립트 태그 내 인라인 코드의 사용을 허용한다.

Content-Security-Policy: script-src 'nonce-YTQyYWZkODYtYWYyNy00ZGQzLTg2YjMtNzJhY2ZmOWY5OGNj'
스크립트 태그의 nonce 속성에 YTQyYWZkODYtYWYyNy00ZGQzLTg2YjMtNzJhY2ZmOWY5OGNj 값이 존재하지 않으면
스크립트 로드에 실패한다.

Content-Security-Policy: script-src 'sha256-5jFwrAK0UV47oFbVg/iCCBbxD8X1w+QvoOUepu4C2YA='
스크립트 태그 내의 코드 혹은 src 속성으로 지정된 파일의 sha256 해시를 base64로 인코딩한 결과가
5jFwrAK0UV47oFbVg/iCCBbxD8X1w+QvoOUepu4C2YA=와 다르다면 스크립트 로드에 실패한다.

'드림핵 - WHA(Client Side)' 카테고리의 다른 글

CORS Vulnerability  (0) 2023.04.17
CSRF Token 오용  (0) 2023.04.17
CSP Bypass  (0) 2023.04.13
XSS Filtering Bypass - II  (0) 2023.03.27
XSS Filtering Bypass - I  (0) 2023.03.27