【JAVA-WEB常見漏洞-XSS漏洞】
XSS漏洞
攻擊者利用XSS(Cross-site scripting
)漏洞攻擊可以在使用者的瀏覽器中執行JS惡意指令碼,XSS
攻擊可以實現使用者會話劫持
、釣魚攻擊
、惡意重定向
、點選劫持
、掛馬
、XSS蠕蟲
等,XSS攻擊型別分為:反射型
、儲存型
、DOM型
。
1. 反射型XSS攻擊
示例 - 存在反射型XSS的xss.jsp程式碼:
<%=request.getParameter("input")%>
攻擊者通過傳入惡意的input
引數值可以在使用者瀏覽器中注入一段JavaScript
指令碼。
示例 - 注入XSS程式碼:
<script>alert('xss');</script>
瀏覽器請求:http://localhost:8000/modules/servlet/xss.jsp?input=%3Cscript%3Ealert(%27xss%27)%3B%3C/script%3E;%3C/script%3E)。
2. 儲存型XSS攻擊
示例 - 存在儲存型XSS的guestbook.jsp程式碼:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="java.util.*" %>
<%
String username = request.getParameter("username");
String content = request.getParameter("content");
String guestBookKey = "GUEST_BOOK";
List<Map<String, String>> comments = new ArrayList<Map<String, String>>();
if (content != null) {
Object obj = application.getAttribute(guestBookKey);
if (obj != null) {
comments = (List<Map<String, String>>) obj;
}
Map<String, String> comment = new HashMap<String, String>();
String ip = request.getHeader("x-real-ip");
if (ip == null) {
ip = request.getRemoteAddr();
}
comment.put("username", username);
comment.put("content", content);
comment.put("ip", ip);
comment.put("date", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
comments.add(comment);
application.setAttribute(guestBookKey, comments);
}
%>
<html>
<head>
<title>留言板</title>
</head>
<style>
* {
margin: 0;
padding: 0;
}
</style>
<body>
<div style="border: 1px solid #C6C6C6;">
<div style="text-align: center;">
<h2>線上留言板</h2>
</div>
<div>
<dl>
<%
Object obj = application.getAttribute(guestBookKey);
if (obj instanceof List) {
comments = (List<Map<String, String>>) obj;
for (Map<String, String> comment : comments) {
%>
<dd>
<div style="min-height: 50px; margin: 20px; border-bottom: 1px solid #9F9F9F;">
<p><B><%=comment.get("username")%>
</B>[<%=comment.get("ip")%>] 於 <%=comment.get("date")%> 發表回覆:</p>
<p style="margin: 15px 0 5px 0; font-size: 12px;">
<pre><%=comment.get("content")%></pre>
</p>
</div>
</dd>
<%
}
}
%>
</dl>
</div>
<div style="background-color: #fff; border: 1px solid #C6C6C6;">
<form action="#" method="POST" style="margin: 20px;">
暱稱: <input type="text" name="username" style="width:250px; height: 28px;"/><br/><br/>
<textarea name="content" style="overflow: auto;width: 100%; height: 250px;"></textarea>
<input type="submit" value="提交留言" style="margin-top: 20px; width: 80px; height: 30px;"/>
</form>
</div>
</div>
</body>
</html>
訪問:http://10.10.99.2:8000/modules/servlet/guestbook.jsp,並在留言內容出填入xss測試程式碼,如下:
提交留言後頁面會重新整理,並執行留言的xss程式碼:
3. DOM XSS
示例 - dom.jsp程式碼:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Date: <span style="color: red;"></span>
<input type="hidden" value="<%=request.getParameter("date")%>" />
<script>
var date = document.getElementsByTagName("input")[0].value;
document.getElementsByTagName("span")[0].innerHTML = date;
</script>
正常請求測試:http://localhost:8000/modules/servlet/dom.jsp?date=2020-11-15%2015:57:22
XSS攻擊測試:http://localhost:8000/modules/servlet/dom.jsp?date=%3Cimg%20src=1%20οnerrοr=alert(/xss/)%20/%3E%20/%3E)
4. XSS防禦
XSS最為常見的處理方式是轉義特殊字元,後端程式在接受任何使用者輸入的引數時都應當優先考慮是否會存在XSS攻擊。
4.1 htmlspecialchars
在PHP中通常會使用htmlspecialchars函式會將一些可能有攻擊威脅的字串轉義為html實體編碼,這樣可以有效的避免XSS攻擊。
示例 - htmlspecialchars 轉義
字元 | 替換後 |
---|---|
& (& 符號) | & |
" (雙引號) | " |
' (單引號) | ' 或者' |
< (小於) | < |
> (大於) | > |
在Java中雖然沒有內建如此簡單方便的函式,但是我們可以通過字串替換的方式實現類似htmlspecialchars
函式的功能。
/**
* 實現htmlSpecialChars函式把一些預定義的字元轉換為HTML實體編碼
*
* @param content 輸入的字串內容
* @return HTML實體化轉義後的字串
*/
public static String htmlSpecialChars(String content) {
if (content == null) {
return null;
}
char[] charArray = content.toCharArray();
StringBuilder sb = new StringBuilder();
for (char c : charArray) {
switch (c) {
case '&':
sb.append("&");
break;
case '"':
sb.append(""");
break;
case '\'':
sb.append("'");
break;
case '<':
sb.append("<");
break;
case '>':
sb.append(">");
break;
default:
sb.append(c);
break;
}
}
return sb.toString();
}
在儲存或者輸出請求引數的時候使用該方法過濾即可實現XSS防禦。
4.2 全域性的XSSFilter
package com.anbai.sec.vuls.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.IOException;
public class XSSFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
// 建立HttpServletRequestWrapper,包裝原HttpServletRequest物件,示例程式只重寫了getParameter方法,
// 應當考慮如何過濾:getParameter、getParameterValues、getParameterMap、getInputStream、getReader
HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(request) {
public String getParameter(String name) {
// 獲取引數值
String value = super.getParameter(name);
// 簡單轉義引數值中的特殊字元
return value.replace("&", "&").replace("<", "<").replace("'", "'");
}
};
chain.doFilter(requestWrapper, resp);
}
@Override
public void destroy() {
}
}
web.xml新增XSSFilter過濾器:
<!-- XSS過濾器 -->
<filter>
<filter-name>XSSFilter</filter-name>
<filter-class>com.anbai.sec.vuls.filter.XSSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>XSSFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
請求XSS示例程式:http://localhost:8000/modules/servlet/xss.jsp?input=%3Cscript%3Ealert(%27xss%27);%3C/script%3E;%3C/script%3E)
經過全域性過濾器轉義後的引數就不會再帶有XSS攻擊能力了。
4.3 RASP XSS攻擊防禦
RASP可以實現類似於全域性XSSFilter的請求引數過濾功能,比較穩定的一種方式是Hook到javax.servlet.ServletRequest
介面的實現類的getParameter/getParameterValues/getParameterMap
等核心方法,在該方法return之後插入RASP的檢測程式碼。這種實現方案雖然麻煩,但是可以避免觸發Http請求引數解析問題(Web應用無法獲取getInputStream
和亂碼等問題)。
示例 - RASP對getParameter返回值Hook示例:
反射型的XSS防禦相對來說比較簡單,直接禁止GET引數中出現<>
標籤,只要出現就理解攔截,如:
http://localhost:8000/modules/servlet/xss.jsp?input=<script>alert('xss');</script>
過濾或攔截掉<>
後input
引數就不再具有攻擊性了。
但是POST請求的XSS引數就沒有那麼容易過濾了,為了兼顧業務,不能簡單的使用htmlSpecialChars
的方式直接轉義特殊字元,因為很多時候應用程式是必須支援HTML標籤的(如:<img>、<h1>
等)。RASP在防禦XSS攻擊的時候應當儘可能的保證使用者的正常業務不受影響,否則可能導致使用者無法業務流程阻塞或崩潰。
為了支援一些常用的HTML標籤和HTML標籤屬性,RASP可以通過詞法解析的方式,將傳入的字串引數值解析成HTML片段,然後分析其中的標籤和屬性是否合法即可。
4.4 RASP XSS防禦能力測試
4.4.1 惡意的HTML標籤屬性XSS測試
示例 - 提交帶有XSS攻擊的Payload:
<img src='1.jpg' width='10px' height='10px' onerror='alert(/xss/);' />
請求示例地址:http://localhost:8000/modules/servlet/guestbook.jsp,並填寫XSS攻擊程式碼,如下圖:
RASP能夠正確識別並攔截XSS攻擊:
4.4.2 XSS富文字檢測測試
RASP如果要實現精確的XSS檢測能力就必須能夠正確的識別出使用者傳入的資料到底是否合法,經過HTML詞法分析後RASP能夠正確認識使用者傳入的引數值是否是包含了惡意的HTML標籤或者屬性。
示例 - 使用者在留言板中帶圖片回覆:
示例 - 使用者在留言板中回覆被註釋的HTML片段:
經測試,RASP對XSS攻擊防禦能力正常,能夠識別合法的HTML和javascript程式碼(DOM類XSS佔不支援)。
相關文章
- XSS漏洞
- XSS漏洞釣魚
- 論PHP常見的漏洞PHP
- python常見漏洞總結Python
- Python開發常見漏洞Python
- Linux常見漏洞修復教程!Linux
- 2021網站常見漏洞有哪些網站
- 邏輯漏洞的常見驗證手法
- Web中介軟體常見漏洞總結Web
- 滲透測試9種常見漏洞
- TCP/IP協議常見漏洞型別TCP協議型別
- 常見中介軟體漏洞復現(上)
- php xss 反序列化漏洞PHP
- XSS常見問題
- web 應用常見安全漏洞一覽Web
- 常見的伺服器漏洞防護措施!伺服器
- Web 安全漏洞之 XSS 攻擊Web
- vue實踐中的常見知識漏洞001Vue
- WPS漏洞利用工具Bully常見命令集合
- 常見Flash XSS攻擊方式
- WEB應用常見15種安全漏洞一覽Web
- 一些常見的重置密碼漏洞分析整理密碼
- DVWA中學習PHP常見漏洞及修復方法PHP
- CWE-352: CSRF漏洞有幾種常見型別?型別
- 滲透測試常見的漏洞有哪些?這五類最常見!
- 漏洞分析——變數缺陷漏洞及通用異常捕獲宣告缺陷漏洞變數
- 【第七章】XSS 跨站指令碼漏洞指令碼
- 常見網路攻擊:XSS 篇
- 滲透測試常見漏洞有哪些?如何有效防範?
- 常見的Web安全漏洞及測試方法介紹Web
- Android 常見安全漏洞修復理論與實踐Android
- Python中的10個常見安全漏洞及修復方法Python
- 滲透測試之小白的常見web漏洞總結(下)Web
- 滲透測試之小白的常見web漏洞總結(上)Web
- 滲透測試常見的9大漏洞,你知道幾個?
- Web安全系列(三):XSS 攻擊進階(挖掘漏洞)Web
- 如何檢測網站的安全漏洞?常見方法是什麼?網站
- 邏輯漏洞挖掘之XSS漏洞原理分析及實戰演練 | 京東物流技術團隊