未经许可,不得转载。

XSS
XSS(跨站脚本攻击,Cross-Site Scripting) 是一种常见的Web安全漏洞,攻击者通过在网页中注入恶意脚本,使得这些脚本在用户的浏览器中执行。
XSS攻击通常分为以下三种类型
1、存储型XSS:恶意脚本被永久存储在目标服务器上(如数据库),当用户访问包含该脚本的页面时,脚本被执行。
2、反射型XSS:恶意脚本作为请求的一部分发送到服务器,服务器将脚本嵌入到响应中返回给用户,脚本在用户浏览器中执行。
3、DOM型XSS:恶意脚本通过修改页面的DOM结构来执行,不经过服务器处理。
漏洞成因
在 Java Web 应用中,XSS 漏洞通常源于对用户输入缺乏适当的过滤和处理,使得恶意脚本能够被注入并在浏览器中执行。
1、直接输出用户输入
String userInput = request.getParameter("input");
out.println(userInput); // 直接输出用户输入,可能导致XSS
2、在JSP中使用EL表达式输出用户输入
<p>${param.input}</p> <!-- 直接输出用户输入,可能导致XSS -->
3、在Thymeleaf模板中输出用户输入
<p th:text="${input}"></p> <!-- 直接输出用户输入,可能导致XSS -->
4、在JavaScript中嵌入用户输入
String userInput = request.getParameter("input");
out.println("<script>var input = '" + userInput + "';</script>"); // 直接嵌入用户输入到JS中,可导致XSS
此外,还有多种写法导致XSS,例如过滤不全被绕过等。
实战案例
案例1
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
//这一行是JSP的指令,用于指定页面属性:告诉浏览器这个页面是 HTML 格式;指定页面的字符编码为 UTF-8,可以正确显示中文等非 ASCII 字符;JSP 代码使用的语言是 Java。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>XSS 测试靶场</title>
</head>
<body>
<h1>XSS 反射型漏洞测试</h1>
<form action="index.jsp" method="get">
<label>请输入内容:</label>
<input type="text" name="input">
<button type="submit">提交</button>
</form>
<h2>输出结果:</h2>
<p>
<%
String userInput = request.getParameter("input");
if (userInput != null) {
out.println(userInput); // 直接输出,存在 XSS 漏洞
}
%>
//在JSP中,<% ... %> 用于嵌入 Java 代码,这些代码会在服务器端执行,并生成 HTML 发送给浏览器。
</p>
</body>
</html>
代码使用 request.getParameter(“input”) 获取用户输入,接着使用 out.println(userInput); 直接输出,未进行 HTML 编码,导致 XSS:

案例2
EL 表达式 不会自动转义 HTML,会直接渲染用户输入的内容。
如下代码存在漏洞:
<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>XSS EL表达式测试</title>
</head>
<body>
<h1>XSS EL表达式漏洞</h1>
<form action="index.jsp" method="get">
<label>请输入内容:</label>
<input type="text" name="input">
<button type="submit">提交</button>
</form>
<h2>输出结果:</h2>
<p>${param.input}</p> <!-- 直接输出,存在XSS漏洞 -->
</body>
</html>
payload:
<img src=1 onerror=alert("优快云秋说")>

案例3
<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>XSS 测试</title>
</head>
<body>
<h1>在JavaScript中直接使用用户输入导致XSS</h1>
<form action="index.jsp" method="get">
<label>请输入内容:</label>
<input type="text" name="input">
<button type="submit">提交</button>
</form>
<h2>输出结果:</h2>
<p>
<%
String userInput = request.getParameter("input");
if(userInput != null){
out.println("<script>var input = '" + userInput + "';</script>");
}
%>
</p>
</body>
</html>
如果用户访问:http://localhost:8080/index.jsp?input=Hello
则服务器返回的 HTML 为:
<script>var input = 'Hello';</script>
因此我们可以构造语句,实现单引号闭合。
若构造的payload为:';alert(1)
但结果如下,JS语句并没有被执行:

这是因为语法错误,JavaScript 解析器会将其视为无害的普通字符串,并不会执行alert(1);。
因此需要将后面的script标签注释掉,payload:
';alert(1)//
服务器返回:
<script>var input = '';alert(1);//';</script>
此时成功触发XSS:


1450

被折叠的 条评论
为什么被折叠?



