查看这个cms系统后台管理员 添加用户的页面

点击添加管理员
这个模块只有管理员拥有,普通用户没有这个模块。
打开源码分析是否存在越权漏洞。
------------------------------------------------------------------------------------------------------------
表单代码
- <form name="adminForm" id="adminForm">
- <input type="hidden" name="item" value="${item}" />
- <table border="0" cellpadding="0" cellspacing="0" class="table_c1">
- <tr>
- <td class="label_c" width="15%"><label><fmt:message key="username" bundle="${messagesBundle}"/>:label>td>
- <td width="85%">
- <c:if test="${item==null}">
- <input type="text" value="${admin.username}" name="username" id="username" class="wid_80"/>
- c:if>
- <c:if test="${item!=null}">
- <input type="text" readonly value="${admin.username}" name="username" id="username" class="wid_80"/>
- c:if>
- td>
- tr>
- <tr>
- <td class="label_c"><label>姓名:label>td>
- <td>
- <input type="text" value="${admin.adminName}" name="name" id="name" class="wid_80"/>
- td>
- tr>
- <tr>
- <td class="label_c"><label><fmt:message key="sex" bundle="${messagesBundle}"/>:label>td>
- <td>
- <select name="sex" id="sex">
- <option value="">--请选择--option>
- <option value="男">男option>
- <option value="女">女option>
- select>
- td>
- tr>
- <tr>
- <td class="label_c"><label><fmt:message key="role" bundle="${messagesBundle}"/>:label>td>
- <td>
- <select name="role" id="role">
- <option value="">--请选择--option>
- <c:forEach items="${roleList}" var="role" varStatus="status">
- <option value="${role.id }">${role.name}option>
- c:forEach>
- select>
- td>
- tr>
- <tr>
- <td class="label_c"><label><fmt:message key="qq" bundle="${messagesBundle}"/>:label>td>
- <td>
- <input type="text" name="qq" id="qq" value="${admin.qq}" class="wid_80"/>
- td>
- tr>
- table>
-
- form>
-
- <div class="right_bottom_btnlist">
- <ul>
- <li>
- <input type="submit" value="
submit " bundle="${messagesBundle}"/>" class="button-2 vcenter" onclick="add()"/> - li>
- ul>
- div>
查看触发post请求的js代码
- function add(){
- var username=requree_name("username") && requree_length("username",6,20);
- var name=requree_name("name") && requree_length("name",2,20);
- var role=document.getElementById("role").value;
- //requree_name函数可能用于验证username字段是否符合指定规则,而requree_length函数可能用于验证username字段的长度是否在指定范围内
- if(!username){
- layer.alert("用户名为必填项,限制6~20位");
- }else if(!name){
- layer.alert("请输入姓名,限制2~20位");
- }else if(role==""||role==null){
- layer.alert("请设置所属角色!");
- }else{
- var params= $('#adminForm').serialize();
- $.ajax({
- url:"<%=basePath%>admin/addAdmin", //后台处理程序
- type:'post', //数据发送方式
- dataType:'json',
- data:params, //要传递的数据
- success:function(data){
- alert(data.tip);
- parent.window.location.reload();
- }
- });
- }
-
- }
- document.getElementById("role").value="${admin.role}";
- document.getElementById("sex").value="${admin.adminSex}";
- var height = $(window).height();
- $(".middle_cnt_c2").height(height-80);
- $(window).resize(function () { //当浏览器大小变化时
- var height = $(window).height();
- $(".middle_cnt_c2").height(height-80);
- });
根据提交的接口定位到<%=basePath%>admin/addAdmin 后端源码
- @WebServlet(
- displayName = "添加管理员",
- name = "AddAdmin",
- urlPatterns = {"/admin/addAdmin"}
- )
- /*这是一个Java Servlet的注解(Annotation),用于将Java类声明为一个Web应用程序的Servlet。该注解中包含了多个参数:
- displayName:Servlet的显示名称,可以在Web应用程序管理界面中使用;
- name:Servlet的名称,必须是唯一标识符,在Web应用程序中引用时会用到;
- urlPatterns:Servlet映射的URL模式,可以是一个字符串数组,每个字符串对应一个URL模式。
- 在这个例子中,该Servlet被映射到了URL模式/admin/addAdmin,也就是说当用户请求这个URL时,容器会将该请求交给AddAdmin Servlet来处理*/
- public class AddAdmin extends HttpServlet {
- public AddAdmin() {
- }
-
- public void destroy() {
- super.destroy();
- }
-
- public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- }
-
- public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- response.setContentType("text/html;charset=UTF-8");
- PrintWriter out = response.getWriter();
- AdminService as = new AdminService();
- //AdminService 是一个自定义的类controller,它可能是用于处理与管理员相关的业务逻辑或提供相应的服务。通过创建 AdminService 对象,我们可以使用该对象中的方法来执行特定的操作,例如管理管理员账户、处理管理员权限等。
- HttpSession session = request.getSession(true);
- Object user = session.getAttribute("user");
- /*这段代码用于获取当前请求所关联的HTTP Session,并从中获取属性名为"user"的属性值。
- 首先,request.getSession(true)方法用于获取当前请求所对应的Session对象。如果Session对象不存在,则会创建一个新的Session对象并返回。如果传入的参数为false,则表示只会查找已经存在的Session对象,如果不存在,则返回null。
- 然后,session.getAttribute("user")方法用于获取当前Session中名称为"user"的属性值。如果该属性不存在,则返回null。注意,Session是一种保存在服务器端的数据对象,在Session中保存的数据在整个会话期间都可以被访问和修改。*/
- String json = "";
- String id = request.getParameter("item");//
- String admin_username = request.getParameter("username");
- String admin_passbak = "123456";
- String admin_pass = Md5Util.getMD5Str(admin_passbak);
- String admin_name = request.getParameter("name");
- String admin_sex = request.getParameter("sex");
- String admin_role = request.getParameter("role");
- String qq = request.getParameter("qq");
- Locale loc = new Locale("zh", "CN");
- ResourceBundle rb = ResourceBundle.getBundle("messages", loc);
- String adminTip = rb.getString("adminTip");
-
- String flag = "";
- if (user == null) {
- RequestDispatcher rd = request.getRequestDispatcher("/WEB-INF/login.jsp");
- request.setAttribute("tip", adminTip);
- rd.forward(request, response);
- } else {
- boolean f = false;
- if (id != null && !id.equals("") && !id.equals("undefined")) {
- if (!admin_username.trim().equals("")) {
- flag = as.updateAdmin(id, admin_role, admin_name, admin_sex, qq);
- //控制器controller执行了updateAdmin 其中id 可控 可能为唯一键值 ,造成了越权漏洞
-
- if (flag.equals("ok")) {
- json = "{\"tip\":\"" + rb.getString("modify") + rb.getString("success") + "\"}";
- } else {
- json = "{\"tip\":\"" + rb.getString("modify") + rb.getString("failure") + "\"}";
- }
- } else {
- json = "{\"tip\":\"" + rb.getString("name") + rb.getString("not") + rb.getString("empty") + "\"}";
- }
- } else if (!admin_username.trim().equals("")) {
- try {
- f = as.geyUser(admin_username);
- } catch (SQLException var22) {
- var22.printStackTrace();
- }
-
- if (f) {
- flag = as.saveAdmin(admin_username, admin_pass, admin_passbak, admin_role, admin_name, admin_sex, qq);
- if (flag.equals("ok")) {
- json = "{\"tip\":\"" + rb.getString("add") + rb.getString("success") + "," + rb.getString("default") + rb.getString("password") + ":123456\"}";
- } else {
- json = "{\"tip\":\"" + rb.getString("add") + rb.getString("failure") + "\"}";
- }
- } else {
- json = "{\"tip\":\"" + rb.getString("username") + rb.getString("already") + rb.getString("there") + "\"}";
- }
- } else {
- json = "{\"tip\":\"" + rb.getString("name") + rb.getString("not") + rb.getString("empty") + "\"}";
- }
-
- out.print(json);
- }
-
- }
-
- public void init() throws ServletException {
- }
- }
urlPatterns:Servlet映射的URL模式,URL模式/admin/addAdmin,映射到了此Servlet类。
AdminService 是一个自定义的类controller,它可能是用于处理与管理员相关的业务逻辑或提供相应的服务。通过创建 AdminService 对象,我们可以使用该对象中的方法来执行特定的操作,例如管理管理员账户、处理管理员权限等。
控制器controller执行了updateAdmin 其中id 可控 可能为唯一键值 ,造成了越权漏洞。
执行updateAdmin 没有对用户的身份权限信息(管理员)做任何验证处理。只要当前session存在user,即使是普通账户也可以执行updateAdmin,而传入的参数都为我们用户可控,由此引发越权漏洞。
利用方式
伪造这个接口的http请求头,将cookie信息设置成我们普通用户的cookie,输入我们想要的请求体(增加新的管理员信息),发送。
总结
无论是纵向越权还是横向越权,我们都需要对用户信息做再次的验证,对于一些敏感信息像id这种唯一键值尽量不要存放在前端,............