這本系列的第一篇,先解釋瀏覽器的功能以及執行方式。由於大多數客戶將通過瀏覽器與 web 應用程式進行互動,因此必須瞭解這些出色程式的基礎知識。
瀏覽器是一個渲染引擎,它的工作是下載一個web頁面,並以人類能夠理解的方式渲染它。
雖然這幾乎是一種過於簡單的過分簡化,但我們現在需要知道的全部內容。
- 使用者在瀏覽器欄中輸入一個地址。
- 瀏覽器從該 URL 下載“文件”並渲染它。
你可能習慣使用 Chrome,Firefox,Edge或Safari等流行的瀏覽器之一,但這並不意味著沒有不同的瀏覽器。
例如,lynx 是一種輕量級的、基於文字的瀏覽器,可以在命令列中工作。lynx 的核心原理與其他“主流”瀏覽器的原理完全相同。使用者輸入 web 地址(URL),瀏覽器獲取文件並呈現它——唯一的區別是 lynx 不使用視覺化渲染引擎,而是使用基於文字的介面,這使得像谷歌這樣的網站看起來像這樣:
我們大致瞭解瀏覽器的功能,但是讓我們仔細看看這些機智的應用程式為我們所做的步驟。
瀏覽器做了什麼?
長話短說,瀏覽器的工作主要包括:
- DNS 解析
- HTTP 交換
- 渲染
- 重複以下步驟
DNS 解析
這個過程確保一旦使用者輸入 URL,瀏覽器就知道它必須連線到哪個伺服器。瀏覽器聯絡 DNS 伺服器,發現google.com
翻譯成 216.58.207.110
,這是一個瀏覽器可以連線的 IP 地址。
HTTP 交換
一旦瀏覽器確定了哪個伺服器將為我們的請求提供服務,它將啟動與它的 TCP 連線並開始 HTTP 交換。 這只是瀏覽器與伺服器通訊所需內容以及伺服器回覆的一種方式。
HTTP 只是用於在 Web 上進行通訊協議的名稱,而瀏覽器一般通過 HTTP 與伺服器進行通訊。 HTTP 交換涉及客戶端(我們的瀏覽器)傳送請求,伺服器回覆響應。
例如,當瀏覽器成功連線到 google.com 背後的伺服器後,它將傳送一個如下所示的請求:
GET / HTTP/1.1
Host: google.com
Accept: */*
讓我們一行一行地把請求分解:
-
GET / HTTP/1.1
:在第一行中,並補充說其餘請求將遵循 HTTP/1.1 協議(它也可以使用1.0
或2
) -
Host: google.com
:這是 HTTP/1.1 中唯一必須的 HTTP 報頭。因為伺服器可能服務多個域(google.com
,google.co.uk
) 。這裡的客戶端提到請求是針對特定的主機的。 -
Accept: */*
:一個可選的標頭,其中瀏覽器告訴伺服器接受任何型別的響應。伺服器可以擁有 JSON、XM L或HTML 格式的可用資源,因此它可以選擇自己喜歡的格式。
作為客戶端的瀏覽器傳送請求之後,就輪到伺服器進行響應了,這是響應的格式如下:
HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Content-Type: text/html; charset=ISO-8859-1
Server: gws
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
Set-Cookie: NID=1234; expires=Fri, 18-Jan-2019 18:25:04 GMT; path=/; domain=.google.com; HttpOnly
<!doctype html><html">
...
...
</html>
哇,有很多資訊需要消化。伺服器讓我們知道請求是成功的(200 OK
),並向響應中新增一些頭部資訊,例如,它告知哪個伺服器處理了我們的請求(Server:gws
),該響應的 X-XSS-Protection
策略是什麼,等等。
現在,你不需要理解響應中的每一行,在本系列後面的文章中,我們將介紹 HTTP 協議及其頭部等內容。
現在,你只需要瞭解客戶端和伺服器正在交換資訊,並且它們是通過 HTTP 進行交換的。
渲染
<!doctype html><html">
...
...
</html>
在響應的主體中,伺服器根據 Content-Type
頭包括響應型別來表示。 在我們的例子中,內容型別設定為 text/ html
,因此我們期待響應中的 HTML 標記 - 這正是我們在正文中找到的。
這才是瀏覽器真正的亮點所在。它解析 HTML,載入標記中包含的額外資源(例如,可能需要獲取JavaScript檔案或CSS文件),並儘快將它們呈現給使用者。
最終的結果是普通人能夠理解的:
如果想要更詳細地瞭解當我們在瀏覽器位址列中按Enter鍵時會發生什麼,建議閱讀“What happens when…”,這是一個非常精細的嘗試來解釋該過程背後的機制。
由於這是一個關注安全性的系列文章,從剛剛瞭解到的內容可以提到提示:攻擊者可以輕鬆地利用 HTTP 交換和渲染部分中的漏洞謀生。漏洞和惡意使用者也潛伏在其他地方,但是這些級別上更好的安全方法已經允許你在改進安全性方面取得進展。
供應商
4 個最流行的瀏覽器屬於不同的公司:
- 谷歌的 Chrome
- Mozilla 的火狐
- 蘋果的 Safari
- 微軟的 Edge
除了為了增加市場滲透率而相互競爭之外,供應商也為了提高 web 標準而相互合作,這是對瀏覽器的一種“最低要求”。
W3C是標準開發的主體,但是瀏覽器開發自己的特性並最終成為 web 標準的情況並不少見,安全性也不例外。
例如,Chrome 51 引入了 SameSite cookie,該功能允許 Web 應用程式擺脫稱為 CSRF 的特定型別的漏洞(稍後將詳細介紹)。其他供應商認為這是一個好主意,並紛紛效仿,導致 SameSite 成為 web 標準:到目前為止,Safari 是唯一沒有 SameSite cookie 支援的主流瀏覽器。
這告訴我們兩件事:
- Safari似乎並不關心使用者的安全性(開玩笑:Safari 12中將提供SameSite cookie,這可能在你閱讀本文時已經發布)
- 修補一個瀏覽器上的漏洞並不意味著所有使用者都是安全的
第一點是對 Safari 的一次嘗試(正如我提到的,開玩笑的!),而第二點非常重要。在開發web應用程式時,我們不僅需要確保它們在不同的瀏覽器中看起來是相同的,還需要確保我們的使用者在不同的平臺上受到相同的保護。
你的網路安全策略應根據瀏覽器供應商允許我們執行的操作而有所不同。 如今,大多數瀏覽器都支援相同的功能集,並且很少偏離其常見的路線圖,但是上面的例項仍然會發生,這是我們在定義安全策略時需要考慮的事情。
在我們的例子中,如果我們決定只通過 SameSite cookie 來減輕 CSRF 攻擊,那麼我們應該意識到我們正在將 Safari 使用者置於危險之中。我們的使用者也應該知道這一點。
最後但並非最不重要,你應該記住,你可以決定是否支援瀏覽器版本:支援每一個瀏覽器版本將是不切實際的(想想 Internet Explorer 6)。雖然確保最近幾個版本的主流瀏覽器的支援通常是一個好的決定,但是如果你不打算在特定的平臺上提供保護,一般建議讓你的使用者知道。
專業提示:你不應該鼓勵你的使用者使用過時的瀏覽器,或積極支援他們。儘管你可能已經採取了所有必要的預防措施,但是其他web開發人員可能沒有。鼓勵使用者使用主流瀏覽器支援的最新版本。
供應商還是標準bug?
普通使用者通過第三方客戶端(瀏覽器)訪問我們的應用程式這一事實增加了另一層次的間接性:瀏覽器本身可能存在安全漏洞。
‘
供應商通常會向能夠發現瀏覽器自身漏洞的安全研究人員提供獎勵(即 bug獎金)。這些bug與你的實現無關,而是與瀏覽器本身處理安全性的方式有關。
例如,Chrome 獎勵計劃可讓安全工程師與 Chrome 安全團隊聯絡,報告他們發現的漏洞。 如果確認了這些漏洞,則會發布補丁,通常會向公眾釋出安全建議通知,研究人員會從該計劃中獲得(通常是財務上的)獎勵。
像谷歌這樣的公司在他們的Bug賞金專案中投入了相對較多的資金,這使得他們能夠通過承諾在發現應用程式的任何問題時獲得經濟利益來吸引研究人員。
在一個漏洞賞金計劃中,每個人都是贏家:供應商設法提高其軟體的安全性,研究人員也因此獲得報酬。我們將在後面討論這些程式,因為我相信Bug賞金計劃應該在安全領域有自己的一節。
Jake Archibald 是谷歌的一名開發人員,他最近發現了一個影響多個瀏覽器的漏洞。他在一篇有趣的部落格文章中記錄了他的努力,他如何接觸不同的供應商,以及他們的反應,建議你閱讀 這篇文章。
開發人員的瀏覽器
到目前為止,我們應該理解一個非常簡單但相當重要的概念:瀏覽器只是為普通網路衝浪者構建的 HTTP 客戶端。
它們肯定比平臺的純HTTP客戶端更強大(例如,考慮NodeJS的require(‘HTTP’)),但歸根結底,它們“只是”更簡單的 HTTP客戶端的自然演化。
作為開發人員,我們選擇的HTTP客戶機可能是 Daniel Stenberg 的 cURL,他是 web 開發人員每天使用的最流行的軟體程式之一。它允許我們通過從命令列傳送 HTTP 請求來實時執行 HTTP 交換:
$ curl -I localhost:8080
HTTP/1.1 200 OK
server: ecstatic-2.2.1
Content-Type: text/html
etag: "23724049-4096-"2018-07-20T11:20:35.526Z""
last-modified: Fri, 20 Jul 2018 11:20:35 GMT
cache-control: max-age=3600
Date: Fri, 20 Jul 2018 11:21:02 GMT
Connection: keep-alive
在上面的示例中,我們在 localhost:8080/
上請求了文件,本地伺服器成功響應。
在這裡,我們沒有將響應的主體顯示在命令列,而是使用了 -I
標誌,它告訴 cURL 我們只對響應頭感興趣。更進一步,我們可以指示 cURL 顯示更多的資訊,包括它執行的實際請求,以便更好地檢視整個HTTP交換。需要使用的選項是-v
(詳細):
$ curl -I -v localhost:8080
* Rebuilt URL to: localhost:8080/
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> HEAD / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< server: ecstatic-2.2.1
server: ecstatic-2.2.1
< Content-Type: text/html
Content-Type: text/html
< etag: "23724049-4096-"2018-07-20T11:20:35.526Z""
etag: "23724049-4096-"2018-07-20T11:20:35.526Z""
< last-modified: Fri, 20 Jul 2018 11:20:35 GMT
last-modified: Fri, 20 Jul 2018 11:20:35 GMT
< cache-control: max-age=3600
cache-control: max-age=3600
< Date: Fri, 20 Jul 2018 11:25:55 GMT
Date: Fri, 20 Jul 2018 11:25:55 GMT
< Connection: keep-alive
Connection: keep-alive
<
* Connection #0 to host localhost left intact
主流瀏覽器通過它們的 DevTools 可以獲得幾乎相同的資訊。
正如我們所見,瀏覽器只不過是精心設計的HTTP客戶端。 當然,他們新增了大量的功能(想到憑據管理,書籤,歷史等),但事實是,它們是作為人類的 HTTP 客戶端而誕生的。 這很重要,因為在大多數情況下,不需要使用瀏覽器來測試Web應用程式的安全性,因為你可以簡單的通過 curl
命令來檢視響應資訊。
進入 HTTP 協議
正如我們所提到的,HTTP交換和渲染階段是我們主要要涉及的階段,因為它們為惡意使用者提供了最大數量的攻擊媒介。
在下一篇文章中,我們將深入研究HTTP協議,並嘗試瞭解為了保護HTTP交換,我們應該採取哪些措施。
原文:
https://medium.freecodecamp.o...
你的點贊是我持續分享好東西的動力,歡迎點贊!
歡迎加入前端大家庭,裡面會經常分享一些技術資源。