存儲型XSS
又稱為持久型跨站點(diǎn)腳本,它一般發(fā)生在XSS攻擊向量(一般指XSS攻擊代碼)存儲在網(wǎng)站數(shù)據(jù)庫,當(dāng)一個(gè)頁面被用戶打開的時(shí)候執(zhí)行。每當(dāng)用戶打開瀏覽器,腳本執(zhí)行。持久的XSS相比非持久性XSS攻擊危害性更大,因?yàn)槊慨?dāng)用戶打開頁面,查看內(nèi)容時(shí)腳本將自動執(zhí)行。谷歌的orkut曾經(jīng)就遭受到XSS。
簡單例子:
從名字就可了解到存儲型XSS攻擊就是將攻擊代碼存入數(shù)據(jù)庫中,然后客戶端打開時(shí)就執(zhí)行這些攻擊代碼。例如留言板
留言板表單中的表單域:
正常操作:
用戶是提交相應(yīng)留言信息;將數(shù)據(jù)存儲到數(shù)據(jù)庫;其他用戶訪問留言板,應(yīng)用去數(shù)據(jù)并顯示。
非正常操作:
攻擊者在value填寫<script>alert(‘foolish!’)</script>【或者h(yuǎn)tml其他標(biāo)簽(破壞樣式。。。)、一段攻擊型代碼】;
將數(shù)據(jù)存儲到數(shù)據(jù)庫中;其他用戶取出數(shù)據(jù)顯示的時(shí)候,將會執(zhí)行這些攻擊性代碼
反射型xss攻擊
又稱為非持久性跨站點(diǎn)腳本攻擊,它是最常見的類型的XSS。漏洞產(chǎn)生的原因是攻擊者注入的數(shù)據(jù)反映在響應(yīng)中。一個(gè)典型的非持久性XSS包含一個(gè)帶XSS攻擊向量的鏈接(即每次攻擊需要用戶的點(diǎn)擊)。
簡單例子
正常發(fā)送消息:
http://www.test.com/message.php?send=Hello,World!
接收者將會接收信息并顯示Hello,Word
非正常發(fā)送消息:
http://www.test.com/message.php?send=<script>alert(‘foolish!’)</script>!
接收者接收消息顯示的時(shí)候?qū)棾鼍娲翱?/strong>
DOMBasedXSS(基于dom的跨站點(diǎn)腳本攻擊)
基于DOM的XSS有時(shí)也稱為type0XSS。當(dāng)用戶能夠通過交互修改瀏覽器頁面中的DOM(DocumentObjectModel)并顯示在瀏覽器上時(shí),就有可能產(chǎn)生這種漏洞,從效果上來說它也是反射型XSS。
通過修改頁面的DOM節(jié)點(diǎn)形成的XSS,稱之為DOMBasedXSS。
前提是易受攻擊的網(wǎng)站有一個(gè)HTML頁面采用不安全的方式從document.location 或document.URL 或 document.referrer獲取數(shù)據(jù)(或者任何其他攻擊者可以修改的對象)。
修復(fù)漏洞方針
【不相應(yīng)用戶提交的數(shù)據(jù),過濾過濾過濾!】
1、將重要的cookie標(biāo)記為http only, 這樣的話Javascript 中的document.cookie語句就不能獲取到cookie了.
2、表單數(shù)據(jù)規(guī)定值的類型,例如:年齡應(yīng)為只能為int、name只能為字母數(shù)字組合。。。。
4、對數(shù)據(jù)進(jìn)行Html Encode 處理
5、過濾或移除特殊的Html標(biāo)簽
相關(guān)代碼
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("檢驗(yàn)非法參數(shù)名稱:---" + 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);
}
}
}
}