代码审计--3--输入输出验证

版权声明:本文为博主原创文章,转载本站文章请注明作者和出处,请勿用于任何商业用途。 https://blog.csdn.net/wutianxu123/article/details/82941435

3.1 SQL注入

当应用程序将用户输入的内容,拼接到SQL语句中,一起提交给数据库执行时,就会产生SQL注入威胁

1、是否存在全局过滤器
过滤器配置、过滤函数等

2、过滤器是否可以过滤所有查询请求

3、请求是否都按要求经过过滤器处理

4、过滤器的过滤是否符合要求

5、初期检查可以依据PHPIDS的规则库,后期根据收集的情况予以补充

6、是否使用了预编译

7、预查询是指在将数据传入SQL语句前明确指定传输数据的类型,以执行必要的转换。在Java中预查询的调用方式为prepareStatement。

8、是否存在SQL语句拼接
某些特殊的查询(特别复杂的组合查询)难免用到SQL语句拼接,遇到这种情况,就需要检查拼接是否有可能导致注入。

代码示例:

String query = "SELECT account_balance FROM user_data WHERE user_name = "+ request.getParameter("customerName");

try  {
	Statement statement = connection.createStatement( … );
	ResultSet results = statement.executeQuery( query );
}
//以上代码中由于使用了拼接方式构造sql语句,所以存在sql注入漏洞

3.2 跨站攻击

是否存在全局XSS过滤器(论坛的过滤库)

是否存在需过滤和不需过滤两种输出,页面是否控制恰当(*)

某些情况下可能存在两种输出,文本输出和富文本(HTML)输出,要强制文本输出,只需要调用HTMLEncode()对内容进行编码后输出即可;但是富文本本身就需要使用html来进行格式的控制,简单的编码就无法使用,这时需要在此类内容从客户端输入(用户提交)或输出给客户端(显示)时进行危险代码过滤。

输出的时候是否进行编码(HTML、JS)

3.3 csrf防护

Web 表单是否使用了Token(或验证码)

代码示例:

<form action="http://spdb.com/modify.jsp" method="POST">
	<input name="email">
	<input name="tel">
	<input name="realname">
	<input name="userid">
	<input type="submit">
</form>
//因为表单中没有token,以上代码中存在csrf漏洞

Web表单提交(成功或不成功)后token(或验证码)是否重置。原理同图形验证码的校验原理。

检查Token的生成算法是否安全。

检查服务器获取Web表单参数值的方式。
如果在操作时不严格区分GET和POST,在没有Token(或验证码)的辅助下很容易导致CSRF的发生。

3.4 文件上传漏洞

是否限制了上传文件的扩展名
以白名单形式指定允许上传的扩展名;以黑名单形式指定禁止上传的文件扩展名

是否对上传文件进行了重命名操作
重命名操作是否安全,防止重命名过程中产生二次风险

是否对上传文件的存放位置禁止了脚本执行

代码示例:

protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException 
{
	response.setContentType("text/html");
	PrintWriter out = response.getWriter();
	String contentType = request.getContentType();
	int ind = contentType.indexOf("boundary=");
	String boundary = contentType.substring(ind+9);
	String pLine = new String();
	String uploadLocation = new String(UPLOAD_DIRECTORY_STRING);
	//判断contentType是否是multipart/form-data

	if (contentType != null && contentType.indexOf("multipart/form-data") != -1) 
	{
		//从HttpHeader中提取文件名
		BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
		...
		pLine = br.readLine();
		String filename = pLine.substring(pLine.lastIndexOf("\\"),pLine.lastIndexOf("\""));
		...
		//把文件输出到上传目录
		try  {
			BufferedWriter bw = new BufferedWriter(new FileWriter(uploadLocation+filename, true));
			for (String line; (line=br.readLine())!=null; )  {
				if (line.indexOf(boundary) == -1)  {
					bw.write(line);
					bw.newLine();
					bw.flush();
				}
			}           //循环结束
			bw.close();
		} 
		catch (IOException ex) {...}
		//输出成功加载并返回的HTML页面
	}
	//输出成功加载并返回的HTML页面
	else
	{...}
}

3.5 文件下载防护

是否存在客户端指定文件名的下载功能。

直接指定文件名的下载是否允许客户端指定路径。

对于不同用户的文件在下载时是否进行了权限控制。
文件下载功能中是否对用户的权限进行了检查。

代码示例:

protected void doPost(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException 
{
	try  {
		byte data[] = new byte[1];
		//取得用户提交的图片文件名,没有检测是否为图片,也没有检测是否包含../../目录跳转的字符
		String imgName = request.getParameter("imgName");
		String imgKey = MD5Encrypt.MD5(imgName);        //本地

		if (imageCache.containsKey(imgKey))  {
			data = (byte[]) imageCache.get(imgKey);
		}  else  {
			String imagePath = Consts.IMG_LOCAL_PAHT + imgName;
			//没有对该参数进行严格的验证和过滤,就拼接成完整的图片路径
			InputStream inputStream = null; 
			File imageFile = new File(imagePath);
			logger.debug(imagePath + " " + imageFile.exists());
			if (imageFile.exists() && imageFile.isFile())  {
				inputStream = new FileInputStream(imagePath);
				int i = inputStream.available();
				data = new byte[i];
				inputStream.read(data);
				inputStream.close();
				imageCache.put(imgKey, data);
			}  else  {
				……
			}
		}
		//将文件内容输出到客户端
		response.setContentType("image/*");
		OutputStream outputStream = response.getOutputStream();
		outputStream.write(data);
		outputStream.close();
	}
}

3.6 重定向与转发

是否具有客户端控制的重定向或转发
是否定义了重定向的信任域名或主机列表
是否对客户端的重定向或转发请求进行检查

代码示例:

public class RedirectServlet extends HttpServlet  {
	protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException 
	{
		String query = request.getQueryString();
		
		if (query.contains("url"))  {
			String url = request.getParameter("url");
			response.sendRedirect(url);
		}
	}
}
//服务端从客户端接收参数url,直接指定其为重定向地址

猜你喜欢

转载自blog.csdn.net/wutianxu123/article/details/82941435