扣丁書屋

為什么你的網頁需要 CSP?

內容安全策略(CSP)是一個 HTTP Header,CSP 通過告訴瀏覽器一系列規則,嚴格規定頁面中哪些資源允許有哪些來源, 不在指定范圍內的統統拒絕。

內容安全策略(CSP)是一個 HTTP Header,CSP 通過告訴瀏覽器一系列規則,嚴格規定頁面中哪些資源允許有哪些來源, 不在指定范圍內的統統拒絕。

使用它是防止跨站點腳本(XSS)漏洞的最佳方法。由于難以使用 CSP 對現有網站進行改造(可通過漸進式的方法),因此 CSP 對于所有新網站都是強制性的,強烈建議對所有現有高風險站點進行 CSP 策略配置。

為什么要配置

CSP 的主要好處就是可以全面禁止使用不安全的嵌入式 JavaScript。內聯 JavaScript(無論是反射的還是存儲的),意味著不正確的轉義用戶輸入都可以被 Web 瀏覽器解釋為 JavaScript 代碼。通過使用 CSP 禁用嵌入式 JavaScript,你可以有效消除針對你站點的幾乎所有 XSS 攻擊。

注意,禁用內聯 JavaScript 意味著必須從 src 標記加載所有 JavaScript <script>。直接在標記上使用的事件處理程序(例如 onclick )將無法正常工作,<script>標記內的 JavaScript 也會通過。此外,使用 <style> 標簽或 style 屬性的內聯樣式表也將無法加載。因此為了讓 CSP 易于實現,在設計站點時必須非常小心。

如何配置?

開啟 CSP 很簡單, 你只需要配置你的網絡服務器返回 Content-Security-Policy 這個 HTTP Header (有時你會看到一些關于X-Content-Security-Policy Header 的提法, 那是舊版本,你無須再如此指定它)。

除此之外,<meta> 元素也可以被用來配置該策略, 例如

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">

指令

無論是 header ,還是在 <meta> 標簽中指定,其值的格式都是統一的,由一系列 CSP 指令(directive)組合而成。

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

這里 directive,即指令,是 CSP 規范中規定用以詳細詳述某種資源的來源,比如前面示例中使用的 script-src,指定腳本可以有哪些合法來源,img-src 則指定圖片的合法淶源,以下是常用指令:

  • base-uri 限制可出現在頁面 <base> 標簽中的鏈接。
  • child-src 列出可用于 worker 及以 frame 形式嵌入的鏈接。譬如: child-src https://youtube.com 表示只能從 Youtube 嵌入視頻資源。
  • connect-src 可發起連接的地址 (通過 XHR, WebSockets 或 EventSource)。
  • font-src 字體來源。譬如,要使用 Google web fonts 則需要添加 font-src https://themes.googleusercontent.com 規則。
  • form-action <form>標簽可提交的地址。
  • frame-ancestors 當前頁面可被哪些來源所嵌入(與 child-src 正好相反)。作用于 <frame>, <iframe>, <embed><applet>。該指令不能通過 <meta>指定且只對非 HTML文檔類型的資源生效。
  • frame-src 該指令已在 level 2 中廢棄但會在 level 3 中恢復使用。未指定的情況下回退到 tochild-src 指令。
  • img-src 指定圖片來源。
  • media-src 限制音視頻資源的來源。
  • object-src Flash 及其他插件的來源。
  • plugin-types 限制頁面中可加載的插件類型。
  • report-uri 指定一個可接收 CSP 報告的地址,瀏覽器會在相應指令不通過時發送報告。不能通過 <meta> 標簽來指定。
  • style-src 限制樣式文件的來源。
  • upgrade-insecure-requests 指導客戶端將頁面地址重寫,HTTP 轉 HTTPS。用于站點中有大量舊地址需要重定向的情形。
  • worker-src CSP Level 3 中的指令,規定可用于 worker, shared worker, 或 service worker 中的地址。

預設值

除了配置指定的淶源以外,這些指令還可以配置一些預定義的值來完成一些默認配置:

  • none 不匹配任何東西。
  • self 匹配當前域,但不包括子域。比如 example.com 可以,api.example.com 則會匹配失敗。
  • unsafe-inline 允許內嵌的腳本及樣式。是的,沒看錯,對于頁面中內嵌的內容也是有相應限制規則的。
  • unsafe-eval 允許通過字符串動態創建的腳本執行,比如 eval,setTimeout 等。

如果頁面中非得用內聯的寫法,還有種方式。即頁面中這些內聯的腳本或樣式標簽,賦值一個加密串,這個加密串由服務器生成,同時這個加密串被添加到頁面的響應頭里面。

<script nonce="EDNnf03nceIOfn39fn3e9h3sdfa">

  // 這里放置內聯在 HTML 中的代碼

</script> 

頁面 HTTP 響應頭的 Content-Security-Policy配置中包含相同的加密串:

Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'

配置示例

示例 1

所有內容均來自站點的同一個源 (不包括其子域名)

Content-Security-Policy: default-src 'self'

示例 2

允許內容來自信任的域名及其子域名 (域名不必須與CSP設置所在的域名相同)

Content-Security-Policy: default-src 'self' *.trusted.com

示例 3

允許網頁應用的用戶在他們自己的內容中包含來自任何源的圖片, 但是限制音頻或視頻需從信任的資源提供者(獲得),所有腳本必須從特定主機服務器獲取可信的代碼.

Content-Security-Policy: default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com

在這里,各種內容默認僅允許從文檔所在的源獲取, 但存在如下例外:

  • 圖片可以從任何地方加載(注意 "*" 通配符)。
  • 多媒體文件僅允許從 media1.com 和 media2.com 加載(不允許從這些站點的子域名)。
  • 可運行腳本僅允許來自于userscripts.example.com。

示例 4

一個線上銀行網站的管理者想要確保網站的所有內容都要通過SSL方式獲取,以避免攻擊者竊聽用戶發出的請求。

Content-Security-Policy: default-src https://onlinebanking.jumbobank.com

該服務器僅允許通過HTTPS方式并僅從onlinebanking.jumbobank.com域名來訪問文檔。

示例 5

一個在線郵箱的管理者想要允許在郵件里包含HTML,同樣圖片允許從任何地方加載,但不允許JavaScript或者其他潛在的危險內容(從任意位置加載)。

Content-Security-Policy: default-src 'self' *.mailsite.com; img-src *

注意這個示例并未指定script-src。在此CSP示例中,站點通過 default-src 指令的對其進行配置,這也同樣意味著腳本文件僅允許從原始服務器獲取。

上報你的數據

當檢測到非法資源時,除了控制臺看到的報錯信息,也可以讓瀏覽器將日志發送到服務器以供后續分析使用。接收報告的地址可在 Content-Security-Policy 響應頭中通過 report-uri指令來配置。當然,服務端需要編寫相應的服務來接收該數據。

配置 report-uri

Content-Security-Policy: default-src 'self'; ...; report-uri /my_amazing_csp_report_parser;`

服務端收到請求:

{
  "csp-report": {
    "document-uri": "http://example.org/page.html",
    "referrer": "http://evil.example.com/",
    "blocked-uri": "http://evil.example.com/evil.js",
    "violated-directive": "script-src 'self' https://apis.google.com",
    "original-policy": "script-src 'self' https://apis.google.com; report-uri http://example.org/my_amazing_csp_report_parser"
  }
}

Report Only

CSP 提供了一種報告模式,該模式下資源不會真的被限制加載,只會對檢測到的問題進行上報 ,以 JSON 數據的形式發送到 report-uri 指定的地方。

通過指定 Content-Security-Policy-Report-Only 而不是 Content-Security-Policy,則開啟了報告模式。

Content-Security-Policy-Report-Only: default-src 'self'; ...; report-uri /my_amazing_csp_report_parser;

當然,你也可以同時指定兩種響應頭,各自里的規則還會正常執行,不會互相影響。比如:

Content-Security-Policy: img-src *;

Content-Security-Policy-Report-Only: img-src ‘none’; report-uri http://reportcollector.example.com/collector.cgi

這里圖片還是會正常加載,但是 img-src ‘none’ 也會檢測到并且發送報告。

報告模式對于測試非常有用。在開啟 CSP 之前肯定需要對整站做全面的測試,將發現的問題及時修復后再真正開啟,比如上面提到的對內聯代碼的改造。

如何檢驗配置成功了?

在Network中可以看到配置成功的header:

下面是 Twitter 的一個配置示例,非常完善:

在控制臺可以看到資源 block 報錯:

Network中可以看到Block資源上報:

最多閱讀

為Electron程序添加運行時日志 3年以前  |  14868次閱讀
Node.js下通過配置host訪問URL 3年以前  |  4765次閱讀
js動態創建類和實例化 3年以前  |  3902次閱讀
wordpress標簽頁的制作 3年以前  |  3739次閱讀
初探 React 組件 3年以前  |  3712次閱讀
用 esbuild 讓你的構建壓縮性能翻倍 2年以前  |  3701次閱讀
500行PHP代碼搞定富文本安全過濾 3年以前  |  3606次閱讀
10 種跨域解決方案(附終極方案) 2年以前  |  3509次閱讀
22個HTML5的初級技巧 3年以前  |  3480次閱讀
MBTI免費在線測試 3年以前  |  3428次閱讀
使用 SRI 增強 localStorage 代碼安全 3年以前  |  3357次閱讀
淺談瀏覽器的原生拖拽事件 3年以前  |  3352次閱讀
CSS清除浮動 3年以前  |  3348次閱讀
第三版主題上線 3年以前  |  3285次閱讀
利用服務器返回header來傳輸數據 3年以前  |  3256次閱讀

手機掃碼閱讀
18禁止午夜福利体验区,人与动人物xxxx毛片人与狍,色男人窝网站聚色窝
<蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <文本链> <文本链> <文本链> <文本链> <文本链> <文本链>