安全 - 內容安全策略(CSP)(未完)


威脅

跨站腳本攻擊(Cross-site scripting)

  • 跨站腳本攻擊Cross-site scripting (XSS)是一種安全漏洞,攻擊者可以利用這種漏洞在網站上注入惡意的客戶端代碼。
  • 攻擊者可以突破網站的訪問權限,冒充受害者
  • 以下2種情況下,容易發生XSS攻擊:
    • 從一個不可靠的鏈接進入到一個web應用程序。
    • 沒有過濾掉惡意代碼的動態內容被發送給web用戶。(可以上傳動態內容得接口沒有過濾惡意代碼)
  • 惡意內容一般包括 JavaScript,但是,有時候也會包括HTML,FLASH。

XSS攻擊可以分為3類:存儲型(持久型)、反射型(非持久型)、基於DOM。

存儲型XSS

  • 注入型腳本永久存儲在目標服務器上。當瀏覽器請求數據時,腳本從服務器上傳回並執行。(當前網站支持上傳數據,但是對數據得內容沒有進行過濾。)
  • 例如:上傳一個圖片,但是圖片得實際路徑指向一個腳本的url,由於腳本url在未設置CSP時支持跨域,當該圖片被其他用戶加載時就加載運行了該腳本。當前網站的個人信息就會被該腳本以合法的方式獲取

反射型XSS(非持久性XSS)

  • 當用戶點擊一個惡意鏈接,或者提交一個表單,或者進入一個惡意網站時,注入腳本進入被攻擊者的網站
  • Web服務器將注入腳本,比如一個錯誤信息,搜索結果等 返回到用戶的瀏覽器上。
  • 這種方式是利用某些特別的接口,這些接口返回的數據和提交的內容相關,但又未對提交的內容進行過濾。導致服務器返回的內容把惡意代碼注入到了客戶端瀏覽器中。
  • 例如:在舊版的瀏覽器中,input的值會寫入value屬性中<input value='默認值可以修改' type='text'></input>,如果某個返回的數據如下就會向客戶端瀏覽器注入惡意代碼
返回value值為 '/><script>...dosome...</script><input  value='
這時渲染的input標簽會變為 <input value=''/><script>...dosome...</script><input  value='' type='text'></input>
JS代碼就會被注入執行了

基於DOM的XSS(本地利用漏洞,這種漏洞存在於頁面中客戶端腳本自身。)

  • 瀏覽器自身有安全漏洞,用戶訪問了惡意網站,這些具有針對這些漏洞進行攻擊的腳本就會利用這些漏洞繞過瀏覽器安全機制獲取信息
  • 這種攻擊危害較小,只針對瀏覽器版本沒有及時更新且訪問了惡意網站的用戶

—————————————————

數據包嗅探攻擊

  • 除限制可以加載內容的域,服務器還可指明哪種協議允許使用;比如 (從理想化的安全角度來說),服務器可指定所有內容必須通過HTTPS加載。
  • 一個完整的數據安全
    • 傳輸策略強制使用HTTPS進行數據傳輸
    • 所有的cookie標記安全標識
    • 提供自動的重定向使得HTTP頁面導向HTTPS版本。
  • 網站也可以使用 Strict-Transport-Security HTTP頭部確保連接它的瀏覽器只使用加密通道。

———————————————————————————————————————

使用 CSP

  • 內容安全策略 (CSP) 是一個額外的安全層,用於檢測並削弱某些特定類型的攻擊,包括跨站腳本 (XSS) 和數據注入攻擊等。
  • CSP2 在向后兼容有明確提及的不一致
  • 為使CSP可用, 你需要配置你的網絡服務器返回 Content-Security-Policy HTTP頭部
  • X-Content-Security-Policy頭部的提法, 那是舊版本,你無須再如此指定它
  • 除此之外, <meta> 元素也可以被用來配置該策略, 例如<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
  • Content-Security-Policy 某些指令源需要配合標簽屬性使用,例如:nonce
  • CSP通過指定有效域——即瀏覽器認可的可執行腳本的有效來源——使服務器管理者有能力減少或消除XSS攻擊所依賴的載體。
  • 一個CSP兼容的瀏覽器將會僅執行從白名單域獲取到的腳本文件,忽略所有的其他腳本 (包括內聯腳本和HTML的事件處理屬性)。

制定策略

  • policy參數是一個包含了各種描述你的CSP策略指令的字符串。
Content-Security-Policy: policy

描述策略

  • 一個策略由一系列策略指令所組成,每個策略指令都描述了一個針對某個特定類型資源以及生效范圍的策略。
  • 你的策略應當包含一個default-src策略指令,在其他資源類型沒有符合自己的策略時應用該策略
  • 一個策略可以包含 default-src 或者 script-src 指令來防止內聯腳本運行, 並杜絕eval()的使用。
  • 一個策略也可包含一個 default-src 或 style-src 指令去限制來自一個 <style> 元素或者style屬性的內聯樣式。

對策略進行測試

  • 為降低部署成本,CSP可以部署為報告(report-only)模式
  • 在此模式下,CSP策略不是強制性的,但是任何違規行為將會報告給一個指定的URI地址。
  • 一個報告模式的頭部可以用來測試一個修訂后的未來將應用的策略而不用實際部署它。
  • 用Content-Security-Policy-Report-Only HTTP 頭部來指定你的策略
  • 如果Content-Security-Policy-Report-Only 頭部和 Content-Security-Policy 同時出現在一個響應中,兩個策略均有效
    • 在Content-Security-Policy 頭部中指定的策略有強制性 ,而Content-Security-Policy-Report-Only中的策略僅產生報告而不具有強制性
  • 支持CSP的瀏覽器將始終對於每個企圖違反你所建立的策略都發送違規報告,如果策略里包含一個有效的report-uri 指令
Content-Security-Policy: default-src 'self'; report-uri http://reportcollector.example.com/collector.cgi
  • Don't implement the above policy yet; instead just report violations that would have occurred(尚未實施上述策略;只需報告可能發生的違規行為。)
Content-Security-Policy-Report-Only: default-src https:; report-uri /csp-violation-report-endpoint/

違例報告的語法

  • 作為報告的JSON對象報告包含了以下數據:
  • document-uri 發生違規的文檔的URI。
  • referrer 違規發生處的文檔引用(地址)。
  • blocked-uri 被CSP阻止的資源URI。如果被阻止的URI來自不同的源而非文檔URI,那么被阻止的資源URI會被刪減,僅保留協議,主機和端口號。為了防止泄露跨域資源的敏感信息
  • violated-directive 違反的策略名稱。
  • original-policy 在 Content-Security-Policy HTTP 頭部中指明的原始策略。

違例報告樣本

{
  "csp-report": {
    "document-uri": "http://example.com/signup.html",
    "referrer": "",
    "blocked-uri": "http://example.com/css/style.css",
    "violated-directive": "style-src cdn.example.com",
    "original-policy": "default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports"
  }
}

——————————————————————————————————————————

Content-Security-Policy

語法

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

指令

獲取指令

  • 通過獲取指令來控制某些可能被加載的確切的資源類型的位置。
  • child-src 為網絡工作者(Service Worker和其他內嵌瀏覽器內容(例如用<frame>和<iframe>加載到頁面的內容)定義合法的源地址。
  • frame-src 設置允許通過類似<frame>和<iframe>標簽加載的內嵌內容的源地址。
  • worker-src 限制Worker、SharedWorker或者ServiceWorker腳本源。
  • connect-src 限制能通過腳本接口加載的URL。
  • default-src 為其他取指令提供備用服務(child-src、connect-src、font-src、frame-src、img-src、manifest-src、media-src、object-src、script-src、style-src、worker-src)
  • font-src 設置允許通過@font-face加載的字體源地址。
  • img-src 限制圖片和圖標的源地址
  • manifest-src 限制應用聲明文件(manifest)的源地址。
  • media-src 制通過<audio>、<video>或<track>標簽加載的媒體文件的源地址。
    • <track> 元素 被當作媒體元素—<audio> 和 <video>的子元素來使用。它允許指定計時字幕(或者基於時間的數據),例如自動處理字幕。
  • object-src 限制<object>、<embed>、<applet>標簽的源地址。(這3個標簽再HTML5中已經廢棄)
  • prefetch-src 指定預加載或預渲染的允許源地址。?
  • script-src 限制JavaScript的源地址。
  • style-src 限制層疊樣式表文件源。
  • webrtc-src 指定WebRTC連接的合法源地址。(實驗)
    • WebRTC (Web Real-Time Communications) 是一項實時通訊技術,它允許網絡應用或者站點,在不借助中間媒介的情況下,建立瀏覽器之間點對點(Peer-to-Peer)的連接,實現視頻流和(或)音頻流或者其他任意數據的傳輸。

文檔指令

  • 文檔指令管理文檔屬性或者worker環境應用的策略。
  • base-uri 限制在DOM中<base>元素可以使用的URL。
  • plugin-types 通過限制可以加載的資源類型來限制哪些插件可以被嵌入到文檔中。?
  • sandbox 類似<iframe> sandbox屬性,為請求的資源啟用沙盒。
    • sandbox 對呈現在iframe框架中的內容啟用一些額外的限制條件。

導航指令

  • 導航指令管理用戶能打開的鏈接或者表單可提交的鏈接
  • form-action 限制能被用來作為給定上下文的表單提交的 目標 URL (說白了,就是限制 form 的 action 屬性的鏈接地址)
  • frame-ancestors 指定可能嵌入頁面的有效父項<frame>, <iframe>, <object>, <embed>, or <applet>.
  • navigation-to 限制文檔可以通過以下任何方式訪問URL (a, form, window.location, window.open, etc.?)(實驗)

報告指令

  • 報告指令控制 CSP違規的報告過程.
  • report-uri 當出現可能違反CSP的操作時,讓客戶端提交報告。這些違規報告會以JSON文件的格式通過POST請求發送到指定的URI(不被推薦)
  • report-to 觸發SecurityPolicyViolationEvent事件?

其他指令

  • block-all-mixed-content 當使用HTTPS加載頁面時阻止使用HTTP加載任何資源。
  • require-sri-for 使用 SRI 作用於頁面上的腳本或樣式。
    • SRI 子資源完整性
  • upgrade-insecure-requests 所有得請求都用HTTPS發起

CSP 和 Workers

  • Workers 一般來說不被創建他的文檔(或者父級Worker)的CSP策略管理。如果要為Worker指定CSP策略,可以為Worker腳本的請求的響應的頭部設置CSP策略。
  • 如果Worker腳本的來源是一個全局唯一ID(比如,它的URL是一個結構化的數據或者BLOB)。在這種情況下,這個Worker會繼承它所屬的文檔或者創建它的Worker的CSP策略。

多內容安全策略

  • CSP 允許在一個資源中指定多個策略, 包括通過 Content-Security-Policy 頭, 以及 Content-Security-Policy-Report-Only 頭,和 <meta> 組件(對於相同策略的條款,總是取他們的交集生效)
Content-Security-Policy: default-src 'self' http://example.com;
                         connect-src 'none';
Content-Security-Policy: connect-src http://example.com/;
                         script-src http://example.com/

——————————————————————————————————————————

內容源

  • 大多數策略指令需要一個或多個內容源。內容源是一串表明內容可能從哪里加載的字符串。

源列表

  • 源列表是一個字符串
  • 指定了一個或多個互聯網主機(通過主機名或 IP 地址)
  • 和可選的 URL 協議和/或端口號。如果端口號沒有被指定,瀏覽器會使用指定協議的默認端口號。如果協議沒有被指定,瀏覽器會使用訪問該文檔時的協議。
  • 站點地址可以包含可選的通配符前綴 (星號, ''),端口號也可以使用通配符 (同樣是 '') 來表明所有合法端口都是有效來源。
  • 主機通過空格分隔。
http://*.foo.com    // 匹配所有使用 http: 協議加載 foo.com 任何子域名的嘗試。
mail.foo.com:443    // 匹配所有訪問 mail.foo.com 的 443 端口 的嘗試。
https://store.foo.com    // 匹配所有使用 https: 協議訪問 store.foo.com 的嘗試。

關鍵字

  • 'none' 代表空集;即不匹配任何 URL。兩側單引號是必須的。
  • 'self' 代表和文檔同源,包括相同的 URL 協議和端口號。兩側單引號是必須的。
  • 'unsafe-inline' 允許使用內聯資源,如內聯的 <script> 元素、javascript: URL、內聯的事件處理函數和內聯的 <style> 元素。兩側單引號是必須的。(不安全)
  • 'unsafe-eval' 允許使用 eval() 等通過字符串創建代碼的方法。兩側單引號是必須的。(不安全)

數據

  • data: 允許 data: URI 作為內容來源。這是不安全的,因為攻擊者可以精心構造 data: URI 來攻擊。請謹慎地使用這個源,並確保不要用於腳本。
  • mediastream: 允許 mediastream: URIs 作為內容的源。
    • MediaStream 對象代表音頻或視頻相關數據的流量。 通常一個 MediaStream是作為一個簡單的URL string 它可以用來引用存儲在DOM中的數據 File, 或者一個 Blob 對象建立 window.URL.createObjectURL()(實驗功能)

——————————————————————————————————————————

指令源(以default-src為例)

語法

Content-Security-Policy: default-src <source>;
Content-Security-Policy: default-src <source> <source>;

<host-source>

  • 以域名或者 IP 地址表示的主機名,外加可選的 URL 協議名(URL scheme)以及端口號。站點地址中可能會包含一個可選的前置通配符(星號 ''),同時也可以將通配符(也是'')應用於端口號,表示在這個源中可以使用任意合法的端口號。
  • 舉例說明:
    • http://*.example.com: 匹配從使用 http: 的 example.com 的任意子域的資源加載。
    • mail.example.com:443:匹配對 mail.example.com 上的 443 端口號的訪問。
    • https://store.example.com: 匹配對使用了 https: 的 store.example.com 的訪問。
  • 一個網站管理者允許內容來自信任的域名及其子域名 (域名不必須與CSP設置所在的域名相同)
Content-Security-Policy: default-src 'self' *.trusted.com
  • 允許網頁應用的用戶在他們自己的內容中包含來自任何源的圖片,
  • 音頻或視頻需從信任的資源提供者(獲得)(多媒體文件僅允許從 media1.com 和 media2.com 加載(不允許從這些站點的子域名)。)
  • 所有腳本必須從特定主機服務器獲取可信的代碼.(可運行腳本僅允許來自於userscripts.example.com。)
Content-Security-Policy: default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com
  • 想要確保網站的所有內容都要通過SSL方式獲取,以避免攻擊者竊聽用戶發出的請求。
    • SSL(Secure Sockets Layer 安全套接層)
  • 該服務器僅允許通過HTTPS方式並僅從onlinebanking.jumbobank.com域名來訪問文檔。
Content-Security-Policy: default-src https://onlinebanking.jumbobank.com

<scheme-source>

  • 協議名如'http:' 或者 'https:'。必須帶有冒號,不要有單引號。
  • data: 允許 data: URIs 作為內容的源。這是不安全的。攻擊者可以注入任意 data: URI 。不要輕易使用這種形式的源,尤其是腳本,絕對不要使用。data:text/html,<script>alert('hi');</script>
  • mediastream: 允許 mediastream: URIs 作為內容的源。
    • MediaStream 對象代表音頻或視頻相關數據的流量。 通常一個 MediaStream是作為一個簡單的URL string 它可以用來引用存儲在DOM中的數據 File, 或者一個 Blob 對象建立 window.URL.createObjectURL()(實驗功能)
  • blob: 允許 blob: URIs 作為內容的源。
  • filesystem: 允許 filesystem: URIs 作為內容的源。(filesystem: URIs文件系統,已經廢棄)
  • 禁用不安全的內聯/動態執行, 只允許通過 https加載這些資源 (images, fonts, scripts, etc.)
// header
Content-Security-Policy: default-src https:

// meta tag
<meta http-equiv="Content-Security-Policy" content="default-src https:">

'self'

  • 指向與要保護的文件所在的源,包括相同的 URL scheme 與端口號。必須有單引號。
  • 一些瀏覽器會特意排除 blob 與 filesystem 。需要設定這兩種內容類型的站點可以在 Data 屬性中進行設定。?
  • 一個網站管理者想要所有內容均來自站點的同一個源 (不包括其子域名)
Content-Security-Policy: default-src 'self'

'unsafe-inline'

  • 允許使用內聯資源,例如內聯 <script> 元素(javascript: URL)、內聯事件處理器以及內聯 <style> 元素。必須有單引號。
Content-Security-Policy: default-src https: 'unsafe-eval' 'unsafe-inline'; object-src 'none'

'unsafe-eval'

  • 允許使用 eval() 以及相似的函數來從字符串創建代碼。必須有單引號。

'none'

  • 不允許任何內容。 必須有單引號。

'nonce-<base64值>'

  • 特定使用一次性加密內聯腳本的白名單。服務器必須在每一次傳輸政策時生成唯一的一次性值。否則將存在繞過資源政策的可能。
<script nonce=EDNnf03nceIOfn39fn3e9h3sdfa src=''></script>

Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa' // 響應頭,指明了nonce白名單包括范圍

——————————————————————————————————————————

Strict-Transport-Security

  • 一個安全功能,它告訴瀏覽器只能通過HTTPS訪問當前資源,而不是HTTP。(HTTPS一般用來校驗身份,隨后的請求都換為更節能的HTTP,但是這些請求可能被攔截,然后返回重定向,使你的頁面重定向虛假網站,這個響應頭強制要求瀏覽器把HTTP請求轉為HTTPS發起)
  • 同時阻止了只能通過 HTTP 訪問的內容。

語法

Strict-Transport-Security: max-age=<expire-time>
Strict-Transport-Security: max-age=<expire-time>; includeSubDomains
Strict-Transport-Security: max-age=<expire-time>; preload

指令

  • max-age= 設置在瀏覽器收到這個請求后的 秒的時間內凡是訪問這個域名下的請求都使用HTTPS請求
  • includeSubDomains 如果這個可選的參數被指定,那么說明此規則也適用於該網站的所有子域名。
    • mail.example.com和calendar.example.com是example.com的兩個子域
  • preload 不是標准的一部分。(預加載?)

描述

  • 一個網站接受一個HTTP的請求,然后跳轉到HTTPS,用戶可能在開始跳轉前,通過沒有加密的方式和服務器對話,這樣存在中間人攻擊潛在威脅,跳轉過程可能被惡意網站利用來直接接觸用戶信息,而不是原來的加密信息。
  • Strict-Transport-Security 在通過 HTTP 訪問時會被瀏覽器忽略; 因為攻擊者可以通過中間人攻擊的方式在連接中修改、注入或刪除它. 只有在你的網站通過HTTPS訪問並且沒有證書錯誤時, 瀏覽器才認為你的網站支持HTTPS 然后使用 Strict-Transport-Security 的值 .

瀏覽器如何處理

  • 你的網站第一次通過HTTPS請求,服務器響應Strict-Transport-Security 頭,瀏覽器記錄下這些信息,然后后面嘗試訪問這個網站的請求都會自動把HTTP替換為HTTPS。
  • 當HSTS頭設置的過期時間到了,后面通過HTTP的訪問恢復到正常模式,不會再自動跳轉到HTTPS。
  • 每次瀏覽器接收到Strict-Transport-Security頭,它都會更新這個網站的過期時間,所以網站可以刷新這些信息,防止過期發生。

預加載 HSTS

  • 谷歌維護着一個 HSTS 預加載服務。按照如下指示成功提交你的域名后,瀏覽器將會永不使用非安全的方式連接到你的域名
  • 雖然該服務是由谷歌提供的,但所有瀏覽器都有使用這份列表的意向(或者已經在用了)。
  • 火狐也有自己的 HSTS 預加載列表

示例

  • 現在和未來的所有子域名會自動使用 HTTPS 連接長達一年。同時阻止了只能通過 HTTP 訪問的內容。
Strict-Transport-Security: max-age=31536000; includeSubDomains


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM