前台RequestPayload传值 后台RequestBody 接收不到

本文档描述了一个前端RequestPayload传递数据到后台RequestBody时,由于后台的XSS过滤机制过滤了'and'字符,导致参数standard_model接收为null的问题。问题定位在XSS拦截过滤器,该过滤器对特定字符进行了替换。解决方案在于调整XSS过滤规则,确保不影响正常参数的传递。在后续的漏洞修复中,需要注意避免对合法参数的误过滤。
摘要由CSDN通过智能技术生成

前台RequestPayload传值 后台RequestBody 接收不到

问题描述 字段值为standard_model的药具规格 后台接受值为null

问题定位:xss拦截

scriptPattern = Pattern.compile("and", Pattern.CASE_INSENSITIVE);
        input = scriptPattern.matcher(input).replaceAll("");
        
        
后台进行了xss拦截 过滤器的原因 对and字符进行了过滤 导致参数standard_model变成了stard_model
由此后台取值出现问题

此类问题在之后漏洞修复的时候要注意

附:正确解决方法
/**
 * xss请求处理类
 * */
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
	HttpServletRequest orgRequest = null;
	private boolean isIncludeRichText = false;

	public static Pattern pattern_select = Pattern.compile("select",Pattern.CASE_INSENSITIVE);
	public static Pattern pattern_insert = Pattern.compile("insert",Pattern.CASE_INSENSITIVE);
	public static Pattern pattern_update = Pattern.compile("update",Pattern.CASE_INSENSITIVE);
	public static Pattern pattern_drop = Pattern.compile("drop",Pattern.CASE_INSENSITIVE);
	public static Pattern pattern_delete = Pattern.compile("delete",Pattern.CASE_INSENSITIVE);
	public static Pattern pattern_truncate = Pattern.compile("truncate",Pattern.CASE_INSENSITIVE);
	public static Pattern pattern_or = Pattern.compile("or",Pattern.CASE_INSENSITIVE);
	public static Pattern pattern_and = Pattern.compile("and",Pattern.CASE_INSENSITIVE);

	// 将<script>进行置换
	public static Pattern pattern_script = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
	// 将<src>进行置换
	public static Pattern pattern_src =  Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);

	public XssHttpServletRequestWrapper(HttpServletRequest request, boolean isIncludeRichText) {
		super(request);
		orgRequest = request;
		this.isIncludeRichText = isIncludeRichText;
	}

	@Override
	public ServletInputStream getInputStream() throws IOException {
		// 非json类型,直接返回
		if (!super.getHeader("Content-Type").equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE)) {
			return super.getInputStream();
		}
		// 为空,直接返回
		String json = IOUtils.toString(super.getInputStream(), "utf-8");
		if (StringUtils.isBlank(json)) {
			return super.getInputStream();
		}
		// xss过滤
		json = xssEncode(json,0);
		final ByteArrayInputStream bis = new ByteArrayInputStream(json.getBytes());
		return new ServletInputStream() {
			@Override
			public boolean isFinished() {
				return true;
			}

			@Override
			public boolean isReady() {
				return true;
			}

			@Override
			public void setReadListener(ReadListener readListener) {

			}

			@Override
			public int read() throws IOException {
				return bis.read();
			}
		};
	}

	/**
	 * 覆盖getParameter方法,将参数名和参数值都做xss过滤。<br/>
	 * 如果需要获得原始的值,则通过super.getParameterValues(name)来获取<br/>
	 * getParameterNames,getParameterValues和getParameterMap也可能需要覆盖
	 */
	@Override
	public String getParameter(String name) {
		Boolean flag = ("content".equals(name) || name.endsWith("WithHtml"));
		if (flag && !isIncludeRichText) {
			return super.getParameter(name);
		}
		name = JsoupUtil.clean(name);
		String value = super.getParameter(name);
		if (StringUtils.isNotBlank(value)) {
			value = xssEncode(value,1);
		}
		return value;
	}

	@Override
	public String[] getParameterValues(String name) {
		String[] arr = super.getParameterValues(name);
		if (arr != null) {
			for (int i = 0; i < arr.length; i++) {
				arr[i] = xssEncode(arr[i],1);
			}
		}
		return arr;
	}

	/**
	 * 覆盖getHeader方法,将参数名和参数值都做xss过滤。<br/>
	 * 如果需要获得原始的值,则通过super.getHeaders(name)来获取<br/>
	 * getHeaderNames 也可能需要覆盖
	 */
	@Override
	public String getHeader(String name) {
		name = JsoupUtil.clean(name);
		String value = super.getHeader(name);
		if (StringUtils.isNotBlank(value)) {
			value = xssEncode(value,0);
		}
		return value;
	}

	private String xssEncode(String input,Integer type) {

		input = pattern_script.matcher(input).replaceAll("");
		// 避免src形式的表达式
        input = pattern_src.matcher(input).replaceAll("");
		Pattern  scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
        input = scriptPattern.matcher(input).replaceAll("");
        // 删除单个的 </script> 标签
        scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);
        input = scriptPattern.matcher(input).replaceAll("");
        // 删除单个的<script ...> 标签
        scriptPattern = Pattern.compile("<script(.*?)>",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
        input = scriptPattern.matcher(input).replaceAll("");
		// 避免 eval(...) 形式表达式
        scriptPattern = Pattern.compile("eval\\((.*?)\\)",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
        input = scriptPattern.matcher(input).replaceAll("");
        // 避免 expression(...) 表达式
        scriptPattern = Pattern.compile("expression\\((.*?)\\)",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
        input = scriptPattern.matcher(input).replaceAll("");
        // 避免 javascript: 表达式
        scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);
        input = scriptPattern.matcher(input).replaceAll("");
        // 避免 vbscript:表达式
        scriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);
        input = scriptPattern.matcher(input).replaceAll("");
        // 避免 οnlοad= 表达式
        scriptPattern = Pattern.compile("onload(.*?)=",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
        input = scriptPattern.matcher(input).replaceAll("");
        //将<svg>进行置换
        scriptPattern = Pattern.compile("<svg(.*?)>",Pattern.CASE_INSENSITIVE);
        input = scriptPattern.matcher(input).replaceAll("");
        // 避免 οnerrοr= 表达式
        scriptPattern = Pattern.compile("onerror(.*?)=",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
        input = scriptPattern.matcher(input).replaceAll("");
        // 避免 alert(...) 形式表达式
        scriptPattern = Pattern.compile("alert\\((.*?)\\)",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
        input = scriptPattern.matcher(input).replaceAll("");
		// 避免 prompt(...) 形式表达式
		scriptPattern = Pattern.compile("prompt\\((.*?)\\)",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
		input = scriptPattern.matcher(input).replaceAll("");

		// 避免过滤特殊字符
		if(type==1){
			scriptPattern = Pattern.compile("[`~!@#$%^&*()+=|''\\\\[\\\\]<>/?~!@#¥%……&*()——+|‘;:”“’。,、?]",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
			input = scriptPattern.matcher(input).replaceAll("");
			input = pattern_and.matcher(input).replaceAll("");
			input = pattern_or.matcher(input).replaceAll("");
			input = pattern_delete.matcher(input).replaceAll("");
			input = pattern_drop.matcher(input).replaceAll("");
			input = pattern_select.matcher(input).replaceAll("");
			input = pattern_insert.matcher(input).replaceAll("");
			input = pattern_update.matcher(input).replaceAll("");
			//去除执行SQL语句的命令关键字
		}

		return input;
	}

	/**
	 * 获取最原始的request
	 * 
	 * @return
	 */
	public HttpServletRequest getOrgRequest() {
		return orgRequest;
	}

	/**
	 * 获取最原始的request的静态方法
	 * 
	 * @return
	 */
	public static HttpServletRequest getOrgRequest(HttpServletRequest req) {
		if (req instanceof XssHttpServletRequestWrapper) {
			return ((XssHttpServletRequestWrapper) req).getOrgRequest();
		}

		return req;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值