漏洞分析-存储型XSS-JAVA篇
0x00 原理分析
存储型XSS:用户在浏览器传入的数据未做校验,导致一些恶意的前端代码被插入至数据库中,前端再次读取数据时,数据被当成前端代码,或与前端代码拼接并执行。
0x01 效果演示
通过添加操作添加一个用户名为<h1>11</h1>的用户
数据库存储其用户名为<h1>11</h1>
插入弹框语句,则前端页面也显示弹框语句:
0x02 代码分析
servlet接口代码:
package controller; import bean.Contact; import org.apache.commons.beanutils.BeanUtils; import service.ContactSysService; import service.ContactSysServiceImpl; 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 java.io.IOException; import java.util.Map; @WebServlet("/add") public class AddContactServlet extends HttpServlet { private ContactSysService contactSysService = new ContactSysServiceImpl(); @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { // 1、获取当前添加界面的全部参数键值对 Map<String, String[]> params = request.getParameterMap(); // 2、把参数封装成实体类对象 Contact contact = new Contact(); BeanUtils.populate(contact , params); // 3、调用业务层对象 contactSysService.addContact(contact); // 4、响应添加成功的结果回去 request.setAttribute("tip" , "添加成功!"); } catch (Exception e) { request.setAttribute("tip" , "添加失败!"); e.printStackTrace(); } request.getRequestDispatcher("/add.jsp").forward(request , response); } }
jsp页面代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <!-- HTML5文档--> <!DOCTYPE html> <!-- 网页使用的语言 --> <html lang="zh-CN"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>添加用户</title> <!-- 1. 导入CSS的全局样式 --> <link href="BootStrap/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div class="container" style="max-width: 500px"> <h3>添加联系人页面</h3> <span style="color: red">${tip}</span> <form action="/boot/add" method="post"> <div class="form-group"> <label for="name">姓名:</label> <input type="text" class="form-control" id="name" name="name" placeholder="请输入姓名"> </div> <div class="form-group"> <label>性别:</label> <input type="radio" name="sex" value="男" checked="checked"/>男 <input type="radio" name="sex" value="女"/>女 </div> <div class="form-group"> <label for="age">年龄:</label> <input type="number" class="form-control" id="age" name="age" placeholder="请输入年龄"> </div> <div class="form-group"> <label for="address">籍贯:</label> <select name="address" class="form-control" id="address"> <option value="广东">广东</option> <option value="广西">广西</option> <option value="湖南">湖南</option> </select> </div> <div class="form-group"> <label for="qq">QQ:</label> <input type="number" class="form-control" id="qq" name="qq" placeholder="请输入QQ号码"/> </div> <div class="form-group"> <label for="email">Email:</label> <input type="email" class="form-control" id="email" name="email" placeholder="请输入邮箱地址"/> </div> <div class="form-group" style="text-align: center"> <input class="btn btn-primary" type="submit" value="提交" /> <input class="btn btn-default" type="reset" value="重置" /> <a class="btn btn-default" type="button" href="${pageContext.request.contextPath}/list" >返回</a> </div> </form> </div> <!-- 2. jQuery导入,建议使用1.9以上的版本 --> <script src="BootStrap/js/jquery-2.1.0.min.js"></script> <!-- 3. 导入bootstrap的js文件 --> <script src="BootStrap/js/bootstrap.min.js"></script> </body> </html>
前端触发漏洞的代码:
<input type="text" class="form-control" id="name" name="name" placeholder="请输入姓名">
与placeholder="请输入姓名"无关,插入失败很可能是因为waf或者是该数据库设置的长度有限制。
![](https://img2023.cnblogs.com/blog/1674381/202302/1674381-20230218235519572-558702322.png)
长度限制:发现是可以插入数据库恶意语句是,只不多数据库的用户名的长度有限制。重新设置数据库表长度为200:
改好之后,就能插入恶意的xss payload:
然后页面触发弹框:
在td内被插入了xss的payload:
产生原理就是未对输入的数据未进行校验。request.getParameterMap()方法,直接获取request请求提交的所有的值,然后再把参数封装成实体类。未进行过滤操作: