XSS攻击防御的filter实现
2016-09-01 09:29
127 查看
XSS攻击的基本概念主要是:
恶意用户在网页的可输入的地方输入可执行的脚本(如javascript)代码,从而使网页解析执行该脚本代码来达到攻击的效果, 比如在网站上写一篇文章时包含这段代码: ,如果该字符串在后台没有进行XSS攻击防范,就会导致导致其他人访问该文章时网页执行上面的脚本从而alert(1).
防止XSS攻击最主要方式 :
把特殊标签符号转码,比如把”<”, “>”, “&”等这些特殊字符转码即可防止XSS攻击.
要考虑代码的维护问题,我们不能把太多的XSS防攻击代码侵入到业务代码中, 我们可以使用过滤器的方式来转换编码.在过滤器中获取每一个参数进行转换编码:
做法:
1. 在web.xml中加入filter如下:
编写filter实现如下:
(默认情况下request只有getParameter()方法而没有setParameter方法, 所以默认情况下我们无法将转码后的参数放回request中的, 所以我们需要自己实现一个包装类来处理参数)
但有一个问题没解决,就是如果提交一个包含文件属性的表单时, 这个filter没法拦截, 测试了几次没找到好的方法, 网上也没有找到关于这方面的解决方案, (自己遇到这种情况时是在业务逻辑中侵入了少量的过滤代码) . 如果各位大大找到包含文件的表单的过滤器实现方案,欢迎留言.
恶意用户在网页的可输入的地方输入可执行的脚本(如javascript)代码,从而使网页解析执行该脚本代码来达到攻击的效果, 比如在网站上写一篇文章时包含这段代码: ,如果该字符串在后台没有进行XSS攻击防范,就会导致导致其他人访问该文章时网页执行上面的脚本从而alert(1).
防止XSS攻击最主要方式 :
把特殊标签符号转码,比如把”<”, “>”, “&”等这些特殊字符转码即可防止XSS攻击.
要考虑代码的维护问题,我们不能把太多的XSS防攻击代码侵入到业务代码中, 我们可以使用过滤器的方式来转换编码.在过滤器中获取每一个参数进行转换编码:
做法:
1. 在web.xml中加入filter如下:
<!--配置XSS防攻击的过滤器--> <filter> <filter-name>XSSFilter</filter-name> <filter-class>com.xxx.xxx.filter.XSSFilter</filter-class> </filter> <filter-mapping> <filter-name>XSSFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
编写filter实现如下:
(默认情况下request只有getParameter()方法而没有setParameter方法, 所以默认情况下我们无法将转码后的参数放回request中的, 所以我们需要自己实现一个包装类来处理参数)
package com.xxx.xxx.filter; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException; /** * 防止XSS攻击的过滤器类 * @Author yss * @Version 1.0 * @see */ public class XSSFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } /** * @param request 请求 * @param servletResponse 相应 * @param filterChain 过滤器链 * @throws IOException 异常 * @throws ServletException 异常 */ @Override public void doFilter(ServletRequest request, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { //自定义request包装类,并把它传入过滤器链 ParameterRequestWrapper requestWrapper = new ParameterRequestWrapper((HttpServletRequest) request); filterChain.doFilter(requestWrapper, servletResponse); } @Override public void destroy() { } }
package com.xxx.xxx.filter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.util.HashMap; import java.util.Map; /** * request的参数包装类 * @Author yss * @Version 1.0 * @see */ public class ParameterRequestWrapper extends HttpServletRequestWrapper { private Map<String , String[]> params = new HashMap<String, String[]>(); @SuppressWarnings("unchecked") public ParameterRequestWrapper(HttpServletRequest request) { // 将request交给父类,以便于调用对应方法的时候,将其输出,其实父亲类的实现方式和第一种new的方式类似 super(request); //将参数表,赋予给当前的Map以便于持有request中的参数 this.params.putAll(request.getParameterMap()); } /** * 重写getParameter,代表参数从当前类中的map获取 * @param name * @return */ @Override public String getParameter(String name) { String[]values = params.get(name); if(values == null || values.length == 0) { return null; } String result = values[0]; result = htmlEncode(result);//转码 return result; } public String[] getParameterValues(String name) {//同上 if(params.get(name) instanceof String[]) {//数组 int size = ((String[])params.get(name)).length; String[] vals = new String[size]; for(int i=0;i<((String[])params.get(name)).length;i++) { String str = htmlEncode(((String[])params.get(name))[i]);//转码 vals[i] = str; } return vals; } return null; } public void addAllParameters(Map<String , Object>otherParams) {//增加多个参数 for(Map.Entry<String , Object>entry : otherParams.entrySet()) { addParameter(entry.getKey() , entry.getValue()); } } public void addParameter(String name , Object value) {//增加参数 if(value != null) { if(value instanceof String[]) { params.put(name , (String[])value); }else if(value instanceof String) { params.put(name , new String[] {(String)value}); }else { params.put(name , new String[] {String.valueOf(value)}); } } } /** * 对传入的字符串str进行Html encode转换 * @param value 需要处理的字符串 * @return 处理后的字符串 */ public static String htmlEncode(String value) { StringBuffer stringBuffer = new StringBuffer(); for (int i = 0, len = value.length(); i < len; i++) { stringBuffer.append(htmlEncode(value.charAt(i))); } return stringBuffer.toString(); } /**转码规则: * 对每一个字符进行检查,转换字符。 * @param c * @return */ private static String htmlEncode(char c) { switch (c) { case '&': return "&"; case '<': return "<"; case '>': return ">"; case '"': return """; case ' ': return " "; default: return c + ""; } } }
但有一个问题没解决,就是如果提交一个包含文件属性的表单时, 这个filter没法拦截, 测试了几次没找到好的方法, 网上也没有找到关于这方面的解决方案, (自己遇到这种情况时是在业务逻辑中侵入了少量的过滤代码) . 如果各位大大找到包含文件的表单的过滤器实现方案,欢迎留言.
相关文章推荐
- Web App struts框架里实现Filter.
- 用ImessageFilter接口实现截获键盘消息
- 通过Filter进行统一编码的实现
- Jsp/Java代码分离.实现页面真正的代码分离 实现框架代码:BasePage,TextBox,BasePageFilter
- 用ImessageFilter接口实现截获键盘消息
- 实现 UnhandledExceptionFilter() 需要的几个问题
- FreeBSD+IPFILTER实现整网(N个Vlan)透明代理上网
- 用ImessageFilter接口实现截获键盘消息
- 使用(Filter)过虑器实现对Session是否过时的判断
- XForum 里用 Filter 编程实现安全访问控制
- 实现file writer filter
- 自己写一个strcpy(char*dest,char*src),如何在函数内部实现防御性溢出?
- jsp实用两例:用filter解决汉字编码及禁止页面缓存 和 用listener实现在线人数统计.
- CSS Filter 代替 图片 实现 渐变背景效果。
- 使用Filter实现静态HTML缓冲
- 通过spring的拦截器实现Filter的功能
- 使用Regex实现的为JFileChooser使用的FileFilter对象的创建类
- jsp实用两例:用filter解决汉字编码及禁止页面缓存 和 用listener实现在线人数统计
- 使用Filter实现信息的二次检索
- HTMLParser的功能及实现之Filter模式