簡體   English   中英

內容安全策略 (CSP) 如何工作?

[英]How does Content Security Policy (CSP) work?

我在開發者控制台中收到一堆錯誤:

拒絕評估字符串

拒絕執行內聯腳本,因為它違反了以下內容安全策略指令

拒絕加載腳本

拒絕加載樣式表

這是怎么回事? 內容安全策略 (CSP) 如何工作? 如何使用Content-Security-Policy HTTP 標頭?

具體來說,如何...

  1. ...允許多個來源?
  2. ...使用不同的指令?
  3. ...使用多個指令?
  4. ...處理端口?
  5. ...處理不同的協議?
  6. ...允許file://協議?
  7. ...使用內聯樣式、腳本和標簽<style><script>
  8. ...允許eval()

最后:

  1. 'self'究竟是什么意思?

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加載 javascript、圖像、CSS、字體、AJAX 請求等的默認策略
  • script-src定義 javascript 文件的有效來源
  • style-src定義了 css 文件的有效來源
  • img-src定義圖像的有效來源
  • connect-src定義了 XMLHttpRequest (AJAX)、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. 如何處理不同的協議?

默認情況下,只允許標准協議。 例如,要允許 WebSockets 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 是邪惡的”,而且是世界末日即將來臨的最有可能的原因。 那些人會錯的。 當然,您絕對可以使用 eval 在您站點的安全性中打出重大漏洞,但它具有完全有效的用例。 你只需要聰明地使用它。 你允許它像這樣:

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

9. 'self'究竟是什么意思?

您可能將'self'視為本地主機、本地文件系統或同一主機上的任何內容。 這並不意味着其中任何一個。 這意味着與定義內容策略的文件具有相同方案(協議)、相同主機和相同端口的源。通過 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

Apache 2 mod_headers

您還可以啟用 Apache 2 mod_headers。 Fedora 上它已經默認啟用。 如果您使用 Ubuntu/Debian,請像這樣啟用它:

# First enable headers module for Apache 2,
# and 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;"

注意:這是文件的底部。 只有最后三個條目是 CSP 設置。

第一個參數是指令,第二個參數是要列入白名單的來源。 我已經添加了谷歌分析和廣告服務器,你可能有。 此外,我發現如果您有別名,例如在 Apache 2 中配置的www.example.com和 example.com,您也應該將它們添加到白名單中。

內聯代碼被認為是有害的,你應該避免它。 將所有 JavaScript 代碼和 CSS 復制到單獨的文件中,並將它們添加到白名單中。

當您使用它時,您可以查看其他標頭設置並安裝 mod_security

進一步閱讀:

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM