XSS攻击及预防
2015-12-29 11:05
169 查看
跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script(php,js等)代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的特殊目的。
攻击实例
下面为一个Input标签:
当用输入值为" onfocus="alert(document.cookie) 时,input标签内容变为 <input type="text" value=""onfocus="alert(document.cookie)"></input>
当input中的可以执行的js脚本被存储到数据库中。用户再次取出显示时。就会取到用户的cookie。从而得到用户名和密码。
(1)添加用户
(2)数据库中存储可执行脚本
(3)编辑用户(XSS攻击发生)
[b]攻击危害[/b]
以上获取用户名和密码只是个简单的xss攻击,还有跟多的XSS攻击实例。例如将用户导航到其他网站,后台挂马操作等
[b]攻击预防[/b]
原理:主要采用过滤器对请求中的特殊字符进行编码转化。从而将可以执行的script代码变为不可以执行的script脚本存储到数据库中。
[b]示例:开发环境采用的SSH框架。所以采用过滤器,注意这里采用装饰者模式对请求request对象进行了包装。[/b]
注:由于使用了struts2.所以要[b]自定义的装饰者对象继承StrutsRequestWrapper类。但是这样对于上传文件获得不到参数。因为上传文件请求类型为MultiPart[/b]
[b]所以包装对象为原始的请求HttpServletRequestWrapper[/b]
具体代码:
这里编码实现主要是xssEncode(String source)方法。XssStrutsRequestWrapper必须重写getParameterMap()方法。并调用xssEncode(String source)编码。
[b]结果:[/b]
数据中内容将英文的“变为全角" 。从而将可以执行的js脚本并未不可执行的脚本存储在数据库中。
攻击实例
下面为一个Input标签:
<input type="text" value="value"></input>
当用输入值为" onfocus="alert(document.cookie) 时,input标签内容变为 <input type="text" value=""onfocus="alert(document.cookie)"></input>
当input中的可以执行的js脚本被存储到数据库中。用户再次取出显示时。就会取到用户的cookie。从而得到用户名和密码。
(1)添加用户
(2)数据库中存储可执行脚本
(3)编辑用户(XSS攻击发生)
[b]攻击危害[/b]
以上获取用户名和密码只是个简单的xss攻击,还有跟多的XSS攻击实例。例如将用户导航到其他网站,后台挂马操作等
[b]攻击预防[/b]
原理:主要采用过滤器对请求中的特殊字符进行编码转化。从而将可以执行的script代码变为不可以执行的script脚本存储到数据库中。
[b]示例:开发环境采用的SSH框架。所以采用过滤器,注意这里采用装饰者模式对请求request对象进行了包装。[/b]
注:由于使用了struts2.所以要[b]自定义的装饰者对象继承StrutsRequestWrapper类。但是这样对于上传文件获得不到参数。因为上传文件请求类型为MultiPart[/b]
[b]所以包装对象为原始的请求HttpServletRequestWrapper[/b]
具体代码:
public class XssFilter implements Filter { public void destroy() { } public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { XssStrutsRequestWrapper xssRequest = new XssStrutsRequestWrapper((HttpServletRequest) servletRequest); HttpServletResponse response = (HttpServletResponse)servletResponse; filterChain.doFilter(xssRequest, response); } public void init(FilterConfig arg0) throws ServletException { } }
public class XssStrutsRequestWrapper extends HttpServletRequestWrapper{ private HttpServletRequest orgRequest; public XssStrutsRequestWrapper(HttpServletRequest request) { super(request); this.orgRequest = request; } /** * 获取最原始的request * @return */ public HttpServletRequest getOrgRequest() { return orgRequest; } /** * 获取最原始的request的静态方法 * @return */ public static HttpServletRequest getOrgRequest(HttpServletRequest req) { if (req instanceof XssStrutsRequestWrapper) { return ((XssStrutsRequestWrapper) req).getOrgRequest(); } return req; } /** * 覆盖getParameter方法,将参数名和参数值都做xss过滤。<br/> * 如果需要获得原始的值,则通过super.getParameterValues(name)来获取<br/> * getParameterNames,getParameterValues和getParameterMap也可能需要覆盖 */ @Override public String getParameter(String name) { String value = super.getParameter(xssEncode(name)); if (value != null) { value = xssEncode(value); } return value; } /** * 覆盖getHeader方法,将参数名和参数值都做xss过滤。<br/> * 如果需要获得原始的值,则通过super.getHeaders(name)来获取<br/> * getHeaderNames 也可能需要覆盖 */ @Override public String getHeader(String name) { String value = super.getHeader(xssEncode(name)); if (value != null) { value = xssEncode(value); } return value; } /** * 覆盖getParamterMap方法, */ @Override @SuppressWarnings("unchecked") public Map<String, String[]> getParameterMap() { Map<String, String[]> paramMap = super.getParameterMap(); Set<String> keySet = paramMap.keySet(); for (Iterator iterator = keySet.iterator(); iterator.hasNext();) { String key = (String) iterator.next(); String[] str = paramMap.get(key); for(int i=0; i<str.length; i++) { // 对参数值进行编码过滤 str[i] = xssEncode(str[i]); } } return paramMap ; } public String xssEncode(String source){ if (source == null) { return ""; } String html = ""; StringBuffer buffer = new StringBuffer(); for (int i = 0; i < source.length(); i++) { char c = source.charAt(i); switch (c) { case '<': //buffer.append("<"); buffer.append("<"); break; case '>': //buffer.append(">"); buffer.append(">"); break; case '&': //buffer.append("&"); buffer.append("&"); break; case '"': //buffer.append("""); buffer.append("""); break; default: buffer.append(c); } } html = buffer.toString(); return html; } }
这里编码实现主要是xssEncode(String source)方法。XssStrutsRequestWrapper必须重写getParameterMap()方法。并调用xssEncode(String source)编码。
[b]结果:[/b]
数据中内容将英文的“变为全角" 。从而将可以执行的js脚本并未不可执行的脚本存储在数据库中。
相关文章推荐
- Android Studio 内存不足
- Android仿微信实现下拉列表
- after与before应用
- IEDriverServer,和 ChromeDriver
- BNUOJ49098 神奇的身高 - DP (LIS)
- [转]CocoaPods的安装使用和常见问题
- Linux的分区方法
- 刷新实现原理
- Android sdk content loader 0%的解决方案
- 在iOS 8中使用UIAlertController
- locate包的安装
- ahjesus Axure RP 7.0注册码
- swift 函数创建
- JSON服务器的使用和客户端的解析
- EF学习笔记——通用增删改查方案
- 旋转转盘选择Menu--第三方开源--CircleMenu
- PopupWindow的简单使用
- ListView嵌套ListView的思路
- gpg: no valid OpenPGP data found
- 图片居中显示