- Web漏洞搜索
- (美)彼得·亞沃斯基
- 2668字
- 2021-11-05 10:19:57
1.3 當你訪問一個網址時發生了什么
因為我們將在本書中重點介紹HTTP消息,所以本節將從較高的層次概述在瀏覽器的地址欄中輸入URL后經歷的過程。
第一步:提取域名
一旦你輸入http://www.google.com/,瀏覽器會根據URL確定域名。域名標識你要訪問的網站,并且必須遵守RFC定義的特定規則。例如,域名只能包含字母、數字和下劃線。國際化域名是一個例外,這超出了本書的范圍,如果想了解它們的用法,請參考RFC 3490。在我們列舉的例子中,域名是www.google.com。域名是用于查找服務器地址的一種方式。
第二步:解析IP地址
確定域名后,瀏覽器使用IP來查找與域名關聯的IP地址,此過程稱為解析IP地址?;ヂ摼W上的每個域名都必須被解析為IP地址才能工作。
IP地址存在兩種類型:Internet協議版本4(IPv4)和Internet協議版本6(IPv6)。IPv4地址是由以點連接的四個數字組成的,每個數字在0到255之間。IPv6是Internet協議的最新版本,它是為了解決“可用IPv4地址耗盡”的問題而設計的。IPv6地址由八組四位十六進制數字組成,用冒號隔開,而且也有縮寫的方法。例如,8.8.8.8是IPv4地址,2001:4860:4860::8888是IPv6地址的縮寫。
如果僅使用域名查找IP地址,計算機會向域名系統(DNS)服務器發送請求。DNS服務器由互聯網上的專用服務器組成,這些服務器具有所有域名及其匹配的IP地址的注冊表。前面IPv4和IPv6地址用到的是Google DNS服務器。
在這個例子中,連接到的DNS服務器將匹配到www.google.com的IPv4地址216.58.201.228并發送回你的計算機。要了解有關站點IP地址的更多信息,可以從你的終端使用命令dig A site.com并用你正在查找的網站替換site.com。
第三步:建立一個TCP連接
因為使用http://訪問網址,所以隨后計算機會嘗試與80端口上的IP地址建立TCP連接。TCP的細節并不重要,我們只需注意它是另一種定義“計算機如何相互通信”的協議即可。TCP提供了雙向通信,這樣消息接收者就可以驗證對方是否接收到了信息,并且在傳輸過程中不會丟失任何內容。
你要向其發送請求的服務器可能正在運行多個服務(將服務視為計算機程序),因此它使用端口來標識接收請求的特定進程。你可以將端口視為服務器通向互聯網的入口。如果沒有端口,服務器端將不得不對發送到同一地點的信息進行競爭。這意味著我們需要另一個標準來定義服務如何相互協作,并確保一個服務的數據不會被另一個服務竊取。例如,端口80是發送和接收未加密的HTTP請求的標準端口。另一個公共端口是443,用于處理加密的HTTPS請求。雖然端口80是HTTP的標準端口,443是HTTPS的標準端口,但是TCP通信可以在任何端口上發生,這取決于管理員如何配置應用程序。
通過打開終端并運行nc <IP ADDRESS> 80,你可以在端口80上建立自己的TCP連接。這一命令行使用Netcat utility中的nc命令創建用于讀寫消息的網絡連接。
第四步:發送一個HTTP請求
繼續把http://www.google.com/作為例子,如果在第三步連接成功,你的瀏覽器應該準備并發送一個HTTP請求,如列表1-1所示。
列表1-1 發送一個HTTP請求


瀏覽器向路徑/發出GET請求(?),這是網站的根路徑。網站的內容根據路徑進行組織,就像計算機上的文件夾和文件一樣。當進一步訪問每個文件夾時,所走的路徑都是通過記錄每個文件夾的名稱后面跟一個“/”來表示的。當你訪問網站的第一頁時,將訪問根路徑,它只是一個“/”。瀏覽器還指示它使用的是1.1版本的HTTP協議。GET請求只獲取信息。我們之后會了解更多有關GET方法的知識。
Host頭(?)包含請求中發送的一部分附加信息。HTTP 1.1需要Host頭來找到服務器的IP地址以確定請求應該發向哪里,因為IP地址可以對應多個域名。連接頭(?)表示請求與服務器的連接保持打開狀態,以避免不斷打開和關閉連接。
你可以在?中知道預期的響應格式。在本例中,我們期望返回的格式是application/html,同時通過通配符(*/*)可以接受任何響應格式。目前有數百種可能的內容類型,但對我們來說,application/html、application/json、application/octet-stream、text/plain是比較常用的。最后,User-Agent(?)表示發送請求的軟件系統。
第五步:服務器響應
為了響應請求,服務器應該使用類似于列表1-2的內容進行響應。
列表1-2 服務器響應

這里,我們收到一個狀態碼為200的HTTP響應(?)。狀態碼很重要,因為它代表了服務器的響應狀態。同樣由RFC定義,這些狀態碼通常是以2、3、4或5開頭的三位數字。雖然沒有嚴格要求服務器使用特定代碼,但2xx通常表示請求成功。
由于這里服務器沒有嚴格執行HTTP狀態碼的使用規則,因此即使HTTP報文解析存在應用程序錯誤,也可能會看到一些狀態碼是200的響應。HTTP報文是一段與請求或響應相關聯的文本(?)。在本例中,我們刪除了內容并將其替換為“--snip--”,因為Google的響應體太大了。對于Web頁面,響應內容通常是HTML,但對于應用程序編程接口(API),響應內容可能是JSON,而對于文件下載,響應內容則可能是一個文件,等等。
Content-Type頭(?)通知瀏覽器的媒體類型。媒體類型決定瀏覽器如何呈現內容。但瀏覽器并不總是使用從應用程序返回的值;相反,瀏覽器執行MIME sniffing,通過讀取正文內容的第一位來確定自己的媒體類型。應用程序通過包含頭文件X-Content-Type-Options:nosniff,可以禁止瀏覽器使用MIME sniffing這種方式。
其他以3開頭的響應狀態碼表示重定向,指示瀏覽器發出附加請求。例如,理論上,如果Google需要永久性地將一個URL重定向到另一個URL,可以使用301響應。相反,302是臨時重定向。
當收到3xx響應狀態碼時,瀏覽器應向Location頭中指定的URL發出新的HTTP請求,如下所示:

以4開頭的響應通常表示用戶錯誤。例如,盡管提供了一個有效的HTTP請求,但請求不包括授權訪問內容的正確標識時就會響應403。以5開頭的響應表示某種類型的服務器錯誤,例如503表示服務器無法處理發送的請求。
第六步:呈現響應
因為服務器發送了一個狀態碼為200,內容類型為text/html的響應,瀏覽器將開始呈現它收到的內容。響應體會告訴瀏覽器應該向用戶顯示什么。
例如,這個響應體將包括頁面結構的HTML,用于樣式和布局的級聯樣式表(CSS),以及用于添加附加動態功能和媒體文件(如圖像或視頻)的JavaScript。服務器也能返回其他內容,例如XML,但是仍以本例的內容為準。第11章中更詳細地討論了XML。
因為網頁可以引用外部文件,如CSS、JavaScript和媒體文件,所以瀏覽器可能會對網頁的所有必需文件發出額外的HTTP請求。當瀏覽器請求這些附加文件時,它會繼續解析響應并將正文作為網頁呈現給你。在本例中,它將呈現Google的主頁:www.google.com。
請注意,JavaScript是每種主流瀏覽器都支持的腳本語言。JavaScript允許網頁具有動態功能,包括在不重新加載網頁的情況下更新網頁內容,(在某些網站上)檢查密碼是否足夠強,等等。與其他編程語言一樣,JavaScript具有內置函數,可以將值存儲在變量中,并運行代碼以響應Web頁面上的事件。它還可以訪問各種瀏覽器API。這些API使JavaScript能夠與其他系統交互,其中最重要的可能是文檔對象模型(Document Object Model,DOM)。
DOM允許JavaScript訪問和操作網頁的HTML和CSS。這一點很重要,因為如果攻擊者可以在站點上執行自己的JavaScript,那么他們就可以訪問DOM,并可以以目標用戶的名義在站點上執行操作。第7章中會進一步探討這一部分內容。