代码审计之SpringMVC框架的安全攻防问题研究

SpringMVC中数据的接收

下面我们先介绍SpringMVC中能从外部接收参数的几种方式。

1.通过@RequestParam 注解指定客户端的参数

代码如下:

package com.pc.controller;

省略导入的包...

@Controller
public class ParamController {

    @RequestMapping("/action/param/")
    public String action_param(@RequestParam("user") String user,@RequestParam("pass") String pass){
        System.out.println(user);
        System.out.println(pass);
        if("admin".equals(user)&&"passwd".equals(pass)){
            return "login";
        }else{
            return "error";     
        }
        return "login";
    }
    
}


2.使用JavaBean的方式请求处理客户端的参数

通过javaBean的方式就是要定义一个java对象

User.java类的文件如下:

package com.pc.beans;

public class U {

    private String user;
    private String pass;

    public String getUser() {
        return user;
    }
    public void setUser(String user) {
        this.user = user;
    }
    public String getPass() {
        return pass;
    }
    public void setPass(String pass) {
    this.pass = pass;
    }
}


controller层代码如下

package com.pc.controller;

import com.pc.beans.U;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class ParamController {
    
    @RequestMapping("/actiont/bean.do")
    public String login_bean(U u) throws Exception{
        String user = u.getUser();
        System.out.println(user);
        String pass = u.getPass();
        System.out.print(pass);
        
        if("admin".equals(user)&&"pass".equals(pass)){
            return "login";
        }else{
            return "error";     
        }
    }

}


3.通过@PathVariabl注解获取路径中的参数

通过@PathVariabl注解获取参数,直接把参数传递到路径里

package com.pc.controller;

包省略...

@Controller
public class PathController {
	@RequestMapping("/login/{user}/{pass}/")
	public String login(@PathVariable(value="user") String user,@PathVariable(value="pass") String pass) throws Exception{
		System.out.println(user);
		System.out.println(pass);
		if("admin".equals(user)&&"passwd".equals(pass)){
			return "login";
		}else{
			return "error";		
		}
	}


4.通过@ModelAttribute注解获取参数

同bean的方法相似,需定义一个pojo对象

package com.pc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import com.pc.beans.pojo;


@Controller
public class PojoController {

    @RequestMapping("/actiont/pojo")
    public String PojoRequest(@ModelAttribute("pojo") pojo pojo){
        String user = pojo.getUser();
        String pass = pojo.getPass();
        System.out.println(user);
        System.out.println(pass);
        if("admin".equals(user)&&"pass".equals(pass)){
            return "login";
        }else{
            return "error";
        }
    }

}



5.直接用HttpServletRequest对象获取

这一种就是利用httpServletRequest这个对象接收参数,在jsp中我们也是利用这个对象进行的响应操作。

其他的层和设置就不贴出来了,主要我看controller层的内容。

package com.pc.controller;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class HttpController {
    
    @RequestMapping("/action/request/")
    public String login_request(HttpServletRequest request, HttpServletResponse response){
        String username = request.getParameter("user");
        String password = request.getParameter("pass");
        
        if (username.isEmpty() || password.isEmpty()) {
            return "error";
        }else{
            User u = new User();
            u.setUser(username);
            u.setPass(password);
            request.setAttribute("u", u);
            
            User user = UserService.findUser(username,password);
            if (user == null){
                return "error";
            }
            //登录成功
            return "login";
        }       
        
    }

    
}


6.通过SpringMVC框架的中函数WebRequest获取

通过SpringMVC中自带的WebRequest对象进行获取


package com.pc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.WebRequest;


@Controller
public class WebrequestController {
	@RequestMapping("/action/webrequest/")
	public String WebRequest(WebRequest webRequest, NativeWebRequest nativeWebRequest){
		String user = webRequest.getParameter("user");
		String pass = webRequest.getParameter("pass");
		System.out.println(user);
		System.out.println(pass);
		if("admin".equals(user)&&"pass".equals(pass)){
			return "login";
		}else{
			return "error";
		}
	}

}

其他客户端可以自定义参数的获取

1.利用@CookieValue注解获取cookie数据值

package com.pc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class CookieController {
	
	@RequestMapping("/cookie")
	public String login_cookie(@CookieValue(value="username") String username) throws Exception{
		System.out.println(username);
		if(!"admin".equals(username)){
			return "login";
		}else{
			return "error";		
		}
	}	
}


2.利用@RequestHeader注解绑定请求头数据

package com.pc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;


@Controller
public class HeaderController {
	
	@RequestMapping("/header")
	public String header(@RequestHeader("User-Agent") String userAgent,@RequestHeader("Test") String test){
		System.out.println(userAgent);
		System.out.println(test);
		if(!"admin".equals(test)){
			return "login";
		}else{
			return "error";		
		}	
	}
}


上面的这些注解和函数都是SpringMVC中接收外部数据的方法,对于这个点,也是我们代码审计数据流跟踪的起点,一般一个公司的开发框架接收参数的形式都是使用固定某种方式。我们可以根据特定的某种方式做出自己的代码审计请求接口获取自动化工具。

比如我们利用HttpRequestServlet这个类获取参数,代码如下

package com.pc.controller;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class HttpController {
    
    @RequestMapping("/action/request/")
    public String login_request(HttpServletRequest request, HttpServletResponse response){
        String username = request.getParameter("user");
        String password = request.getParameter("pass");
        
        if (username.isEmpty() || password.isEmpty()) {
            return "error";
        }else{
            User u = new User();
            u.setUser(username);
            u.setPass(password);
            request.setAttribute("u", u);
            
            User user = UserService.findUser(username,password);
            if (user == null){
                return "error";
            }
            //登录成功
            return "login";
        }       
    }

    @RequestMapping("/action/request1/")
    public String login_request(HttpServletRequest request, HttpServletResponse response){
        String username = request.getParameter("user");
        String password = request.getParameter("pass");
        
        if (username.isEmpty() || password.isEmpty()) {
            return "error";
        }else{
            User u = new User();
            u.setUser(username);
            u.setPass(password);
            request.setAttribute("u", u);
            
            User user = UserService.findUser(username,password);
            if (user == null){
                return "error";
            }
            //登录成功
            return "login";
        }       
   }
}


 这个代码的http请求的url是http://www.xxx.com/action/request?user=xxx&pass=xxxx,直接访问这个请求就会被我们的这段代码处理。 

现在大家应该都发现规律了,那么我们就说一下这个抓取url接口的脚本实现过程。以这一个文件为例。

首先我们RequestMapping关键词直接或者RequestMapping到结尾(取出一个函数的边界可以自己根据相应的代码确定,我这仅仅是个栗子)的部分,把这一部分利用python中的函数re.finditer取出来。在这块代码中匹配RequestMapping取出路径,匹配request.getParameter取出参数。就能获取我们的请求接口了。

关于jsp的形式的文件就更加简单了

比如下面是个jsp的文件

<%@page language="java" import="java.util.*" pageEncoding="GB2312"%>
<html>
    <head>
        <title>
            result.jsp file
        </title>
    </head>

    <body bgcolor="ffffff">
        <%

          String name=request.getParameter("name");
          String pwd=request.getParameter("password");
            if(!name.equals("") && !pwd.equals(""))
            {
        %>
                姓名:<%=name%><br/>
                密码:<%=pwd%><br/>
                       %>
        <%
            }
            else
            {
        %>
                    请输入姓名或密码!
        <%
            }
        %>
    </body>
</html>

我们去这个文件的路径一般都是文件存放的位置path.取参数就是看request.getParamater和{param.user}这两个函数。

就是直接匹配取出组成url,http://www.xxxx.com/result.jsp?name=xxx&password=xxxx


上面是给大家分享这个思路去自动化发掘代码中的请求接口做自动化审计,同时根据自己的代码的做相应的改变了。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值