프로그래밍 기초

콘텐츠 보안 정책(Content Security Policy, CSP)

hs-archive 2023. 6. 3. 23:19

콘텐츠 보안 정책(Content Security Policy, CSP)

Content Security Policy(CSP)는 웹 애플리케이션의 보안 강화를 위한 보안 정책 매커니즘입니다. CSP를 사용하면 웹 페이지의 리소스 로딩 및 실행에 대한 제한을 설정하여 악성 스크립트 실행을 방지하고 XSS(Cross-Site Scripting) 및 기타 웹 공격을 예방할 수 있습니다.

 

CSP는 비유를 통해 설명하자면, 웹 애플리케이션의 보안 경계를 구축하는 방벽이라고 할 수 있습니다. 이 방벽은 웹 페이지에 허용되는 리소스와 동작을 제한하고, 악성 요소의 침입을 방지합니다. 특정 사람들에게만 통행을 허용하는 보안 게이트나 출입 제한 장치라고 생각해도 좋습니다. CSP는 허용되지 않은 스크립트 실행을 막고, 허용된 스크립트만 실행되도록 제한을 설정함으로써 웹 페이지의 보안성을 강화합니다.

 

CSP의 "script-src"를 예로 들어 CSP의 동작을 보여드리겠습니다. 우선 아래와 같이 CSP 정책을 설정해 보겠습니다.

 

Content-Security-Policy: script-src 'self' example.com;

 

위의 정책은 example.com에서 로드된 스크립트만 실행을 허용하고, 다른 도메인에서 로드된 스크립트는 실행되지 않도록 제한합니다. 따라서 허용된 주소 이외의 주소에서 가져오는 스크립트는 파일에 아무리 작성하여도 실행되지 않습니다. 이는 아래와 같습니다.

 

<!-- 
    script-src를 통해 example.com을 허용했으므로, 
    example.com에서 가져온 아래 스크립트는 정상적으로 실행됩니다.
-->
<script src="example.com"></script>



<!-- 
    other.com은 script-src에 명시되지 않은 주소이므로, 
    other.com에서 가져온 아래 스크립트는 실행되지 않습니다.
-->
<script src="other.com"></script>

 

이렇게 CSP는 웹 애플리케이션의 보안을 강화하는 데 도움을 주는 중요한 도구입니다. 적절한 CSP 정책을 설정하면 웹 페이지의 취약성을 줄이고, 사용자 데이터의 안전성을 보장할 수 있습니다.

 

참고로 위 Content-Security-Policy: script-src 'self' example.com 에서 'self'는 현재 웹 페이지의 URL을 뜻합니다. 따라서, 위 정책에서 "self"란 현재 웹 페이지에서 로드된 스크립트를 허용한다는 의미입니다.

 

CSP에는 script-src 외에도 여러 정책이 존재하며 이를 적절히 활용하는 것이 보안에 도움이 됩니다.

 

엄격한 CSP 

앞서 언급한 것처럼, CSP는 XSS 공격을 방지하는 데 효과가 있습니다. 그러나 허용 목록 CSP는 XSS 방지 효과가 상대적으로 떨어지며, 엄격한 CSP가 실제로 XSS를 방지하고 애플리케이션을 보호하는 데 더욱 효과적입니다. 따라서, 엄격한 CSP를 사용하는 것이 권장됩니다.

 

허용 목록 CSP와 엄격한 CSP는 모두 같은 CSP입니다. 다만, 설정 방식에 약간의 차이가 있습니다. 

 

허용 목록 CSP (Allowlist CSP)

Content-Security-Policy: script-src 'self' trustedscripts.com;

위 CSP 설정은 스크립트 리소스를 현재 도메인('self')과 'trustdescripts.com'에서만 로드할 수 있도록 허용합니다. 다른 도메인의 스크립트는 실행이 차단됩니다.

 

엄격한 CSP (Strict CSP)

Content-Security-Policy: script-src 'nonce-{RANDOM_NONCE}' 'sha256-{RANDOM_HASH}';

위 CSP 설정은 임시값(nonce) 혹은 해시값(sha256)과 함께 작성된 스크립트만 실행되도록 합니다. script가 임시값 혹은 해시값과 함께 작성되지 않은 경우 해당 스크립트는 실행이 차단됩니다.

 

허용 목록 CSP보다 엄격한 CSP가 권장되는 이유

허용 목록 CSP는 도메인을 허용하는 방식이기 때문에 허용된 도메인이 해킹되었다면, 그 도메인으로부터 받아오는 스크립트 안에 있는 악성 스크립트를 모두 허용하게 됩니다. 하지만, 엄격한 CSP의 경우 상대 도메인이 해킹되었더라도 그 안에 있는 스크립트가 수행되기 위해서는 현재의 임시값이나 해시값과 함께 작성되어야 합니다. 하지만 임시값과 해시값은 매번 바뀌는 랜덤한 값이고 상대방은 해당 값을 알 수 없으므로 엄격한 CSP가 허용 목록 CSP보다 안전합니다.

 

게다가 엄격한 CSP는 RANDOM_NONCE 함수 혹은 RANDOM_HASH 함수를 한번 만들어 놓으면 script를 추가할 때마다 해당 값을 함께 넣기만 하면 되어서 항상 같은 구조를 갖추고 있는데, Allowlist CSP의 경우 허용 도메인이 추가될 때마다 도메인을 허용 리스트에 새로 추가해야 하므로 많은 사용자 정의가 요구됩니다.

 

엄격한 CSP 작성 예시

임시값 기반 엄격한 CSP를 아래와 같이 작성할 수 있습니다. 아래 정책의 경우 script-src는 nonce-{RANDOM}이거나 strict-dynamic인 것만 허용하고, object-src과 base-uri는 'none'으로 아무것도 허용하지 않는 정책입니다. 

Content-Security-Policy:
  script-src 'nonce-{RANDOM}' 'strict-dynamic';
  object-src 'none';
  base-uri 'none';

 

위와 동일한 정책을 해시 기반 엄격한 CSP로 작성할 수도 있습니다.

Content-Security-Policy:
  script-src 'sha256-{HASHED_INLINE_SCRIPT}' 'strict-dynamic';
  object-src 'none';
  base-uri 'none';

 

아래는 해당 정책의 실제 동작 예시입니다. 아래 사진을 보면 nonce-r4nd0m이 nonce 값으로 설정되어 있습니다. 따라서 <script nonce="r4nd0m" ... /> 와 같이 r4nd0m 값이들어간 script만 실행이 되고 다른 값이 들어간 스크립트는 실행되지 않는 모습을 확인할 수 있습니다. strict-dynamic은 이미 허용된 스크립트의 내부에서 동적으로 생성된 스크립트를 허용하는 옵션입니다.

CSP의 동작 예시

 

정리

CSP(Content Security Policy)는 웹 애플리케이션의 보안을 강화하는 정책 매커니즘입니다. CSP는 여러 정책 옵션을 제공하여 악성 스크립트 실행을 방지하고 여러 웹 공격을 예방할 수 있도록 도와줍니다. 엄격한 CSP는 XSS를 효과적으로 방지하며, 허용 목록 CSP보다 더 안전한 보호 기능을 제공합니다.

 

 

 

 

 


엄격한 CSP에 대해 더욱 자세히 알고 싶다면 다음을 참고해 주세요.

https://web.dev/strict-csp/

 

엄격한 CSP(콘텐츠 보안 정책)로 XSS(교차 사이트 스크립팅) 완화

교차 사이트 스크립팅에 대한 심층 방어로 스크립트 임시값 또는 해시를 기반으로 CSP를 배포하는 방법 대해 알아봅니다.

web.dev

 

CSP의 여러 정책 옵션에 대해 알고 싶다면 다음을 참고해 주세요.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/Sources

 

CSP source values - HTTP | MDN

HTTP Content-Security-Policy (CSP) header directives that specify a <source> from which resources may be loaded can use any one of the values listed below. Relevant directives include the fetch directives, along with others listed below.

developer.mozilla.org