XSS解决方法(以及前段UrlEncode 加密两次的原理分析)
来源:互联网 发布:中医在线咨询软件 编辑:程序博客网 时间:2024/05/19 20:40
XSSFilter.java
package com.sfpay.scfp.oms.app.filter;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * Servlet Filter implementation class XSSFilter */public class XSSFilter implements Filter { /** * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (!(request instanceof HttpServletRequest)) { chain.doFilter(request, response); return; } HttpServletRequest hrequest = (HttpServletRequest) request; HttpServletResponse hresponse = (HttpServletResponse) response; XSSRequestWrapper secureRequest = new XSSRequestWrapper(hrequest); chain.doFilter(secureRequest, hresponse); } @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub } @Override public void destroy() { // TODO Auto-generated method stub }}
XSSRequestWrapper.java
package com.sfpay.scfp.oms.app.filter;import java.net.URLDecoder;import java.util.Enumeration;import java.util.regex.Pattern;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;/** * * @author wzs * */public class XSSRequestWrapper extends HttpServletRequestWrapper implements HttpServletRequest { HttpServletRequest orgRequest = null; public XSSRequestWrapper(HttpServletRequest servletRequest) { super(servletRequest); orgRequest = servletRequest; } public boolean getStatus() { boolean flag=true; Enumeration<String> parameterNames = super.getParameterNames(); while(parameterNames.hasMoreElements()){ String nextElement = parameterNames.nextElement(); String parameter = this.getParameter(nextElement); if(parameter.contains("script")){ flag=false; break; } } return flag; } @Override public String[] getParameterValues(String parameter) { String[] values = super.getParameterValues(parameter); if (values == null) { return null; } int count = values.length; String[] encodedValues = new String[count]; for (int i = 0; i < count; i++) { encodedValues[i] = cleanXSS(values[i]); } return encodedValues; } @Override public String getParameter(String parameter) { String value = super.getParameter(parameter); if (value == null) { return null; } return cleanXSS(value); } @Override public String getHeader(String name) { String value = super.getHeader(name); if (value == null) { return null; } return cleanXSS(value); } private String cleanXSS(String value) { if (value == null || value.isEmpty()) { return value; } // 后台在参数传递时已经进行了encode,此处需要decode。 /** * 注意:前段js对url进行两次加密 UrlEncode(UrlEncode(URL)),目的是:前台第一次通过加密使用前后台约定编码。比如:UTF-8 * 加密完成以后,此时的url基本上就是%、字母、数字了。第二次加密就是对%、字母、数字进行加密了。此时无论使用哪一种编码集 * 加密后的结果都是一样的,(UTF-8/GBK/ISO-8859-1), * 后台,只需要显示的调用一下URLDecoder.decode(value, "UTF-8"); 就可以了。 * 因为request.getParameter("name")之前会自动做一次解码的工作,而且是默认的ISO-8859-1。 * 然后通过显示的调用URLDecoder.decode(value, "UTF-8");就得到我们想要的url了 * 可参考:http://blog.csdn.net/kongqz/article/details/9028111 */ try { value = URLDecoder.decode(value, "UTF-8"); } catch (Exception e) { /* * 显示模板保存时未进行encode,出现%时decode会抛异常,异常截取改为Exception且不打印堆栈。 * 当然,【%】encode后为【%25】,若值包含%25,则会decode为%。 */// e.printStackTrace(); } // 方案一:对相关Xss特殊字符进行替换,但是,返回前台时数据还是会有问题。 // You'll need to remove the spaces from the html entities below // value = value.replaceAll("<", "<").replaceAll(">", ">"); // value = value.replaceAll("\\(", "(").replaceAll("\\)", ")"); // value = value.replaceAll("'", "'"); // value = value.replaceAll("eval\\((.*)\\)", ""); // value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\""); // value = value.replaceAll("script", "scr1pt"); // 方案二:采用XssProject进行替换,有bug就是。实现原理是将Xss特殊字段截取。需要完整的html标签,无法只针对<script>...</script>进行处理,直接返回空字符串。// StringReader reader = new StringReader(value);// StringWriter writer = new StringWriter();// try {// HTMLParser.process(reader, writer, new XSSFilter(), true);// value = writer.toString();// } catch (NullPointerException e) {// return value;// } catch (Exception ex) {// ex.printStackTrace(System.out);// } // 方案三:采用Spring提供的函数,跟方案一存在同样的bug。// value = HtmlUtils.htmlEscape(value); // 方案四:采用ESAPI进行处理。相关配置非常麻烦。 // NOTE: It's highly recommended to use the ESAPI library and uncomment the following line to avoid encoded attacks. // value = ESAPI.encoder().canonicalize(value); // 方案五:采用正则表达式,对相关Xss特殊字符进行替换。后台应该没有需要富文本编辑的功能。 // Avoid null characters value = value.replaceAll("", ""); // Avoid anything between script tags Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); // Avoid anything in a src='...' type of expression scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); // Remove any lonesome </script> tag scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); // Remove any lonesome <script ...> tag scriptPattern = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); // Avoid eval(...) expressions scriptPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); // Avoid expression(...) expressions scriptPattern = Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); // Avoid javascript:... expressions scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); // Avoid vbscript:... expressions scriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); // Avoid onload= expressions scriptPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); return value; } /** * 获取最原始的request * * @return */ public HttpServletRequest getOrgRequest() { return orgRequest; } /** * 获取最原始的request的静态方法 * * @return */ public static HttpServletRequest getOrgRequest(HttpServletRequest req) { if (req instanceof XSSRequestWrapper) { return ((XSSRequestWrapper) req).getOrgRequest(); } return req; }}
前段两次加密原理测试:可参考:http://blog.csdn.net/kongqz/article/details/9028111
String sArgs="与客户合同中约定利率为12%,系统显示利率为36.4%,故需减免复利差额"; //第一次加密,核心加密 String encode = URLEncoder.encode(sArgs, "UTF-8"); System.out.println(encode); //第二次加密,只是对%、字母、数字进行二次加密。使用任何字符集加密的结果是一样的 String encode2 = URLEncoder.encode(encode, "ISO-8859-1"); System.out.println(encode2); System.out.println("......................................."); //第一次解密:对第二次加密的结果进行解密 String decode = URLDecoder.decode(encode2, "UTF-8"); System.out.println(decode); //第二次解密:核心解密 String decode2 = URLDecoder.decode(decode, "UTF-8"); System.out.println(decode2);
对%、字母、数字进行二次加密,使用任何字符集加密的结果是一样的。测试如下;
String sArgs="与客户合同中约定利率为12%,系统显示利率为36.4%,故需减免复利差额"; //第一次加密,核心加密 String encode = URLEncoder.encode(sArgs, "UTF-8"); System.out.println(encode); //str 就是 encode 的值 String str ="%E4%B8%8E%E5%AE%A2%E6%88%B7%E5%90%88%E5%90%8C%E4%B8%AD%E7%BA%A6%E5%AE%9A%E5%88%A9%E7%8E%87%E4%B8%BA12%25%EF%BC%8C%E7%B3%BB%E7%BB%9F%E6%98%BE%E7%A4%BA%E5%88%A9%E7%8E%87%E4%B8%BA36.4%25%EF%BC%8C%E6%95%85%E9%9C%80%E5%87%8F%E5%85%8D%E5%A4%8D%E5%88%A9%E5%B7%AE%E9%A2%9D"; String decode = URLEncoder.encode(str, "UTF-8"); System.out.println(decode); String decode2 = URLEncoder.encode(str, "GBK"); System.out.println(decode2); String decode3= URLEncoder.encode(str, "ISO-8859-1"); System.out.println(decode3); //decode decode2 decode3 的结果是一样的
阅读全文
0 0
- XSS解决方法(以及前段UrlEncode 加密两次的原理分析)
- XSS的原理分析
- hashmap冲突的解决方法以及原理分析
- hashmap冲突的解决方法以及原理分析:
- hashmap冲突的解决方法以及原理分析
- hashmap冲突的解决方法以及原理分析
- XSS的原理分析与解剖
- XSS的原理分析与解剖
- XSS的原理分析与解剖
- XSS的原理分析与解剖
- XSS的原理分析与解剖
- XSS的原理分析与解剖
- XSS的原理分析与解剖
- XSS的原理分析与解剖
- XSS的原理分析与解剖
- XSS攻击的原理分析与解剖
- xss攻击原理与解决方法
- xss攻击原理与解决方法
- 深入浅出JMS(一)--JMS基本概念
- LInux下装jdk
- ActiveMQ发布订阅模式
- Xcode真机调试包路径
- selenium +webdriver+java 环境配置
- XSS解决方法(以及前段UrlEncode 加密两次的原理分析)
- BD3086
- UE4 鼠标点击事件 || 虚幻4 鼠标点击事件
- 共同学习Java源代码-数据结构-HashMap(七)
- 金融工程学知识点概况
- 行业黑马显现 月薪过万职位暴涨
- 《剑指offer》刷题笔记(举例让抽象具体化):二叉树中和为某一值的路径
- NYOJ 非洲小孩
- Linux服务器tomcat启动慢的问题,解决