最近在作項目中的漏洞修復工做,在短期內接觸到不少關於web開發須要防範的漏洞,例如SQL injection , XSS, CSRF等等,這些漏洞對web開發的項目來講的破壞仍是比較大的,其實在網上有不少這些漏洞的介紹和防範,像SQL injection這些漏洞的注入已經不多見了。做爲一個初學者我認爲仍是要可以弄清楚爲何會產生這個漏洞,這樣才能從原理上理解漏洞的發生,才能更好的去修復它,本文就對XSS漏洞作一個簡單的筆記,僅供你們相互交流不斷的提高web開發的安全性。javascript
XSS的全稱Cross-site Scripting,誇腳本攻擊,其實它的縮寫應該是CSS,可是和web開發使用的css重名了,因此就簡稱爲XSS了,該漏洞在web開發中比較常見,下面演示一個XSS漏洞的過程,我本身寫了一個很簡單的web頁面(你們不要拍磚),兩個輸入框,姓名和我的介紹。css
web開發中的常見漏洞,通常都發生在這些輸入框中,通常狀況咱們會對這些輸入域進行客戶端的校驗和服務器端的校驗,可是在客戶端的校驗基本上起不來什麼做用,由於客戶端的全部代碼咱們均可以進行更改,防止漏洞的發生仍是須要服務器端的校驗,可是通常服務器端的校驗都是校驗你輸入的字符或者是數字的長度等等。下面就演示一個XSS的漏洞注入,當咱們寫入姓名和我的介紹以後,後臺代碼的處理就是進行一個簡單的轉發,而後把咱們剛纔的信息轉發到一個info.jsp頁面進行顯示,代碼以下(不要拍磚):html
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username = req.getParameter("username"); String describe = req.getParameter("describe"); req.setAttribute("username", username); req.setAttribute("describe", describe); req.getRequestDispatcher("/info.jsp").forward(req, resp); }
咱們在輸入框中這樣輸入:java
你們看一下我的介紹裏邊寫的是一段javascript代碼,目前咱們後臺沒有對javascript代碼作任何的處理,直接把輸入的信息輸出到info.jsp頁面,這個時候咱們點擊提交按鈕,頁面跳轉到info.jsp頁面以後,就壞事了,直接把咱們寫的javascript代碼運行了,直接彈出 hello world 提示框了。若是咱們在我的介紹寫上<script>document.location.href='http://www.baidu.com'</script>,那麼提交之就跳轉到百度了,若是跳轉到xxoo網站呢,這不就壞事了嘛。web
若是你使用的是chrome 和 firefox瀏覽器演示例子,會發現不會出現上邊的狀況,主要緣由是chrome和firefox瀏覽器進行了攔截,看一下chrome瀏覽器console中的錯誤提示:sql
The XSS Auditor refused to execute a script in 'http://127.0.0.1:8080/javaweb/helloworld' because its source code was found within the request. The auditor was enabled as the server sent neither an 'X-XSS-Protection' nor 'Content-Security-Policy' header. helloworld:24
若是在request的請求和response響應中包含相同的script可執行的腳本,chrome會進行攔截,難道咱們使用chrome瀏覽器就能夠防止XSS的出現嗎?答案確定不是這樣的,通常狀況下咱們會把用戶輸入的表單內容存到數據庫中,而後再查詢的時候進行顯示,如今讓咱們模擬一下查詢數據庫,顯示用戶的輸入,看看chrome會進行攔截嗎?chrome
後臺的代碼改一下,模擬查詢數據庫,是模擬:數據庫
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username = req.getParameter("username"); String describe = req.getParameter("describe"); if(username == null || describe == null){ username ="aaaa"; describe="helloworld<script>alert('hello world');</script>"; } System.out.println(username +" : "+ describe); req.setAttribute("username", username); req.setAttribute("describe", describe); req.getRequestDispatcher("/info.jsp").forward(req, resp); }
在這裏咱們直接請求這個servlet而後再info.jsp頁面顯示信息,這個時候你會發現,咱們 describe="helloworld<script>alert('hello world');</script>";這裏的javascript腳本執行了,彈出的hello world 窗口。因此僅僅依靠瀏覽器防止XSS是不行的。咱們須要本身在後臺對這些特殊的字符進行轉碼,當這些字符再次顯示到頁面的時候不執行腳本。apache
使用什麼樣的方法才能阻止這種狀況的發生,就是對HTML 中的預留字符替換爲字符實體,例如:對< 進行替換成 <,對>替換成> 等等。在這裏把咱們的代碼進行一下完善防止XSS的出現:瀏覽器
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username = req.getParameter("username"); String describe = req.getParameter("describe"); if(username == null || describe == null){ username ="aaaa"; describe="helloworld<script>alert('hello world');</script>"; } //HTML 中的預留字符必須被替換爲字符實體 username = StringEscapeUtils.escapeHtml4(username); describe = StringEscapeUtils.escapeHtml4(describe); System.out.println(username +" : "+ describe); req.setAttribute("username", username); req.setAttribute("describe", describe); req.getRequestDispatcher("/info.jsp").forward(req, resp); }
這個時候咱們再次使用chrome瀏覽器直接訪問請求的servlet在info.jsp中顯示的結果爲:
這樣咱們就能夠簡單的防止XSS誇腳本攻擊,代碼中的 StringEscapeUtils是apache common-lang 包下的一個工具類,這個工具類也能夠對sql中的保留字符進行轉換,同時咱們本身也能夠本身實現一個對html中的預留字進行替換的程序。在後臺打印的describe的字符已經被替換爲:
helloworld<script>alert('hello world');</script> 把這些內容顯示在html中是不會執行javascript腳本的。
本人也是剛剛接觸XSS漏洞的原理,上邊舉得例子是目前最簡單的例子,一些很深刻的XSS漏洞的方法還須要不斷的學習和研究,但願你們有這方面的資料能夠進行一下共享。到此結束。