콘텐츠 보안 정책은 어떻게 작동합니까?


248

개발자 콘솔에 많은 오류가 있습니다.

문자열을 평가하기 위해 거부

다음 콘텐츠 보안 정책 지침을 위반하여 인라인 스크립트 실행을 거부했습니다.

스크립트를로드하기 위해 거부

스타일 시트를로드하도록 거부

이게 다 뭐야? 콘텐츠 보안 정책은 어떻게 작동합니까? Content-Security-PolicyHTTP 헤더 는 어떻게 사용 합니까?

구체적으로 ...

  1. ... 여러 소스를 허용합니까?
  2. ... 다른 지시어를 사용합니까?
  3. ... 여러 지시문을 사용합니까?
  4. ... 핸들 포트?
  5. ... 다른 프로토콜을 처리합니까?
  6. ... file://프로토콜 허용 ?
  7. ... 인라인 스타일, 스크립트 및 태그를 사용 <style>하고 <script>?
  8. ... 허용 eval()?

그리고 마지막으로:

  1. 정확히 무엇을 'self'의미합니까?

답변:


557

Content-Security-Policy메타 태그를 사용하면 위험 줄일 수 있습니다 XSS의 자원이 다른 위치에서 데이터를로드에서 브라우저를 방지에서로드 할 수있는 사용자가 정의 할 수 있도록하여 공격을. 이로 인해 공격자가 사이트에 악성 코드를 삽입하기가 더 어려워집니다.

나는 왜 CSP 오류가 발생했는지 알아 내려고 벽돌 벽에 머리를 부딪쳤다. 어떻게 작동하는지에 대한 간결하고 명확한 지시는 없었습니다. 여기 CSP의 몇 가지 요점을 간략히 설명하려는 시도가 있습니다 . 주로 해결하기 어려운 부분에 집중합니다.

간결하게하기 위해 각 샘플에 전체 태그를 쓰지 않습니다. 대신 content속성 만 표시 하므로 샘플은 다음을 content="default-src 'self'"의미합니다.

<meta http-equiv="Content-Security-Policy" content="default-src 'self'">

1. 여러 소스를 허용하는 방법?

지시문 뒤에 소스를 공백으로 구분 된 목록으로 간단히 나열 할 수 있습니다.

content="default-src 'self' https://example.com/js/"

와 같은 특수 매개 변수 이외의 매개 변수에는 따옴표가 없습니다 'self'. 또한 :지시문 뒤에 콜론 ( ) 이 없습니다 . 지시문과 공백으로 구분 된 매개 변수 목록 만 있습니다.

지정된 매개 변수 아래의 모든 것은 암시 적으로 허용됩니다. 즉, 위 예제에서 유효한 소스가됩니다.

https://example.com/js/file.js
https://example.com/js/subdir/anotherfile.js

그러나 이들은 유효하지 않습니다.

http://example.com/js/file.js
^^^^ wrong protocol

https://example.com/file.js
                   ^^ above the specified path

2. 다른 지시어를 사용하는 방법은 무엇입니까?

가장 일반적인 지시문은 다음과 같습니다.

  • default-src 자바 스크립트, 이미지, CSS, 글꼴, AJAX 요청 등을로드하기위한 기본 정책
  • script-src 자바 스크립트 파일의 유효한 소스를 정의합니다
  • style-src CSS 파일의 유효한 소스를 정의합니다
  • img-src 이미지의 유효한 소스를 정의합니다
  • connect-srcAJAX (XMLHttpRequest), WebSockets 또는 EventSource에 대한 유효한 대상을 정의합니다. 여기에서 허용되지 않는 호스트에 연결을 시도하면 브라우저가 400오류 를 에뮬레이트합니다

다른 것들도 있지만 이것들은 가장 필요할 것입니다.

3. 여러 지시문을 사용하는 방법?

세미콜론 ( ;) 으로 종료하여 하나의 메타 태그 안에 모든 지시문을 정의합니다 .

content="default-src 'self' https://example.com/js/; style-src 'self'"

4. 포트를 처리하는 방법?

허용 된 도메인 뒤에 포트 번호 나 별표를 추가하여 기본 포트를 제외한 모든 것을 명시 적으로 허용해야합니다.

content="default-src 'self' https://ajax.googleapis.com http://example.com:123/free/stuff/"

위의 결과는 다음과 같습니다.

https://ajax.googleapis.com:123
                           ^^^^ Not ok, wrong port

https://ajax.googleapis.com - OK

http://example.com/free/stuff/file.js
                 ^^ Not ok, only the port 123 is allowed

http://example.com:123/free/stuff/file.js - OK

앞에서 언급했듯이 별표를 사용하여 모든 포트를 명시 적으로 허용 할 수도 있습니다.

content="default-src example.com:*"

5. 다른 프로토콜을 처리하는 방법?

기본적으로 표준 프로토콜 만 허용됩니다. 예를 들어 WebSocket을 허용 ws://하려면 명시 적으로 허용해야합니다.

content="default-src 'self'; connect-src ws:; style-src 'self'"
                                         ^^^ web sockets are now allowed on all domains and ports

6. 파일 프로토콜을 허용하는 방법 file://?

그렇게 정의하려고하면 작동하지 않습니다. 대신, 당신은 filesystem매개 변수 와 함께 그것을 허용합니다

content="default-src filesystem"

7. 인라인 스크립트와 스타일 정의를 사용하는 방법?

명시 적으로 허용되지 않으면 인라인 스타일 정의, <script>태그 내부의 코드 또는와 같은 태그 속성을 사용할 수 없습니다 onclick. 당신은 그들을 이렇게 허용합니다 :

content="script-src 'unsafe-inline'; style-src 'unsafe-inline'"

또한 인라인 base64로 인코딩 된 이미지를 명시 적으로 허용해야합니다.

content="img-src data:"

8. 허용하는 방법 eval()?

나는 많은 사람들이 당신이 그렇지 않다고 말할 것이라고 확신합니다. 그 사람들은 틀렸을 것입니다. 물론 eval을 사용하여 사이트 보안에 큰 구멍을 뚫을 수는 있지만 유효한 유스 케이스가 있습니다. 당신은 그것을 사용하는 것에 대해 현명해야합니다. 당신은 그렇게 허용합니다 :

content="script-src 'unsafe-eval'"

9. 정확히 무엇을 'self'의미합니까?

'self'localhost, 로컬 파일 시스템 또는 같은 호스트에있는 것을 의미 할 수 있습니다 . 그것은 어떤 것도 의미하지 않습니다. 콘텐츠 정책이 정의 된 파일과 동일한 체계 (프로토콜), 동일한 호스트 및 동일한 포트를 가진 소스를 의미합니다. HTTP를 통해 사이트를 서비스 하시겠습니까? 명시 적으로 정의하지 않으면 https가 없습니다.

필자는 'self'일반적으로 포함시키는 것이 합리적이므로 대부분의 예에서 사용 했지만 결코 필수는 아닙니다. 필요하지 않은 경우 그대로 두십시오.

그러나 잠시만 요! 그냥 사용 content="default-src *"하고 끝낼 수 없습니까?

아니요. 명백한 보안 취약점 외에도 예상대로 작동하지 않습니다. 일부 문서 에서는 모든 것을 허용한다고 주장 하지만 사실이 아닙니다. 인라인이나 회피를 허용하지 않으므로 실제로 사이트를 더 취약하게 만들려면 다음을 사용하십시오.

content="default-src * 'unsafe-inline' 'unsafe-eval'"

...하지만 당신이하지 않을 것을 믿습니다.

더 읽을 거리 :

http://content-security-policy.com

http://en.wikipedia.org/wiki/Content_Security_Policy


6
좋은 포스트. 한 가지 : 여러 지시문을 지정할 때 어떤 일이 발생하는지는 확실하지 않습니다. 예제 3의 style-src 설정이 default-src보다 우선합니까? etc.
track0

30
따라서 모든 콘텐츠의 모든 것을 허용 하려면default-src *; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'; img-src * data: 'unsafe-inline'; connect-src * 'unsafe-inline'; frame-src *;
Arnold Roa

8
content="default-src * 'unsafe-inline' 'unsafe-eval'"일부 Angular 응용 프로그램을 작동시키는 데 필요 하다는 것을 알아야합니다 .
flanger001

2
@Mahesh "블로그"는 SO에서 복사 한 게시물로 가득합니다. 너무 많은 SO 사용자가 알 수없는 블로거의 콘텐츠를 복사 할 것 같지 않습니다.
Schlaus

2
connect-src경로와 관련된 간단한 참고 사항 : 전체 하위 경로를 포함하려면 후행 슬래시가 필수입니다. 예 : http://foo.com/files/bar.txt소스가 http://foo.com/files인 경우 파일 이 차단 되지만 파일 이있을 때 http://foo.com/files/
제공됨

15

APACHE2 MOD_HEADERS

Apache2 mod_headers도 활성화 할 수 있습니다. Fedora에서는 Ubuntu / Debian을 사용하는 경우 기본적으로 이미 활성화되어 있습니다.

# First enable headers module for Apache2, 
# then restart the Apache2 service   
a2enmod headers
apache2 -k graceful

Ubuntu / Debian에서는 파일에서 헤더를 구성 할 수 있습니다 /etc/apache2/conf-enabled/security.conf

#
# Setting this header will prevent MSIE from interpreting files as something
# else than declared by the content type in the HTTP headers.
# Requires mod_headers to be enabled.
# 
#Header set X-Content-Type-Options: "nosniff"

#
# Setting this header will prevent other sites from embedding pages from this
# site as frames. This defends against clickjacking attacks.
# Requires mod_headers to be enabled.
#
Header always set X-Frame-Options: "sameorigin"
Header always set X-Content-Type-Options nosniff
Header always set X-XSS-Protection "1; mode=block"
Header always set X-Permitted-Cross-Domain-Policies "master-only"
Header always set Cache-Control "no-cache, no-store, must-revalidate"
Header always set Pragma "no-cache"
Header always set Expires "-1"
Header always set Content-Security-Policy: "default-src 'none';"
Header always set Content-Security-Policy: "script-src 'self' www.google-analytics.com adserver.example.com www.example.com;"
Header always set Content-Security-Policy: "style-src 'self' www.example.com;"

참고 : 이것은 파일의 맨 아래 부분이며 마지막 3 개 항목 만 CSP 설정입니다.

첫 번째 매개 변수는 지시문이고, 두 번째 매개 변수는 화이트리스트 할 소스입니다. Google 웹 로그 분석과 광고 서버를 추가했습니다. 또한 Apache2에 구성된 www.example.com 및 example.com과 같은 별칭이 있으면 화이트리스트에도 추가해야한다는 것을 알았습니다.

인라인 코드는 유해한 것으로 간주되므로 피해야합니다. 모든 자바 스크립트와 CSS를 복사하여 파일을 분리하고 화이트리스트에 추가합니다.

당신이 그것을 가지고있는 동안 당신은 다른 헤더 설정을보고 mod_security를 ​​설치할 수 있습니다

더 읽을 거리 :

https://developers.google.com/web/fundamentals/security/csp/

https://www.w3.org/TR/CSP/


2
공유 호스트에서 Apache 구성을 편집 할 수 없으므로 동일한 지시문을 .htaccess 파일에 추가 할 수있었습니다. report-uri.io/home/tools 에서 이러한 설정을 조정하기위한 훌륭한 도구를 찾았 습니다 .
마이클 맥기니스

Tomcat 7 로이 문제를 해결할 수있는 방법이 있습니까? 필터를 추가하려고 시도했지만 작동하지 않았습니다.
Elshan

0

font-src는 다른 것과 동일하게 작동하지만 다른 출처에서로드 한 글꼴을 사용하는 경우 메타 태그에 추가해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.