存储型XSS
又称为持久型跨站点脚本,它一般发生在XSS攻击向量(一般指XSS攻击代码)存储在网站数据库,当一个页面被用户打开的时候执行。每当用户打开浏览器,脚本执行。持久的XSS相比非持久性XSS攻击危害性更大,因为每当用户打开页面,查看内容时脚本将自动执行。谷歌的orkut曾经就遭受到XSS。
简单例子:
从名字就可了解到存储型XSS攻击就是将攻击代码存入数据库中,然后客户端打开时就执行这些攻击代码。例如留言板
留言板表单中的表单域:
正常操作:
用户是提交相应留言信息;将数据存储到数据库;其他用户访问留言板,应用去数据并显示。
非正常操作:
攻击者在value填写<script>alert(‘foolish!’)</script>【或者html其他标签(破坏样式。。。)、一段攻击型代码】;
将数据存储到数据库中;其他用户取出数据显示的时候,将会执行这些攻击性代码
反射型xss攻击
又称为非持久性跨站点脚本攻击,它是最常见的类型的XSS。漏洞产生的原因是攻击者注入的数据反映在响应中。一个典型的非持久性XSS包含一个带XSS攻击向量的链接(即每次攻击需要用户的点击)。
简单例子
正常发送消息:
http://www.test.com/message.php?send=Hello,World!
接收者将会接收信息并显示Hello,Word
非正常发送消息:
http://www.test.com/message.php?send=<script>alert(‘foolish!’)</script>!
接收者接收消息显示的时候将会弹出警告窗口
DOMBasedXSS(基于dom的跨站点脚本攻击)
基于DOM的XSS有时也称为type0XSS。当用户能够通过交互修改浏览器页面中的DOM(DocumentObjectModel)并显示在浏览器上时,就有可能产生这种漏洞,从效果上来说它也是反射型XSS。
通过修改页面的DOM节点形成的XSS,称之为DOMBasedXSS。
前提是易受攻击的网站有一个HTML页面采用不安全的方式从document.location 或document.URL 或 document.referrer获取数据(或者任何其他攻击者可以修改的对象)。
修复漏洞方针
【不相应用户提交的数据,过滤过滤过滤!】
1、将重要的cookie标记为http only, 这样的话Javascript 中的document.cookie语句就不能获取到cookie了.
2、表单数据规定值的类型,例如:年龄应为只能为int、name只能为字母数字组合。。。。
4、对数据进行Html Encode 处理
5、过滤或移除特殊的Html标签
相关代码
package com.supporter.prj.eip.webapp.filter;
import com.supporter.prj.eip.webapp.utils.XssHttpServletRequestWrapper;
import com.supporter.prj.eip_service.exception.BaseRuntimeException;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
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;
public class XssFilter
implements Filter
{
private static final String KEY_BEGIN = "begin";
private static final String KEY_END = "end";
private static final String KEY_EQUALS = "equals";
private String excludedKeyName;
private List<String> keyNameList;
private List<String> notCheckURLList;
private static List<Map<String, String>> excludes;
HashMap<String, String> map = new HashMap();
public void init(FilterConfig filterConfig) throws ServletException
{
this.excludedKeyName = filterConfig.getInitParameter("excludedKeyName");
if (this.excludedKeyName != null) {
this.keyNameList = new ArrayList();
StringTokenizer st = new StringTokenizer(this.excludedKeyName, "|");
while (st.hasMoreTokens()) {
this.keyNameList.add(st.nextToken());
}
}
String ls_URLExclued = filterConfig.getInitParameter("excludedCheckURLList");
if (ls_URLExclued != null) {
StringTokenizer lstrtk_URLExcluded = new StringTokenizer(ls_URLExclued, ";");
this.notCheckURLList = new ArrayList();
while (lstrtk_URLExcluded.hasMoreTokens()) {
this.notCheckURLList.add(lstrtk_URLExcluded.nextToken());
}
}
initExcludeConfig(filterConfig);
}
public void doFilter(ServletRequest srequest, ServletResponse sresponse, FilterChain chain)
throws IOException, ServletException
{
HttpServletRequest request = (HttpServletRequest)srequest;
if (isExcludeUrl(request)) {
chain.doFilter(request, sresponse);
} else {
Map map = request.getParameterMap();
for (String key : map.keySet()) {
if (this.keyNameList.contains(key)) {
System.out.println("检验非法参数名称:---" + request.getRequestURL());
throw new BaseRuntimeException("503", "非法操作!");
}
}
chain.doFilter(new XssHttpServletRequestWrapper(request), sresponse);
}
}
public void destroy()
{
this.excludedKeyName = null;
this.keyNameList = null;
this.notCheckURLList = null;
}
private boolean isExcludeUrl(HttpServletRequest request)
throws IOException, ServletException
{
String contextPath = request.getContextPath();
int index = request.getRequestURI().indexOf(contextPath);
String uri = request.getRequestURI().substring(index + contextPath.length());
if (excludes != null) {
for (Map data : excludes) {
String begin = (String)data.get("begin");
String end = (String)data.get("end");
String equals = (String)data.get("equals");
if (((begin == null) || (uri.startsWith(begin))) &&
((end == null) || (uri.endsWith(end))) && (
(equals == null) || (uri.equals(equals))))
{
return true;
}
}
}
return false;
}
private void initExcludeConfig(FilterConfig filterConfig)
{
String exclude = filterConfig.getInitParameter("excludedCheckURLList");
if ((exclude != null) && (exclude.length() > 0)) {
String[] excludesVal = exclude.replaceAll("\n", "").replaceAll("\t", "").split(";");
excludes = new ArrayList();
for (String val : excludesVal) {
val = val.trim();
Map data = new HashMap();
int i = val.indexOf("*");
if (i > -1) {
String begin = val.substring(0, i);
if ((begin != null) && (begin.length() > 0)) {
data.put("begin", begin.trim());
}
String end = val.substring(i + 1);
if ((end != null) && (end.length() > 0))
data.put("end", end.trim());
}
else {
data.put("equals", val);
}
excludes.add(data);
}
}
}
}