《圖解 HTTP》 讀書筆記

SHERlocked93發表於2019-03-21

這本 HTTP 方面的小冊子還蠻不錯,已經二刷了 ?

這次做了一些筆記,方便自己和其他人翻閱和複習,因為這本書是 2014 年出的初版,所以有一些不怎麼常用的技術,筆記中就省略了,只記一些比較常用的 ~

1. 瞭解 Web 及網路基礎

1.1 網路基礎 TCP/IP

通常使用的網路(包括網際網路)是在 TCP/IP 協議族的基礎上運作,而 HTTP 屬於它內部的一個子集。

按層次分為以下 4 層:應用層、傳輸層、網路層和資料鏈路層。

  1. 應用層: 決定了向使用者提供應用服務時通訊的活動,比如 FTP、DNS、HTTP
  2. 傳輸層: 對上層應用層,提供處於網路連線中的兩臺計算機之間的資料傳輸,比如 TCP、UDP
  3. 網路層: 用來處理在網路上流動的資料包,該層規定了通過怎樣的路徑(所謂的傳輸路線)到達對方計算機,並把資料包傳送給對方;與對方計算機之間通過多臺計算機或網路裝置進行傳輸時,網路層所起的作用就是在眾多的選項內選擇一條傳輸路線。
  4. 資料鏈路層: 用來處理連線網路的硬體部分

《圖解 HTTP》 讀書筆記

利用 TCP/IP 協議族進行網路通訊時,會通過分層順序與對方進行通訊。傳送端從應用層往下走,接收端則往應用層往上走。

以 HTTP 為例,一次通訊的過程

  1. 首先作為傳送端的客戶端在應用層(HTTP 協議)發出獲取 Web 頁面的 HTTP 請求
  2. 接著,為了傳輸方便,在傳輸層(TCP 協議)把從應用層處收到的資料(HTTP 請求報文)進行分割,並在各個報文上打上標記序號及埠號後轉發給網路層。
  3. 在網路層(IP 協議),增加作為通訊目的地的 MAC 地址後轉發給鏈路層。這樣一來,發往網路的通訊請求就準備齊全了
  4. 接收端的伺服器在鏈路層接收到資料,按序往上層傳送,一直到應用層。當傳輸到應用層,才能算真正接收到由客戶端傳送過來的 HTTP 請求。

《圖解 HTTP》 讀書筆記

傳送端在層與層之間傳輸資料時,每經過一層時必定會被打上一個該層所屬的首部資訊。反之,接收端在層與層傳輸資料時,每經過一層時會把對應的首部消去。

這種把資料資訊包裝起來的做法稱為封裝(encapsulate)。

1.2 三次握手

為了準確無誤地將資料送達目標處,TCP 協議採用了三次握手(three-way handshaking)策略。握手過程中使用了 TCP 的標誌(flag) —— SYN(synchronize) 和 ACK(acknowledgement)。

傳送端首先傳送一個帶 SYN 標誌的資料包給對方。接收端收到後,回傳一個帶有 SYN/ACK 標誌的資料包以示傳達確認資訊。最後,傳送端再回傳一個帶 ACK 標誌的資料包,代表“握手”結束。

傳送端首先傳送一個帶 SYN 標誌的資料包給對方。接收端收到後,回傳一個帶有 SYN/ACK 標誌的資料包以示傳達確認資訊。最後,傳送端再回傳一個帶 ACK 標誌的資料包,代表“握手”結束。

《圖解 HTTP》 讀書筆記

1.3 負責域名解析的 DNS 服務

DNS(Domain Name System)服務是和 HTTP 協議一樣位於應用層的協議。它提供域名到 IP 地址之間的解析服務。

《圖解 HTTP》 讀書筆記

1.4 各協議與 HTTP 協議的關係

通過這張圖來了解下 IP 協議、TCP 協議和 DNS 服務在使用 HTTP 協議的通訊過程中各自發揮了哪些作用。

《圖解 HTTP》 讀書筆記

1.5 URI 和 URL

瞭解一下 URI 的各部分

《圖解 HTTP》 讀書筆記

  1. 協議方案名: 使用 http:https: 等協議方案名獲取訪問資源時要指定協議型別。不區分字母大小寫,最後附一個冒號。也可使用 data:javascript: 這類指定資料或指令碼程式的方案名。
  2. 登入資訊(認證): 指定使用者名稱和密碼作為從伺服器端獲取資源時必要的登入資訊(身份認證)。此項是可選項。
  3. 伺服器地址: 使用絕對 URI 必須指定待訪問的伺服器地址。地址可以是類似 hackr.jp 這種 DNS 可解析的名稱,或是 192.168.1.1 這類 IPv4 地址名,還可以是 [0:0:0:0:0:0:0:1] 這樣用方括號括起來的 IPv6 地址名。
  4. 伺服器埠號: 指定伺服器連線的網路埠號。此項也是可選項,若使用者省略則自動使用預設埠號。
  5. 帶層次的檔案路徑: 指定伺服器上的檔案路徑來定位特指的資源。這與 UNIX 系統的檔案目錄結構相似。
  6. 查詢字串: 針對已指定的檔案路徑內的資源,可以使用查詢字串傳入任意引數。此項可選。
  7. 片段識別符號: 使用片段識別符號通常可標記出已獲取資源中的子資源(文件內的某個位置)。但在 RFC 中並沒有明確規定其使用方法。該項也為可選項

2. 簡單的 HTTP 協議

2.1 HTTP 是不儲存狀態的協議

HTTP 是一種不儲存狀態,即無狀態(stateless)協議。HTTP 協議自身不對請求和響應之間的通訊狀態進行儲存。這是為了更快地處理大量事務,確保協議的可伸縮性,而特意把 HTTP 協議設計成如此簡單的。

HTTP1.1 雖然是無狀態協議,但為了實現期望的保持狀態功能,於是引入了 Cookie 技術。

2.2 告知伺服器意圖的 HTTP 方法

  1. GET 獲取資源: 用來請求訪問已被 URI 識別的資源,指定的資源經伺服器端解析後返回響應內容。 如果請求的資源是文字,那就保持原樣返回;如果是像 CGI(Common Gateway Interface,通用閘道器介面)那樣的程式,則返回經過執行後的輸出結果。
  2. POST 傳輸實體主體: 用來傳輸實體的主體 雖然用 GET 方法也可以傳輸實體的主體,但一般不用 GET 方法進行傳輸,而是用 POST 方法。雖說 POST 的功能與 GET 很相似,但 POST 的主要目的並不是獲取響應的主體內容。
  3. PUT 傳輸檔案: 在請求報文的主體中包含檔案內容,然後儲存到請求 URI 指定的位置 鑑於 HTTP1.1 的 PUT 方法自身不帶驗證機制,任何人都可以上傳檔案,存在安全性問題,因此一般的 Web 網站不使用該方法。
  4. HEAD 獲得報文首部: 和 GET 方法一樣,只是不返回報文主體部分。 用於確認 URI 的有效性及資源更新的日期時間等。
  5. DELETE 刪除檔案: 用來刪除檔案,是與 PUT 相反的方法。DELETE 方法按請求 URI 刪除指定的資源。 HTTP1.1 的 DELETE 方法本身和 PUT 方法一樣不帶驗證機制,所以一般的 Web 網站也不使用 DELETE 方法。
  6. OPTIONS 詢問支援的方法: 用來查詢針對請求 URI 指定的資源支援的方法。
  7. TRACE 追蹤路徑: 讓 Web 伺服器端將之前的請求通訊環回給客戶端的方法。 傳送請求時,在 Max-Forwards 首部欄位中填入數值,每經過一個伺服器端就將該數字減 1,當數值剛好減到 0 時,就停止繼續傳輸,最後接收到請求的伺服器端則返回狀態碼 200 OK 的響應。 但 TRACE 方法本來就不怎麼常用,再加上它容易引發 XST(Cross-Site Tracing,跨站追蹤)攻擊,通常就更不會用到了。
  8. CONNECT 要求用隧道協議連線代理: 要求在與代理伺服器通訊時建立隧道,實現用隧道協議進行 TCP 通訊。 主要使用 SSL(Secure Sockets Layer,安全套接層)和 TLS(Transport Layer Security,傳輸層安全)協議把通訊內容加密後經網路隧道傳輸。
方法 說明 支援的 HTTP 協議版本
GET 獲取資源 1.0、1.1
POST 傳輸實體主體 1.0、1.1
PUT 傳輸檔案 1.0、1.1
HEAD 獲得報文首部 1.0、1.1
DELETE 刪除檔案 1.0、1.1
OPTIONS 詢問支援的方法 1.1
TRACE 追蹤路徑 1.1
CONNECT 要求用隧道協議連線代理 1.1
LINK 建立和資源之間的聯絡 1.0
UNLINE 斷開連線關係 1.0

LINK 和 UNLINK 已被 HTTP1.1 廢棄,不再支援。

2.3 持久連線節省通訊量

HTTP 協議的初始版本中,每進行一次 HTTP 通訊就要斷開一次 TCP 連線。

比如,使用瀏覽器瀏覽一個包含多張圖片的 HTML 頁面時,在傳送請求訪問 HTML 頁面資源的同時,也會請求該 HTML 頁面裡包含的其他資源。因此,每次的請求都會造成無謂的 TCP 連線建立和斷開,增加通訊量的開銷。

持久連結 keep-alive

HTTP1.1 和一部分的 HTTP1.0 想出了持久連線(keep-alive)的方法。持久連線的特點是,只要任意一端沒有明確提出斷開連線,則保持 TCP 連線狀態。

持久連線的好處在於減少了 TCP 連線的重複建立和斷開所造成的額外開銷,減輕了伺服器端的負載。另外,減少開銷的那部分時間,使 HTTP 請求和響應能夠更早地結束,這樣 Web 頁面的顯示速度也就相應提高了。

在 HTTP1.1 中,所有的連線預設都是持久連線,但在 HTTP1.0 內並未標準化。

管線化 pipelining

持久連線使得多數請求以管線化(pipelining)方式傳送成為可能。從前傳送請求後需等待並收到響應,才能傳送下一個請求。管線化技術出現後,不用等待響應亦可直接傳送下一個請求。

這樣就能夠做到同時並行傳送多個請求,而不需要一個接一個地等待響應了。

用持久連線可以讓請求更快結束。而管線化技術則比持久連線還要快。請求數越多,時間差就越明顯。

2.4 使用 Cookie 的狀態管理

HTTP 是無狀態協議,它不對之前發生過的請求和響應的狀態進行管理。也就是說,無法根據之前的狀態進行本次的請求處理。

假設要求登入認證的 Web 頁面本身無法進行狀態的管理(不記錄已登入的狀態),那麼每次跳轉新頁面不是要再次登入,就是要在每次請求報文中附加引數來管理登入狀態。

Cookie 技術通過在請求和響應報文中寫入 Cookie 資訊來控制客戶端的狀態。Cookie 會根據從伺服器端傳送的響應報文內的一個叫做 Set-Cookie 的首部欄位資訊,通知客戶端儲存 Cookie。當下次客戶端再往該伺服器傳送請求時,客戶端會自動在請求報文中加入 Cookie 值後傳送出去。

3. HTTP 報文內的 HTTP 資訊

3.1 編碼提升傳輸速率

HTTP 可以在傳輸過程中通過編碼提升傳輸速率。

3.2 壓縮傳輸的內容編碼

內容編碼指明應用在實體內容上的編碼格式,並保持實體資訊原樣壓縮。

常用的內容編碼有:gzip(GNU zip)、compress(UNIX 系統的標準壓縮)deflate(zlib)、identity(不進行編碼)

3.3 分割傳送的分塊傳輸編碼

在 HTTP 通訊過程中,請求的編碼實體資源尚未全部傳輸完成之前,瀏覽器無法顯示請求頁面。在傳輸大容量資料時,通過把資料分割成多塊,能夠讓瀏覽器逐步顯示頁面。這種把實體主體分塊的功能稱為分塊傳輸編碼(Chunked Transfer Coding)。

分塊傳輸編碼會將實體主體分成多個部分(塊)。每一塊都會用十六進位制來標記塊的大小,而實體主體的最後一塊會使用“0(CR+LF)”來標記。

使用分塊傳輸編碼的實體主體會由接收的客戶端負責解碼,恢復到編碼前的實體主體。

3.4 傳送多種資料的多部分物件集合

在 HTTP 報文中使用多部分物件集合時,需要在首部欄位里加上 Content-type

  1. multipart/form-data: 在 Web 表單檔案上傳時使用。
  2. multipart/byteranges: 狀態碼 206(Partial Content,部分內容)響應報文包含了多個範圍的內容時使用。

3.5 獲取部分內容的範圍請求

如果下載過程中遇到網路中斷的情況,那就必須重頭開始。為了解決上述問題,需要一種可恢復的機制。所謂恢復是指能從之前下載中斷處恢復下載。

要實現該功能需要指定下載的實體範圍,指定範圍傳送的請求叫做範圍請求(Range Request)。針對範圍請求,響應會返回狀態碼 206。

比如:

  1. 5001~10 000 位元組:Range: bytes=5001-10000
  2. 從 5001 位元組之後全部的:Range: bytes=5001-
  3. 從一開始到 3000 位元組和 5000~7000 位元組的多重範圍:Range: bytes=-3000, 5000-7000

3.6 內容協商返回最合適的內容

內容協商機制是指客戶端和伺服器端就響應的資源內容進行交涉,然後提供給客戶端最為適合的資源。內容協商會以響應資源的語言、字符集、編碼方式等作為判斷的基準。

包含在請求報文中的某些首部欄位(如下)就是判斷的基準:AcceptAccept-CharsetAccept-EncodingAccept-LanguageContent-Language

有以下幾種型別:

  1. 伺服器驅動協商: 以請求的首部欄位為參考,在伺服器端自動處理。但對使用者來說,以瀏覽器傳送的資訊作為判定的依據,並不一定能篩選出最優內容。
  2. 客戶端驅動協商: 使用者從瀏覽器顯示的可選項列表中手動選擇。還可以利用 JavaScript 指令碼在 Web 頁面上自動進行上述選擇。比如按 OS 的型別或瀏覽器型別,自行切換成 PC 版頁面或手機版頁面。
  3. 透明協商: 是伺服器驅動和客戶端驅動的結合體,是由伺服器端和客戶端各自進行內容協商的一種方法。

4. 返回結果的 HTTP 狀態碼

狀態碼的職責是當客戶端向伺服器端傳送請求時,描述返回的請求結果。藉助狀態碼,使用者可以知道伺服器端是正常處理了請求,還是出現了錯誤。

4.1 狀態碼告知從伺服器端返回的請求結果

數字中的第一位指定了響應類別,後兩位無分類

類別 原因短語
1XX Informational(資訊性狀態碼) 接收的請求正在處理
2XX Success(成功狀態碼) 請求正常處理完畢
3XX Redirection(重定向狀態碼) 需要進行附加操作以完成請求
4XX Client Error(客戶端錯誤狀態碼) 伺服器無法處理請求
5XX Server Error(伺服器錯誤狀態碼) 伺服器處理請求出錯

4.2 2xx 成功

請求被正常處理了。

  1. 200 OK: 表示從客戶端發來的請求在伺服器端被正常處理了
  2. 204 No Content: 表示伺服器接收的請求已成功處理,但在返回的響應報文中不含實體的主體部分。另外,也不允許返回任何實體的主體。比如,當從瀏覽器發出請求處理後,返回 204 響應,那麼瀏覽器顯示的頁面不發生更新。一般在只需要從客戶端往伺服器傳送資訊,而對客戶端不需要傳送新資訊內容的情況下使用。
  3. 206 Partial Content: 表示客戶端進行了範圍請求,而伺服器成功執行了這部分的 GET 請求。響應報文中包含由 Content-Range 指定範圍的實體內容。

4.3 3XX 重定向

瀏覽器需要執行某些特殊的處理以正確處理請求。

  1. 301 Moved Permanently: 永久性重定向。該狀態碼錶示請求的資源已被分配了新的 URI,以後應使用資源現在所指的 URI。也就是說,如果已經把資源對應的 URI 儲存為書籤了,這時應該按 Location 首部欄位提示的 URI 重新儲存。
  2. 302 Found: 臨時性重定向。該狀態碼錶示請求的資源已被分配了新的 URI,希望使用者(本次)能使用新的 URI 訪問。已移動的資源對應的 URI 將來還有可能發生改變。
  3. 303 See Other: 表示由於請求對應的資源存在著另一個 URI,應使用 GET 方法定向獲取請求的資源。303 和 302 有著相同的功能,但 303 狀態碼明確表示客戶端應當採用 GET 方法獲取資源,這點與 302 狀態碼有區別。
  4. 304 Not Modified: 客戶端傳送 GET 方法的請求頭中包含 If-MatchIf-Modified-SinceIf-None-MatchIf-RangeIf-Unmodified-Since 中任一首部時,伺服器端允許請求訪問資源,但未滿足條件的情況。304 狀態碼返回時,不包含任何響應的主體部分。304 雖然被劃分在 3XX 類別中,但是和重定向沒有關係。
  5. 307 Temporary Redirect: 臨時重定向,與 302 Found 有著相同的含義。

4.4 4XX 客戶端錯誤

客戶端發生了錯誤。

  1. 400 Bad Request: 表示請求報文中存在語法錯誤。當錯誤發生時,需修改請求的內容後再次傳送請求。另外,瀏覽器會像 200 一樣對待該狀態碼。
  2. 401 Unauthorized: 表示傳送的請求需要有通過 HTTP 認證的認證資訊。若之前已進行過一次請求,則表示使用者認證失敗。返回含有 401 的響應必須包含一個適用於被請求資源的 WWW-Authenticate 首部用以質詢使用者資訊。當瀏覽器初次接收到 401 響應,會彈出認證用的對話視窗。
  3. 403 Forbidden: 對請求資源的訪問被伺服器拒絕了。伺服器端沒有必要給出拒絕的詳細理由,但如果想作說明的話,可以在實體的主體部分對原因進行描述,這樣就能讓使用者看到了。比如未獲得檔案系統的訪問授權、訪問許可權出現某些問題等情景。
  4. 404 Not Found: 伺服器上無法找到請求的資源。除此之外,也可以在伺服器端拒絕請求且不想說明理由時使用。

4.5 5XX 伺服器錯誤

伺服器本身發生錯誤。

  1. 500 Internal Server Error: 伺服器端在執行請求時發生了錯誤,也有可能是 Web 應用存在的 bug 或某些臨時的故障。
  2. 503 Service Unavailable: 表明伺服器暫時處於超負載或正在進行停機維護,現在無法處理請求。如果事先得知解除以上狀況需要的時間,最好寫入 RetryAfter 首部欄位再返回給客戶端。

5. 與 HTTP 協作的 Web 伺服器

一臺 Web 伺服器可搭建多個獨立域名的 Web 網站,也可作為通訊路徑上的中轉伺服器提升傳輸效率。

5.1 用單臺虛擬主機實現多個域名

HTTP1.1 規範允許一個伺服器搭建多個 Web 站點,這是虛擬主機(Virtual Host,又稱虛擬伺服器)功能。

如果一臺伺服器內託管了兩個域名,對應的同一個伺服器 IP,當收到請求時就需要弄清楚究竟要訪問哪個域名,由於虛擬主機可以寄存多個不同主機名和域名的 Web 網站,因此在傳送 HTTP 請求時,必須在 Host 首部內完整指定主機名或域名的 URI。

5.2 通訊資料轉發程式 :代理、閘道器、隧道

這些應用程式和伺服器可以將請求轉發給通訊線路上的下一站伺服器,並且能接收從那臺伺服器傳送的響應再轉發給客戶端。

  1. 代理: 接收客戶端傳送的請求後轉發給其他伺服器,。代理不改變請求 URI,會直接傳送給前方持有資源的目標伺服器。
    1. 快取代理:預先將資源快取儲存在代理伺服器上,當代理再次接收到對相同資源的請求時,就可以直接將之前快取的資源作為響應返回。
    2. 透明代理:轉發請求或響應時,不對報文做任何加工被稱為透明代理,對報文內容進行加工的稱為非透明代理。
  2. 閘道器: 轉發其他伺服器通訊資料的伺服器,接收從客戶端傳送來的請求時,它就像自己擁有資源的源伺服器一樣對請求進行處理。有時客戶端可能都不會察覺,自己的通訊目標是一個閘道器。閘道器能提高通訊的安全性,因為可以在客戶端與閘道器之間的通訊線路上加密以確保連線的安全。
  3. 隧道: 按要求建立起一條與其他伺服器的通訊線路,屆時使用 SSL 等加密手段進行通訊,在通訊雙方斷開連線時結束。。隧道的目的是確保客戶端能與伺服器進行安全的通訊。

5.3 儲存資源的快取

快取是指代理伺服器或客戶端本地儲存的資源副本,是代理伺服器的一種。

優勢在於避免多次從源伺服器轉發資源,客戶端可就近從快取伺服器上獲取資源,而源伺服器也不必多次處理相同請求。

客戶端的快取: 瀏覽器快取如果有效,不必再向伺服器請求,而直接從本地讀取。當判定快取過期後,會向源伺服器確認資源的有效性。若判斷瀏覽器快取失效,瀏覽器會再次請求新資源。

6. HTTP 首部

HTTP 協議的請求和響應報文中必定包含 HTTP 首部,請求報文大約是下面的結構,響應報文類似

《圖解 HTTP》 讀書筆記

6.1 HTTP 首部欄位

  1. 由首部欄位名和欄位值構成的,中間用冒號“:” 分隔
  2. 欄位值對應單個 HTTP 首部欄位可以有多個值

HTTP 首部欄位將定義成快取代理和非快取代理的行為,分成 2 種型別。

  1. 端到端首部: 分在此類別中的首部會轉發給請求 / 響應對應的最終接收目標,且必須儲存在由快取生成的響應中,另外規定它必須被轉發。
  2. 逐跳首部: 分在此類別中的首部只對單次轉發有效,會因通過快取或代理而不再轉發。HTTP1.1 和之後版本中,如果要使用 hop-by-hop 首部,需提供 Connection 首部欄位。

下面列舉了 HTTP1.1 中的逐跳首部欄位。除這 8 個首部欄位之外,其他所有欄位都屬於端到端首部。

  1. Connection
  2. Keep-Alive
  3. Proxy-Authenticate
  4. Proxy-Authorization
  5. Trailer
  6. TE
  7. Transfer-Encoding
  8. Upgrade

HTTP 首部根據用途被分為 4 種 HTTP 首部欄位型別,在 HTTP 協議通訊互動中使用到的首部欄位,不限於 RFC2616 中定義的 47 種。還有 Cookie、Set-Cookie 和 Content-Disposition 等在其他 RFC 中定義的,使用頻率也很高。

通用首部欄位

請求報文和響應報文兩方都會使用的首部。

首部欄位名 說明
Cache-Control 控制快取的行為
Connection 逐跳首部、連線的管理
Date 建立報文的日期時間
Pragma 報文指令
Trailer 報文末端的首部一覽
Transfer-Encoding 指定報文主體的傳輸編碼方式
Upgrade 升級為其他協議
Via 代理伺服器的相關資訊
Warning 錯誤通知

請求首部欄位

從客戶端向伺服器端傳送請求報文時使用的首部。補充了請求的附加內容、客戶端資訊、響應內容相關優先順序等資訊。

首部欄位名 說明
Accept 使用者代理可處理的媒體型別
Accept-Charset 優先的字符集
Accept-Encoding 優先的內容編碼
Accept-Language 優先的語言(自然語言)
Authorization Web認證資訊
Expect 期待伺服器的特定行為
From 使用者的電子郵箱地址
Host 請求資源所在伺服器
If-Match 比較實體標記(ETag)
If-Modified-Since 比較資源的更新時間
If-None-Match 比較實體標記(與 If-Match 相反)
If-Range 資源未更新時傳送實體 Byte 的範圍請求
If-Unmodified-Since 比較資源的更新時間(與If-Modified-Since相反)
Max-Forwards 最大傳輸逐跳數
Proxy-Authorization 代理伺服器要求客戶端的認證資訊
Range 實體的位元組範圍請求
Referer 對請求中 URI 的原始獲取方
TE 傳輸編碼的優先順序
User-Agent HTTP 客戶端程式的資訊

響應首部欄位

從伺服器端向客戶端返回響應報文時使用的首部。補充了響應的附加內容,也會要求客戶端附加額外的內容資訊。

首部欄位名 說明
Accept-Ranges 是否接受位元組範圍請求
Age 推算資源建立經過時間
ETag 資源的匹配資訊
Location 令客戶端重定向至指定URI
Proxy-Authenticate 代理伺服器對客戶端的認證資訊
Retry-After 對再次發起請求的時機要求
Server HTTP伺服器的安裝資訊
Vary 代理伺服器快取的管理資訊
WWW-Authenticate 伺服器對客戶端的認證資訊

實體首部欄位

針對請求報文和響應報文的實體部分使用的首部。補充了資源內容更新時間等與實體有關的資訊。

首部欄位名 說明
Allow 資源可支援的HTTP方法
Content-Encoding 實體主體適用的編碼方式
Content-Language 實體主體的自然語言
Content-Length 實體主體的大小(單位:位元組)
Content-Location 替代對應資源的URI
Content-MD5 實體主體的報文摘要
Content-Range 實體主體的位置範圍
Content-Type 實體主體的媒體型別
Expires 實體主體過期的日期時間
Last-Modified 資源的最後修改日期時間

6.2 HTTP1.1 通用首部欄位

通用首部欄位是指請求報文和響應報文都會使用的首部。

Cache-Control

  1. no-cache: 防止從快取中返回過期的資源。客戶端請求如果包含 no-cache,表示客戶端將不會接收快取過的響應,快取伺服器必須把客戶端請求轉發給源伺服器。伺服器響應中包含 no-cache,那麼快取伺服器不能對資源進行快取,源伺服器以後也將不再對快取伺服器請求中提出的資源有效性進行確認,且禁止其對響應資源進行快取操作。
  2. no-store: 快取不能在本地儲存請求或響應的任一部分。

從字面意思上很容易把 no-cache 誤解成為不快取,但 no-cache 代表不快取過期的資源,快取會向源伺服器進行有效期確認後處理資源,no-store 才是真正地不進行快取。

Connection

  1. 控制不再轉發給代理的首部欄位: 在客戶端傳送請求和伺服器返回響應內,使用 Connection 首部欄位,可控制不再轉發給代理的首部欄位(即 Hop-by-hop 首部)。
  2. 管理持久連線: HTTP1.1 預設持久連線,客戶端會在持久連線上連續傳送請求。伺服器端想斷開連線時,則設定 Connection 首部欄位為 Close。HTTP1.1 之前預設都是非持久連線。為此,如果想在舊版本 HTTP 協議上持續連線,則需設定 Connection 首部欄位為 Keep-Alive

Date

表明建立 HTTP 報文的日期和時間。

Upgrade

用於檢測 HTTP 協議及其他協議是否可使用更高的版本進行通訊,其引數值可以用來指定一個完全不同的通訊協議。

6.3 請求首部欄位

從客戶端往伺服器端傳送請求報文中所使用的欄位,用於補充請求的附加資訊、客戶端資訊、對響應內容相關的優先順序等內容。

Accept

通知伺服器,使用者代理能夠處理的媒體型別及媒體型別的相對優先順序。可使用 type/subtype 這種形式,一次指定多種媒體型別。

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
複製程式碼

Host

告知伺服器,請求的資源所處的網際網路主機名和埠號。Host 首部欄位在 HTTP1.1 規範內是唯一一個必須被包含在請求內的首部欄位。

請求被髮送至伺服器時,主機名會直接用 IP 地址。但如果這時,相同的 IP 地址下部署多個域名,那麼伺服器就會無法理解究竟是哪個域名對應的請求。因此,就需要使用首部欄位 Host 來明確指出請求的主機名。若伺服器未設定主機名,那直接設空值即可。

If-Match

形如 If-xxx 這種,都可稱為條件請求。伺服器接收到後,只有判斷指定條件為真時,才會執行請求。

首部欄位 If-Match,屬附帶條件之一,它會告知伺服器匹配資源所用的實體標記(ETag)值。這時的伺服器無法使用弱 ETag 值。伺服器會比對 If-Match 的欄位值和資源的 ETag 值,僅當兩者一致時,才會執行請求。

可以用星號 *,伺服器會忽略 ETag 的值,只要資源存在就處理請求。

If-None-Match

If-Match 作用相反,用於指定 If-None-Match 的實體標記 ETag 值與請求資源的 ETag 不一致時,它就告知伺服器處理該請求。

If-Modified-Since

如果在 If-Modified-Since 欄位指定的日期時間後資源發生了更新,伺服器會接受請求。

指定 If-Modified-Since 欄位值的日期時間之後,請求的資源在給定的日期時間之後對內容進行過修改的情況下才會將資源返回,狀態碼為 200,如果請求的資源沒有更新,則返回狀態碼 304 Not Modified 的響應。

If-Unmodified-Since

If-Unmodified-SinceIf-Modified-Since 的作用相反。它的作用的是告知伺服器,指定的請求資源只有在指定日期時間之後未發生更新,才處理請求。如果在指定日期時間後發生了更新,則以狀態碼 412 Precondition Failed 作為響應返回。

If-Range

If-Range 欄位如果跟 ETag 值或更新的日期時間一致,那麼就作為範圍請求處理。反之,則返回全體資源。

6.4 響應首部欄位

由伺服器端向客戶端返回響應報文中所使用的欄位,用於補充響應的附加資訊、伺服器資訊,以及對客戶端的附加要求等資訊。

ETag

實體標識,將資源以字串形式做唯一性標識的方式。伺服器會為每份資源分配對應的 ETag 值。當資源更新時,ETag 值也需要更新。

若在下載過程中出現連線中斷、再連線的情況,都會依照 ETag 值來指定資源。

6.5 實體首部欄位

包含在請求報文和響應報文中的實體部分所使用的首部,用於補充內容的更新時間等與實體相關的資訊。

Allow

通知客戶端能夠支援的所有 HTTP 方法。當伺服器接收到不支援的 HTTP 方法時,會以狀態碼 405 Method Not Allowed 作為響應返回。與此同時,還會把所有能支援的 HTTP 方法寫入首部欄位 Allow 後返回。

Content-Encoding

告知客戶端伺服器對實體的主體部分選用的內容編碼方式。內容編碼是指在不丟失實體資訊的前提下所進行的壓縮。

主要有:gzip、compress、deflate、identity

Content-Length

表明了實體主體部分的大小(單位是位元組)。對實體主體進行內容編碼傳輸時,不能再使用 Content-Length 首部欄位。

Content-Type

說明了實體主體內物件的媒體型別,用 type/subtype 形式賦值。

Content-Type: text/html; charset=UTF-8
複製程式碼

Expires

Expires 會將資源失效的日期告知客戶端。快取伺服器在收到有 Expires 的響應後,會以快取來應答請求,在 Expires 欄位值指定的時間之前,響應的副本會一直被儲存。當超過指定的時間後,快取伺服器在請求傳送過來時,會轉向源伺服器請求資源。

源伺服器不希望快取伺服器對資源快取時,最好在 Expires 欄位內寫入與 Date 相同的時間值。

但是,當首部欄位 Cache-Control 有指定 max-age 時,比起 Expires,會優先處理 max-age 指令。

Last-Modified

包含源頭伺服器認定的資源做出修改的日期及時間。

6.6 為 Cookie 服務的首部欄位

首部欄位名 說明 首部型別
Set-Cookie 開始狀態管理所使用的Cookie資訊 響應首部欄位
Cookie 伺服器接收到的Cookie資訊 請求首部欄位

Set-Cookie

Set-Cookie: status=enable; expires=Tue, 05 Jul 2011 07:26:31 GMT; path=/; domain=.hackr.jp;	
複製程式碼
屬性 說明
NAME=VALUE 賦予 Cookie 的名稱和其值(必需項)
expires=DATE Cookie 的有效期(若不明確指定則預設為瀏覽器關閉前為止)
path=PATH 將伺服器上的檔案目錄作為Cookie的適用物件(若不指定則預設為文件所在的檔案目錄)
domain=域名 作為 Cookie 適用物件的域名 (若不指定則預設為建立 Cookie 的伺服器的域名)
Secure 僅在 HTTPS 安全通訊時才會傳送 Cookie
HttpOnly 加以限制,使 Cookie 不能被 JavaScript 指令碼訪問

一旦 Cookie 從伺服器端傳送至客戶端,伺服器端就沒有顯式刪除 Cookie 的方法。但可通過覆蓋已過期的 Cookie,實現對客戶端 Cookie 的實質性刪除操作。

HttpOnly 屬性是 Cookie 的擴充套件功能,它使 JavaScript 指令碼無法獲得 Cookie。其主要目的為防止跨站指令碼攻擊(Cross-site scripting,XSS)對 Cookie 的資訊竊取。

Cookie

Cookie: status=enable
複製程式碼

當客戶端想獲得 HTTP 狀態管理支援時,就會在請求中包含從伺服器接收到的 Cookie。

6.7 其他首部欄位

X-XSS-Protection

是針對跨站指令碼攻擊(XSS)的一種對策,用於控制瀏覽器 XSS 防護機制的開關,可指定的欄位值如下

  • 0:將 XSS 過濾設定成無效狀態
  • 1:將 XSS 過濾設定成有效狀態

7. 確保 Web 安全的 HTTPS

HTTP 協議中有可能存在資訊竊聽或身份偽裝等安全問題,使用 HTTPS 可以有效地防止這些問題。

7.1 HTTP 的缺點

  1. 通訊使用明文(不加密),內容可能會被竊聽
  2. 不驗證通訊方的身份,因此有可能遭遇偽裝
  3. 無法證明報文的完整性,所以有可能已遭篡改

7.2 HTTP+ 加密 + 認證 + 完整性保護 = HTTPS

把新增了加密及認證機制的 HTTP 稱為 HTTPS(HTTP Secure)。HTTPS 並非是應用層的一種新協議,只是 HTTP 通訊介面部分用 SSL(Secure Socket Layer)和 TLS(Transport Layer Security)協議代替而已。SSL 是獨立於 HTTP 的協議,所以其他執行在應用層的 SMTP 和 Telnet 等協議均可配合 SSL 協議使用。

《圖解 HTTP》 讀書筆記

HTTPS 採用共享金鑰加密和公開金鑰加密兩者並用的混合加密機制。若金鑰能夠實現安全交換,那麼有可能會考慮僅使用公開金鑰加密來通訊。但是公開金鑰加密與共享金鑰加密相比,其處理速度要慢。

所以取長補短,在交換金鑰環節使用公開金鑰加密方式,之後的建立通訊交換報文階段則使用共享金鑰加密方式。

數字證照認證機構(CA,Certificate Authority)和其相關機關頒發的公開金鑰證照就是認證的可以信賴的公開金鑰,伺服器會將這份由數字證照認證機構頒發的公鑰證照傳送給客戶端,以進行公開金鑰加密方式通訊。公鑰證照也可叫做數字證照或直接稱為證照。

《圖解 HTTP》 讀書筆記

HTTPS 通訊的步驟:

  1. 客戶端通過傳送 Client Hello 報文開始 SSL 通訊。報文中包含客戶端支援的 SSL 的指定版本、加密元件(Cipher Suite)列表(所使用的加密演算法及金鑰長度等)。
  2. 伺服器可進行 SSL 通訊時,會以 Server Hello 報文作為應答。和客戶端一樣,在報文中包含 SSL 版本以及加密元件。伺服器的加密元件內容是從接收到的客戶端加密元件內篩選出來的。
  3. 之後伺服器傳送 Certificate 報文。報文中包含公開金鑰證照。
  4. 最後伺服器傳送 Server Hello Done 報文通知客戶端,最初階段的 SSL 握手協商部分結束。
  5. SSL 第一次握手結束之後,客戶端以 Client Key Exchange 報文作為迴應。報文中包含通訊加密中使用的一種被稱為 Pre-master secret 的隨機密碼串。該報文已用步驟 3 中的公開金鑰進行加密。
  6. 接著客戶端繼續傳送 Change Cipher Spec 報文。該報文會提示伺服器,在此報文之後的通訊會採用 Pre-master secret 金鑰加密。
  7. 客戶端傳送 Finished 報文。該報文包含連線至今全部報文的整體校驗值。這次握手協商是否能夠成功,要以伺服器是否能夠正確解密該報文作為判定標準。
  8. 伺服器同樣傳送 Change Cipher Spec 報文。
  9. 伺服器同樣傳送 Finished 報文。
  10. 伺服器和客戶端的 Finished 報文交換完畢之後,SSL 連線就算建立完成。當然,通訊會受到 SSL 的保護。從此處開始進行應用層協議的通訊,即傳送 HTTP 請求。
  11. 應用層協議通訊,即傳送 HTTP 響應。
  12. 最後由客戶端斷開連線。斷開連線時,傳送 close_notify 報文。上圖做了一些省略,這步之後再傳送 TCP FIN 報文來關閉與 TCP 的通訊。

《圖解 HTTP》 讀書筆記

在以上流程中,應用層傳送資料時會附加一種叫做 MAC(Message Authentication Code)的報文摘要。MAC 能夠查知報文是否遭到篡改,從而保護報文的完整性。

SSL 速度慢嗎

HTTPS 也存在一些問題,那就是當使用 SSL 時,它的處理速度會變慢。它慢分兩種。一種是指通訊慢。另一種是指由於大量消耗 CPU 及記憶體等資源,導致處理速度變慢。

和 HTTP 相比,HTTPS 網路負載可能會變慢 2 到 100 倍。除去和 TCP 連線、傳送 HTTP 請求響應以外,還必須進行 SSL 通訊,因此整體上處理通訊量不可避免會增加。另外 SSL 必須進行加密處理,在伺服器和客戶端都需要進行加解密處理,比 HTTP 消耗更多硬體資源,導致負載增強。

針對速度變慢這一問題,並沒有根本性的解決方案,一般會使用 SSL 加速器這種(專用伺服器)硬體。能提高數倍 SSL 的計算速度,僅在 SSL 處理時發揮功效,分擔負載。

沒使用 HTTPS 的原因

與純文字通訊相比,加密通訊會消耗更多的 CPU 及記憶體資源。如果每次通訊都加密,會消耗相當多的資源,平攤到一臺計算機上時,能夠處理的請求數量必定也會隨之減少。

如果是非敏感資訊則使用 HTTP 通訊,只有在包含個人資訊等敏感資料時,才利用 HTTPS 加密通訊。可以僅在那些需要資訊隱藏時才加密,以節約資源。

除此之外,想要節約購買證照的開銷也是原因之一。

8. 確認訪問使用者身份的認證

一些頁面只想讓特定的人瀏覽,這就引入了認證功能。

HTTP1.1 常用的認證方式:

  1. BASIC 認證(基本認證)
  2. DIGEST 認證(摘要認證)
  3. SSL 客戶端認證
  4. FormBase 認證(基於表單認證)

9. 基於 HTTP 的功能追加協議

9.1 全雙工通訊的 WebSocket

連線的發起方仍是客戶端,一旦確立 WebSocket 通訊連線,伺服器與客戶端任意一方都可向對方傳送報文。

  1. 推送功能: 支援由伺服器向客戶端推送資料的推送功能。這樣,伺服器可直接傳送資料,而不必等待客戶端的請求。
  2. 減少通訊量: 和 HTTP 相比,不但每次連線時的開銷減少,且由於首部資訊很小,通訊量也減少了。

通訊的建立:

  1. 首先使用 HTTP 的 Upgrade 首部欄位,告知伺服器通訊協議發生改變,進行握手。

    GET /chat HTTP/1.1
    Host: server.example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Origin: http://example.com
    Sec-WebSocket-Protocol: chat, superchat
    Sec-WebSocket-Version: 13
    複製程式碼

    Sec-WebSocket-Key 欄位內記錄著握手過程中必不可少的鍵值。Sec-WebSocket-Protocol 欄位內記錄使用的子協議。

  2. 之前的請求將會被返回 101 Switching Protocols 響應

    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
    Sec-WebSocket-Protocol: chat
    複製程式碼

    Sec-WebSocket-Accept 的欄位值是由握手請求中的 Sec-WebSocket-Key 的欄位值生成的。

    成功握手建立 WebSocket 連線之後,通訊時不再使用 HTTP 的資料幀,而採用 WebSocket 獨立的資料幀。

《圖解 HTTP》 讀書筆記

9.2 HTTP/2.0

HTTP/2.0 的目標是改善使用者在使用 Web 時的速度體驗。特點:

  1. HTTP/2.0 採用二進位制格式而非文字格式
  2. HTTP/2.0 是完全多路複用的,而非有序並阻塞的——只需一個連線即可實現並行
  3. 使用報頭壓縮,HTTP/2.0 降低了開銷
  4. HTTP/2.0 讓伺服器可以將響應主動“推送”到客戶端快取中

10. 構建 Web 內容的技術

10.1 HTML

HTML(HyperText Markup Language,超文字標記語言)是為了傳送 Web 上的超文字(Hypertext)而開發的標記語言。

超文字是一種文件系統,可將文件中任意位置的資訊與其他資訊(文字或圖片等)建立關聯,即超連結文字。

10.2 Web 應用

Web 應用是指通過 Web 功能提供的應用程式。

CGI 每次接到請求,都要跟著啟動一次,一旦訪問量過大,Web 伺服器要承擔相當大的負載。而 Servlet 執行在與 Web 伺服器相同的程式中,因此受到的負載較小。

Servlet 的執行環境叫做 Web 容器或 Servlet 容器。隨著 CGI 的普及,每次請求都要啟動新 CGI 程式的 CGI 執行機制逐漸變成了效能瓶頸。而 Servlet 常駐記憶體,在每次請求時,可啟動相對程式級別更為輕量的 Servlet,程式的執行效率從而變得更高。

11. Web 的攻擊技術

11.1 針對 Web 的攻擊技術

HTTP 協議本身並不存在安全性問題,伺服器和客戶端以及執行在伺服器上的 Web 應用等資源才是攻擊目標。

HTTP 就是一個通用的單純協議機制,開發者需要自行設計並開發認證及會話管理功能來滿足 Web 應用的安全,因此在執行的應用會隱藏著各種容易被攻擊者濫用的安全漏洞。

在客戶端即可篡改請求

從瀏覽器那接收到的 HTTP 請求的全部內容,都可以在客戶端自由地變更、篡改。所以 Web 應用接受到的內容可能與預期資料不同。

在 HTTP 請求報文內載入攻擊程式碼,就能發起對 Web 應用的攻擊。通過 URL 查詢欄位或表單、HTTP 首部、Cookie 等途徑把攻擊程式碼傳入,若這時 Web 應用存在安全漏洞,那內部資訊就會遭到竊取,或被攻擊者拿到管理許可權。

針對 Web 應用的攻擊模式

對 Web 攻擊的模式有主動攻擊和被動攻擊兩種

主動攻擊

指攻擊者通過直接訪問 Web 應用,把攻擊程式碼傳入的攻擊模式。由於該模式是直接針對伺服器上的資源進行攻擊,因此攻擊者需要能夠訪問到那些資源。

代表性的是 SQL 注入攻擊OS 命令注入攻擊

被動攻擊

指利用圈套策略執行攻擊程式碼的攻擊模式。在被動攻擊過程中,攻擊者不直接對目標 Web 應用訪問發起攻擊。

代表性的是跨站指令碼攻擊跨站點請求偽造

通常的攻擊步驟

  1. 攻擊者誘使使用者觸發已設定好的陷阱,而陷阱會啟動傳送已嵌入攻擊程式碼的 HTTP 請求。
  2. 當使用者不知不覺中招之後,使用者的瀏覽器或郵件客戶端就會觸發這個陷阱。
  3. 中招後的使用者瀏覽器會把含有攻擊程式碼的 HTTP 請求傳送給作為攻擊目標的 Web 應用,執行攻擊程式碼。
  4. 執行完攻擊程式碼,存在安全漏洞的 Web 應用會成為攻擊者的跳板,可能導致使用者所持的 Cookie 等個人資訊被竊取,登入狀態中的使用者許可權遭惡意濫用等後果。

《圖解 HTTP》 讀書筆記

11.2 因輸出值轉義不完全引發的安全漏洞

驗證主要有兩種:

  1. 客戶端的驗證
  2. Web 應用端(伺服器端)的驗證,包括輸入值驗證和輸出值轉義

一般驗證資料是在客戶端使用 JS,然而客戶端的指令碼是可以篡改的,所以不適合作為安全對策。

從資料庫或檔案系統、HTML、郵件等輸出需處理的資料的時候,針對輸出做值轉義處理是一項至關重要的安全策略。當輸出值轉義不完全時,會觸發攻擊者傳入的攻擊程式碼。

XSS 跨站指令碼攻擊

跨站指令碼攻擊(Cross-Site Scripting,XSS)是指通過存在安全漏洞的客戶端執行非法的 HTML 標籤或 JavaScript 進行的一種攻擊。動態建立的 HTML 部分有可能隱藏著安全漏洞。

如果使用者填寫的表單是直接作為 HTML 解析,那麼換成 script 標籤,就中招了。

SQL 注入攻擊

SQL 注入(SQL Injection)是指標對 Web 應用使用的資料庫,通過執行非法的 SQL 而產生的攻擊。

如果在呼叫 SQL 語句的方式上存在疏漏,就可能被惡意注入(Injection)非法的 SQL 語句。

比如,如果把表單查詢的欄位直接拼接給 SQL 語句,那麼可能會出現下面這個情況

上面一句查詢的是 上野宣,下面一句查詢 上野宣'--

SELECT * FROM bookTbl WHERE author = '上野宣' and flag = 1;
SELECT * FROM bookTbl WHERE author = '上野宣'--' and flag = 1;
複製程式碼

SQL 語句中的 -- 之後全視為註釋,因此 and flag=1 這個條件被自動忽略了,失去過濾條件,不想顯示的內容也被顯示出來了。

OS 命令注入攻擊

OS 命令注入攻擊(OS Command Injection)是指通過 Web 應用,執行非法的作業系統命令達到攻擊的目的。只要在能呼叫 Shell 函式的地方就有存在被攻擊的風險。

HTTP 首部注入攻擊

HTTP 首部注入攻擊(HTTP Header Injection)是指攻擊者通過在響應首部欄位內插入換行,新增任意響應首部或主體的一種攻擊。屬於被動攻擊模式。

向首部主體內新增內容的攻擊稱為 HTTP 響應截斷攻擊(HTTP Response Splitting Attack)。

比如有時候 Web 應用有時會把從外部收到的值,賦給響應首部欄位 LocationSet-Cookie。如果攻擊者傳送 101%0D%0ASet-Cookie:+SID=123456789 這裡的 %0D%0A 代表的是換行符,那麼就會導致結果返回:

Location: http://example.com/?cat=101(%0D%0A :換行符)
Set-Cookie: SID=123456789
複製程式碼

這裡攻擊者就可以修改任意的 Cookie 資訊了。

這個例子中,原本應該屬於首部欄位 Location 的查詢值部分,攻擊者輸入的 %0D%0A 成了換行符,結果插入了新的首部欄位,實際上攻擊者可以在響應中插入任意的首部欄位。

HTTP 響應截斷攻擊

HTTP 響應截斷攻擊是用在 HTTP 首部注入的一種攻擊。

攻擊順序相同,但是要將兩個 %0D%0A%0D%0A 並排插入字串後傳送。利用這兩個連續的換行就可作出 HTTP 首部與主體分隔所需的空行了,這樣就能顯示偽造的主體,達到攻擊目的。

Set-Cookie: UID=(%0D%0A :換行符)
(%0D%0A :換行符)
<HTML><HEAD><TITLE>之後,想要顯示的網頁內容 <!-- (原來頁面對應的首部欄位和主體部分全視為註釋)
複製程式碼

利用這個攻擊,已觸發陷阱的使用者瀏覽器會顯示偽造的 Web 頁面,再讓使用者輸入自己的個人資訊等,可達到和跨站指令碼攻擊相同的效果。

郵件首部注入攻擊

郵件首部注入(Mail Header Injection)是指 Web 應用中的郵件傳送功能,攻擊者通過向郵件首部 To 或 Subject 內任意新增非法內容發起的攻擊。利用存在安全漏洞的 Web 網站,可對任意郵件地址傳送廣告郵件或病毒郵件。

目錄遍歷攻擊

目錄遍歷(Directory Traversal)攻擊是指對本無意公開的檔案目錄,通過非法截斷其目錄路徑後,達成訪問目的的一種攻擊。這種攻擊有時也稱為路徑遍歷(Path Traversal)攻擊。

通過 Web 應用對檔案處理操作時,在由外部指定檔名的處理存在疏漏的情況下,使用者可使用 .../ 等相對路徑定位到 /etc/passed 等絕對路徑上,因此伺服器上任意的檔案或檔案目錄皆有可能被訪問到。這樣一來,就有可能非法瀏覽、篡改或刪除 Web 伺服器上的檔案。

http://example.com/read.php?log=0401.log
http://example.com/read.php?log=../../etc/passwd
複製程式碼

遠端檔案包含漏洞

遠端檔案包含漏洞(Remote File Inclusion)是指當部分指令碼內容需要從其他檔案讀入時,攻擊者利用指定外部伺服器的 URL 充當依賴檔案,讓指令碼讀取之後,就可執行任意指令碼的一種攻擊。

11.3 因設定或設計上的缺陷引發的安全漏洞

強制瀏覽

對那些原本不願公開的檔案,為了保證安全會隱蔽其 URL。可一旦知道了那些 URL,也就意味著可瀏覽 URL 對應的檔案。比如

http://www.example.com/entry/entry_081202.log
複製程式碼

這樣一個路徑,就很容易推測出下一個檔案是 entry_081203.log,從而被訪問。

不正確的錯誤訊息處理

不正確的錯誤訊息處理(Error Handling Vulnerability)的安全漏洞是指,Web 應用的錯誤資訊內包含對攻擊者有用的資訊。與 Web 應用有關的主要錯誤資訊如下所示:

  1. Web 應用丟擲的錯誤訊息 Web 應用不必在使用者的瀏覽畫面上展現詳細的錯誤訊息。對攻擊者來說,詳細的錯誤訊息有可能給他們下一次攻擊以提示。
  2. 資料庫等系統丟擲的錯誤訊息 攻擊者從某些錯誤訊息中可讀出資料庫選用的型別,有時還可看見 SQL 語句的片段。這可能給攻擊者進行 SQL 注入攻擊以啟發。系統應對詳細的錯誤訊息進行抑制設定,或使用自定義錯誤訊息。

開放重定向

開放重定向(Open Redirect)是一種對指定的任意 URL 作重定向跳轉的功能。而於此功能相關聯的安全漏洞是指,假如指定的重定向 URL 到某個具有惡意的 Web 網站,那麼使用者就會被誘導至那個 Web 網站。比如:

http://example.com/?redirect=http://www.tricorder.jp
http://example.com/?redirect=http://hackr.jp
複製程式碼

可信度高的 Web 網站如果開放重定向功能,則會被攻擊者用來作為釣魚攻擊的跳板。

11.4 因會話管理疏忽引發的安全漏洞

會話劫持

會話劫持(Session Hijack)是指攻擊者通過某種手段拿到了使用者的會話 ID,並非法使用此會話 ID 偽裝成使用者,達到攻擊的目的。

會話劫持

攻擊者在得知該 Web 網站存在可跨站攻擊 XSS 的安全漏洞後,就設定好用 JavaScript 指令碼呼叫 document.cookie 以竊取 Cookie 資訊的陷阱,獲取含有會話 ID 的 Cookie。

拿到使用者的會話 ID 後,往自己的瀏覽器的 Cookie 中設定該會話 ID,即可偽裝成會話 ID 遭竊的使用者,訪問 Web 網站。

《圖解 HTTP》 讀書筆記

會話固定攻擊

對以竊取目標會話 ID 為主動攻擊手段的會話劫持而言,會話固定攻擊(Session Fixation)攻擊會強制使用者使用攻擊者指定的會話 ID,屬於被動攻擊。

《圖解 HTTP》 讀書筆記

攻擊者設定好強制使用者使用該會話 ID 的陷阱,並等待使用者拿著這個會話 ID 前去認證。一旦使用者觸發陷阱並完成認證,會話在伺服器上的狀態(使用者 A 已認證)就會被記錄下來,再利用之前這個會話 ID 訪問網站。

CSRF 跨站點請求偽造

跨站點請求偽造(Cross-Site Request Forgeries,CSRF)攻擊是指攻擊者通過設定好的陷阱,強制對已完成認證的使用者進行非預期的個人資訊或設定資訊等某些狀態更新,屬於被動攻擊。

《圖解 HTTP》 讀書筆記

比如這個留言板功能,只允許已認證並登入的使用者發表內容。使用者的 Cookie 持有已認證的會話 ID。使用者如果點選了攻擊者留下的惡意程式碼連結,則會利用使用者的資訊執行操作。

11.5 其他安全漏洞

密碼破解

密碼破解攻擊(Password Cracking)即算出密碼,突破認證。

通過網路進行密碼試錯主要有下面兩種方式:

  1. 窮舉法(Brute-force Attack,又稱暴力破解法)是指對所有金鑰集合構成的金鑰空間(Keyspace)進行窮舉。
  2. 字典攻擊是指利用事先收集好的候選密碼(經過各種組合方式後存入字典),列舉字典中的密碼,嘗試通過認證的一種攻擊手法。

字典攻擊中有一種利用其他 Web 網站已洩露的 ID 及密碼列表進行的攻擊,因為很多使用者習慣隨意地在多個 Web 網站使用同一套 ID 及密碼。

對已加密密碼的破解通常有下面幾種方法:

  1. 通過窮舉法/字典攻擊進行類推
  2. 彩虹表
  3. 拿到金鑰
  4. 加密演算法的漏洞

點選劫持

點選劫持(Clickjacking)是指利用透明的按鈕或連結做成陷阱,覆蓋在 Web 頁面之上。然後誘使使用者在不知情的情況下,點選那個連結訪問內容的一種攻擊手段。這種行為又稱為介面偽裝(UI Redressing)。

已設定陷阱的 Web 頁面,表面上內容並無不妥,但早已埋入想讓使用者點選的連結。當使用者點選到透明的按鈕時,實際上是點選了已指定透明屬性元素的 iframe 頁面。

DoS 攻擊

DoS 攻擊(Denial of Service attack)是一種讓執行中的服務呈停止狀態的攻擊。有時也叫做服務停止攻擊或拒絕服務攻擊。DoS 攻擊的物件不僅限於 Web 網站,還包括網路裝置及伺服器等。

  1. 集中利用訪問請求造成資源過載,比如傳送大量的合法請求
  2. 通過攻擊安全漏洞使服務停止。

後門程式

後門程式(Backdoor)是指開發設定的隱藏入口,可不按正常步驟使用受限功能。利用後門程式就能夠使用原本受限制的功能。

可通過監視程式和通訊的狀態發現被植入的後門程式。但設定在 Web 應用中的後門程式,由於和正常使用時區別不大,通常很難發現。


PS:歡迎大家關注我的公眾號【前端下午茶】,一起加油吧~

《圖解 HTTP》 讀書筆記

相關文章