中間人攻擊是一種常見的攻擊手段,攻擊者與通訊雙方分別創建鏈接,將雙方想要交換的數據進行記錄、篡改甚至丟棄。因爲Http是明文傳輸,所以很容易遭受到中間人攻擊。html
這是一個典型的中間人攻擊的過程,在Http中,Tom是客戶端,Jerry是服務端,而郵遞員就是客戶端跟服務端之間的實體(包括代理服務器,路由器、反向代理服務器等),兩把鑰匙分別是公鑰和私鑰。通訊雙方並不知道且很難發覺本身其實在和中間人攻擊而非對方。在通訊過程當中,Tom和Jerry並無驗證對方的身份,這就致使了郵遞員能夠任意查看、修改或者丟棄雙方的通訊內容。sql
用私鑰對某個文件/某段消息的散列值進行簽名就像一我的親手在信件最後簽上本身的名字同樣,證實這份文件/這段消息確實來自本身的擁有者(由於公鑰是公開的,私鑰只有擁有者知道,因此若是能用其公開的公鑰解開數字簽名,那就證實這條消息確實來自於私鑰的擁有者),這就能夠確保消息是來自他所聲稱的那個實體。瀏覽器
不過有個問題,若是中間人在會話創建階段把雙方交換的真實公鑰替換成本身的公鑰,那麼中間人仍是能夠篡改消息的內容而雙方不知情。爲了解決這個問題,須要找一個第三方來爲雙方確認身份。即數字證書跟CA(數字證書認證機構)。安全
數字證書就是申請人將一些必要的信息(包括公鑰、姓名、電子郵件、有效期)等提供給CA,CA在經過各類手段確認申請人確實是他所聲稱的人以後,用本身的私鑰對申請人所提供信息計算散列值進行加密,造成數字簽名,附在證書最後,再將數字證書頒發給申請人,申請人就可使用CA的證書想別人證實本身的身份了。對方收到數字證書以後,只須要用CA的公鑰解密證書最後的簽名獲得加密以前的散列值,同計算數字證書中的信息的散列值,將二者進行對比,只要散列值一致,就證實這張數字證書是有效切且未被篡改。服務器
通訊過程當中的安全性自下而上就是這樣保證的:網絡
HTTP協議最初的時候是明文的,由於安全問題因此如今不少網站都在逐漸過渡到HTTPS,然而對於大部分使用者來講,他們並不知道HTTP和HTTPS的以前的區別,在瀏覽器輸入地址的時候都是直接輸入www.example.com
而非https://www.example.com
,在大部分狀況下,若是一個網站使用了HTTPS,服務器會將這個請求使用301
或者302
狀態碼以及一個Location
頭部鍵將請求從80
端口重定向至使用HTTPS的443
端口,可是,若是中間人劫持了使用者的網絡請求,那麼中間人能夠阻止客戶端與服務器創建HTTPS鏈接,而是一直使用不安全的HTTP鏈接,而中間人和服務器創建正常的HTTP鏈接,讓客戶端覺得本身和真實服務器通訊。這種攻擊手法稱做SSLTrip
。mybatis
爲了而解決這個問題,IETF(互聯網工程任務小組)引入了一個策略,叫作HSTS(HTTP Strict Transport Security,HTTP嚴格傳輸安全)。HSTS的做用是強制客戶端與服務端創建安全的HTTPS鏈接,而非不安全的HTTP鏈接。若是一個站點啓用了HSTS策略,那麼客戶端在第一次與該站點創建鏈接以後,在爲來一段時間內(由一個HTTP頭部控制,這個頭部爲:Strict-Transport-Security),客戶端與該站點的全部鏈接都會直接使用HTTPS,即便客戶端訪問的是HTTP,也會直接在客戶端重定向到HTTPS鏈接。框架
若是站點沒有啓用HSTS,用戶能夠忽略證書無效(域名對不上、自簽名、不在有效期)的警告,繼續創建鏈接,而若是站點啓用了 HSTS,那麼用戶即便想冒風險,瀏覽器也不會繼續訪問。分佈式
HSTS 能夠很大程度上防止 SSLTrip 攻擊,不過這樣仍是有個問題,那就是要啓用 HSTS,瀏覽器至少要和服務器創建一次 HTTPS 鏈接,若是中間人一直阻止瀏覽器與服務器創建 HTTPS 鏈接,那麼 HSTS 就失效了。解決這個問題有個辦法,那就是將 HSTS 站點列表內置到瀏覽器中,這樣只要瀏覽器離線判斷該站點啓用了 HSTS,就會跳過原先的 HTTP 重定向,直接發起 HTTPS 請求。網站
本內容摘自:
HTTPS中間人攻擊及其防範
DDoS的攻擊方式有不少種,最基本的DDoS攻擊就是利用合理的服務請求來佔用過多的服務資源,從而使合法用戶沒法獲得服務的響應。
SYN-Flood是目前最流行的攻擊手段。
SYN-Flood利用TCP/IP協議的固有漏洞。面向鏈接的TCP三次握手是SYN-Flood存在的基礎。
如上圖圖,在第一步中,客戶端向服務端提出鏈接請求。這時TCP SYN標誌置位。客戶端告訴服務端序列號區域合法,須要檢查。客戶端在TCP報頭的序列號區中插入本身的ISN。服務端收到該TCP分段後,在第二步以本身的ISN迴應(SYN標誌置位),同時確認收到客戶端的第一個TCP分段(ACK標誌置位)。在第三步中,客戶端確認收到服務端的ISN(ACK標誌置位)。到此爲止創建完整的TCP鏈接,開始全雙工模式的數據傳輸過程。
假設一個用戶向服務器發送了SYN報文後忽然死機或掉線,那麼服務器在發出SYN+ACK應答報文後是沒法收到客戶端的ACK報文的(第三次握手沒法完成),這種狀況下服務器端通常會重試(再次發送SYN+ACK給客戶端)並等待一段時間後丟棄這個未完成的鏈接,這段時間的長度咱們稱爲SYN Timeout,通常來講這個時間是分鐘的數量級(大約爲30秒-2分鐘);一個用戶出現異常致使服務器的一個線程等待1分鐘並非什麼很大的問題,但若是有一個惡意的攻擊者大量模擬這種狀況,服務器端將爲了維護一個很是大的半鏈接列表而消耗很是多的資源—-數以萬計的半鏈接,即便是簡單的保存並遍歷也會消耗很是多的CPU時間和內存,況且還要不斷對這個列表中的IP進行SYN+ACK的重試。實際上若是服務器的TCP/IP棧不夠強大,最後的結果每每是堆棧溢出崩潰—即便服務器端的系統足夠強大,服務器端也將忙於處理攻擊者僞造的TCP鏈接請求而無暇理睬客戶的正常請求(畢竟客戶端的正常請求比率很是之小),此時從正常客戶的角度看來,服務器失去響應,這種狀況咱們稱作:服務器端受到了SYN Flood攻擊(SYN洪水攻擊)。
主機上的設置
幾乎全部的主機平臺都有抵禦DDoS的設置,基本的有幾種:
網絡設備上的設置
防火牆
本內容摘自:
分佈式拒絕服務攻擊(DDoS)原理及防範
SQL注入是一種危害極大的攻擊形勢,雖然危害很大,可是防護卻遠沒有XSS那麼難。
SQL注入的漏洞存在,就是拼接SQL參數,也就是將用於輸入的查詢參數,直接拼接在SQL語句中,致使了SQL注入漏洞。
String sql = "SELECT id,no FROM user WHERE id = " + id;
其中id是用戶輸入的參數,那麼若是用戶輸入2,那麼上面查到的是一條數據,若是用戶輸入的是"2 or 1 = 1"
進行SQL注入攻擊,那麼即將user表的全部記錄都查找出來了。
String sql = "SELECT id,no FROM user WHERE id = ?"; PreparedStatement ps = conn.preparedStatement(sql); ps.setInt(1,id); ps.executuQuery();
緣由:採用了PrepareStatement,就會將sql語句:"SELECT id,no FROM user WHERE id = ?"
`預先編譯好,也就是SQL引擎預先進行語法分析,產生語法書,聲稱執行計劃,也就是說,後面你輸入的參數,不管輸入什麼,都不會影響該SQL語句的語法結構,後面輸入的參數,毫不會被做爲sql命令來執行,只會被當作字符串面值參數。
在實際項目中,通常都是採用各類框架,好比ibatis,hibernate,mybatis等,他們通常默認就是sql預編譯。對於ibatis/mybatis,若是使用#{name}形式的,那麼就是SQL預編譯,使用${name},就不是SQL預編譯。
mybatis中的#跟$:
#{}:解析爲一個JDBC預編譯語句的參數標識符,一個#{}被解析爲一個參數標識符。
${}:僅僅做爲一個純粹的String替換,在動態SQL解析階段進行變量替換。
eg:
-- id = 123 SELECT id,no FROM user WHERE id = #{id} -- > '123' SELECT id,no FROM user WHERE id = ${id} -- > 123