본문 바로가기

Web hacking

CSP 알아보기

CSP의 탄생 

 

웹 브라우저는 웹 서버로부터 받는 페이지의 컨텐츠가 모두 의도된 컨텐츠인지 확인할 수 없다. XSS 공격의 경우, 페이지 내에 교묘하게 자바스크립트 구문을 삽입하여 마치 원래 페이지의 컨텐츠인 것처럼 브라우저를 속이고 동일 출처 정책을 우회한다. 이에 따라 페이지의 컨텐츠에서 사용하는 자원들이 모두 웹 서버에서 의도한 자원이 맞는지 확인하기 위해 Content Security Pollicy가 탄생했다. 

 

CSP란

 

CSP는 XSS와 데이터 주입 공격을 비롯한 특정 유형의 공격을 탐지하고 완화하는데 도움이 되는 추가 보안 계층이다.

하지만 CSP가 XSS등의 공격 피해를 완전히 무력화하기 위한 수단은 아니기에, XSS에 대한 자체적인 방어가 병행되어야 한다. 

 

CSP 적용

 

CSP 구문은 일반적으로 Content-Security-Policy HTTP 헤더에 추가하여 적용할 수 있다. 그 예시는 아래와 같다. 

 

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

 

위 정책은 페이지 내부의 자원들이 같은 오리진 혹은 https://example.dreamhack.io에서만 만 로드되어야 함을 의미한다.

 

 CSP 헤더는 HTTP 헤더 외에 meta 태그의 엘리먼트로도 정의할 수 있다. 위 CSP 정책을 meta 태그로 정의하면 아래와 같다. 

 

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

 

 

CSP 기본 정책 ( Inline Code, Eval )

 

CSP는 인라인 코드를 유해하다고 간주한다. 따라서 CSP를 사용 시 기본적으로 인라인 코드를 사용할 수 없다. 여기서 이야기하는 인라인 코드는 태그의 src 속성으로 코드를 로드하지 않고, 태그 내에 직접 코드를 삽입하는 것을 의미한다. 

 

예를 들어, <script>alert("Dreamhack")</script>는 <script> 내에 코드를 직접 삽입했기 때문에 인라인 코드이다.  CSP는 인라인 코드 형태를 지양하고, <script src="Dream.js"></script>와 같이 src 속성에 코드 경로를 정의하는 방식을 권장한다. 

 

CSP는 추가적으로 on* 이벤트 핸들러 속성, javascript: URL 스킴 또한 인라인 코드로 간주하고 허용하지 않는다.  또한 CSS 스타일 시트도 인라인 코드를 허용하지 않는다. style 속성과 style 태그 모두 외부 스타일시트로 통합하는 것을 권장한다. 

 

두번째로, CSP는 기본적으로 문자열 텍스트를 실행 가능한 자바스크립트 코드 형태로 변환하는 메커니즘 또한 유해하다고 간주한다. 대표적인 예가 eval 함수이다. eval과 같이 문자열로부터 코드를 실행하는 경우, 의도와 다르게 XSS 공격을 통해 삽입된 공격 코드로 변조되어 실행될 가능성이 있기 때문에 권장하지 않는다. 

 

eval, new Function( ), setTimeout(, ), setInterval(, )과 같이 문자열 형태로 입력을 받는 함수의 실행은 모두 차단된다. 다만, 해당 함수에 문자열 입력이 아닌 인라인 함수 형태로 파라미터가 전달된다면 차단되지 않는다. 

 

아래는 CSP 정책에 의해 차단되는 예제이다. 

 

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

 

아래는 CSP와 관계 없이 허용되는 예제이다. 

 

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

 

 

Policy Directive

 

<Policy-directive>는 <directive>  <value> 형태로 구성된다. <directive>는 지시문이라 부르며, 지시문은 컨텐츠 내에서 로드하는 리소스를 세분화해 어떤 리소스에 대한 출처를 제어할지 결정한다. <value> 부분에는 <directive>에서 정의한 리소스의 출처를 정의한다. <value>에는 여러 개의 출처가 정의될 수 있으며, 공백을 통해 구분된다. 

 

그림 1

 

다음으로 <value> 부분으로 올 수 있는 출처의 종류이다. 일반적으로 <value> 부분에는 URL을 전달 받으나 와일드카드의 사용, 특수한 목적의 출처도 존재한다. 

 

그림 2

 

 

 

참조

 

https://dreamhack.io/

 

https://developer.mozilla.org/ko/docs/Web/HTTP/CSP