威脅
跨站腳本攻擊(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 頭部中指明的原始策略。
違例報告樣本
- 頁面位於 http://example.com/signup.html。它使用以下策略
Content-Security-Policy: default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports
- 存在的違例加載以下
<link rel="stylesheet" href="css/style.css">
- 當該文檔被訪問時,一個兼容CSP的瀏覽器將以POST請求的形式發送違規報告到 http://example.com/_/csp-reports,內容以下:
{
"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 做用於頁面上的腳本或樣式。
- 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