在項(xiàng)目一開始,如果就考慮到這個(gè)問題的話,那是可以完全避免的。
反script注入:在jsp頁面中解決,增刪查修審都用struts標(biāo)簽 ,是沒有任何問題的。如果是html標(biāo)簽的話,用jstl標(biāo)簽也可以完全解決。
那么如果用到文本編輯器的時(shí)候,又該怎么解決???我的反SCRIPT注入就可以解決這個(gè)問題了。
反sql注入:如果是jdbc的話,不要用Statement,用PreparedStatement就可以避免。如果用hibernate的話,用 Criteria查詢就可以解決這個(gè)問題。
如何是在項(xiàng)目快完結(jié)的時(shí)候才發(fā)現(xiàn)這個(gè)問題,那該怎么解決???
apache提供了工具類:org.apache.commons.lang.StringEscapeUtils,它里面有對應(yīng)的方法解決這個(gè)問題。
下面是我自己提供一種方法。
為了實(shí)現(xiàn)反SQL注入和反SCRIPT注入,本例應(yīng)用反射技術(shù)和責(zé)任鏈模式實(shí)現(xiàn)了這個(gè)功能。它對于系統(tǒng)來說是可插撥的,這樣就實(shí)現(xiàn)了與系統(tǒng)的松散耦合。
它的主要思想是:把Form對象,PO對象以及VO等對象中的String型屬性的值或者String類型的參數(shù)進(jìn)行過濾后重新封裝為原有類型的對象。在獲取對象的時(shí)候應(yīng)用了 java反映技術(shù),
在進(jìn)行過濾的時(shí)候,實(shí)現(xiàn)了鏈?zhǔn)竭^濾。這樣做,就是為了達(dá)到可維護(hù)性,可擴(kuò)展性,可重用性以及靈活性的目的。
以下是源代碼:
package net.better_best.www.utils.filter;
public class Request {
// 存儲需要過濾的字符串
private String requestStr;
public String getRequestStr() {
return requestStr;
}
public void setRequestStr(String requestStr) {
this.requestStr = requestStr;
}
}
package net.better_best.www.utils.filter;
public class FilterConstant {
//定義sql過濾的內(nèi)容
public static String[][] SQL_FILTER = {
{";",""},
{"'","''"},
{"--",""},
{"%",""}
};
//定義script過濾的內(nèi)容
public static String[][] SCRIPT_FILTER = {
{"(<[i|I][n|N][p|P][u|U][t|T])([^>]*)(/>)",""},
{"(<[i|I][n|N][p|P][u|U][t|T])([\\s\\S]*)(</[i|I][n|N][p|P][u|U][t|T]>)",""},
{"(<[t|T][a|A][b|B][l|L][e|E])([^>]*)(/>)",""},
{"(<[t|T][a|A][b|B][l|L][e|E])([\\s\\S]*)(</[t|T][a|A][b|B][l|L][e|E]>)",""},
{"(<[d|D][i|I][v|V])([^>]*)(/>)",""},
{"(<[d|D][i|I][v|V])([\\s\\S]*)(</[d|D][i|I][v|V]>)",""},
{"(<[b|B][u|U][t|T][t|T][o|O][n|N])([^>]*)(/>)",""},
{"(<[b|B][u|U][t|T][t|T][o|O][n|N])([\\s\\S]*)(</[b|B][u|U][t|T][t|T][o|O][n|N]>)",""},
{"(<[s|S][c|C][r|R][i|I][p|P][t|T])([^>]*)(/>)",""},
{"(<[s|S][c|C][r|R][i|I][p|P][t|T])([\\s\\S]*)(</[s|S][c|C][r|R][i|I][p|P][t|T])(>)",""},
};
}
package net.better_best.www.utils.filter;
public interface IFilter {
void doFilter(Request request, FilterChain chain);
}
package net.better_best.www.utils.filter;
public class SqlFilter implements IFilter {
@Override
//進(jìn)行sql過濾
public void doFilter(Request request, FilterChain chain) {
if (request != null) {
String strRequest = request.getRequestStr();
String[][] sqlFilter = FilterConstant.SQL_FILTER;
for (String[] strings : sqlFilter) {
strRequest = strRequest.replace(strings[0], strings[1]);
}
request.setRequestStr(strRequest);
}
chain.doFilter(request, chain);
}
}
package net.better_best.www.utils.filter;
public class ScriptFilter implements IFilter {
@Override
//進(jìn)行script過濾
public void doFilter(Request request, FilterChain chain) {
if (request != null) {
String strRequest = request.getRequestStr();
String[][] scriptFilter = FilterConstant.SCRIPT_FILTER;
for (String[] strings : scriptFilter) {
strRequest = strRequest.replaceAll(strings[0], strings[1]);
}
request.setRequestStr(strRequest);
}
chain.doFilter(request, chain);
}
}
package net.better_best.www.utils.filter;
public enum FilterType {
SQL_TYPE,SCRIPT_TYPE ;
}
package net.better_best.www.utils.filter;
public class FilterHelper {
/*
* 生成過濾鏈條 參數(shù):String type:過濾類型 返回:FilterChain; 根據(jù)過濾類型產(chǎn)生過濾鏈條
*/
public static FilterChain createFilterChain(FilterType type,FilterChain fChain) throws Exception {
if (type == null)
return null;
else if (type.equals(FilterType.SQL_TYPE))
return fChain.addFilter(new SqlFilter());
else if (type.equals(FilterType.SCRIPT_TYPE))
return fChain.addFilter(new ScriptFilter());
else
return null;
}
/*
* 把要過濾的字符串封裝成Request對象
*/
public static Request init(String str) throws Exception {
if (str == null || str == "")
return null;
Request request = new Request();
request.setRequestStr(str);
return request;
}
/*
* 對Request對象進(jìn)行循環(huán)過濾
*/
public static String result(Request request, FilterChain fChain)
throws Exception {
if (request == null || fChain == null || fChain.size() == 0)
return null;
fChain.doFilter(request, fChain);
return request.getRequestStr();
}
}
package net.better_best.www.utils.filter;
import java.util.ArrayList;
import java.util.List;
public class FilterChain implements IFilter {
// 使用 List 保存過濾器
private List<IFilter> filters = new ArrayList<IFilter>();
private int index = 0;
// 用于添加過濾器,可以添加實(shí)現(xiàn)了IFilter接口的FilterChain
public FilterChain addFilter(IFilter f) {
this.filters.add(f);
return this;
}
@Override
public void doFilter(Request request, FilterChain chain) {
// 判斷是否是否遍歷到 List 的最大值,如果是 return
if (index == filters.size())
return;
// 逐一獲取過濾器
IFilter f = filters.get(index);
// 此過濾器鏈的下標(biāo),是遍歷過濾器的索引
index++;
// 使用列表中的第index個(gè)過濾器,將更改后的 request ,chain 傳進(jìn)去,
f.doFilter(request,chain);
index = 0;
}
public int size(){
return filters.size();
}
}
package net.better_best.www.utils;
import java.lang.reflect.Field;
import net.better_best.www.utils.filter.FilterChain;
import net.better_best.www.utils.filter.FilterHelper;
import net.better_best.www.utils.filter.FilterType;
public class Filter {
/*
* 參數(shù):Object,接收ActionForm,Plain Object,View.Object的屬性值應(yīng)為單值類型,不能為復(fù)合類型或數(shù)組類型;
* 參數(shù):FilterType,定義需要過濾的類型; 返回值:Object; 作用:根據(jù)已定義的過濾規(guī)則,過濾所傳入Object值;
*/
public static Object objectFilter(Object obj, FilterType... types) {
if (obj == null)return obj;
Class clazz = obj.getClass();
if (clazz.isArray() || clazz.isInterface() || clazz.isPrimitive())return obj;
Field[] fds = clazz.getDeclaredFields();
for (Field field : fds) {
if (field.getType().getName().equals("java.lang.String")) {
field.setAccessible(true);
Object before = null;
try {
before = field.get(obj);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
if (before != null)
try {
field.set(obj, doFilter(before.toString(), types));
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
return obj;
}
/*
* 按照定義好的過濾規(guī)則,進(jìn)行過濾; 參數(shù):String str ,待過濾字符串 返回:String; 已過濾字符串
*/
public static String doFilter(String str, FilterType... types) {
if (str == null || str == "")
return null;
FilterChain fChain = new FilterChain();
String result = "";
try {
if (types.length == 0) {
FilterType[] filterTypes = FilterType.values();
for (FilterType filterType : filterTypes) {
fChain = FilterHelper.createFilterChain(filterType, fChain);
}
} else {
for (FilterType type : types) {
fChain = FilterHelper.createFilterChain(type, fChain);
}
}
if (fChain == null) {
result = str;
} else {
result = FilterHelper.result(FilterHelper.init(str), fChain);
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
使用方法:調(diào)用Filter的兩個(gè)方法,就可以了。
以上內(nèi)容為全部代碼;
歡迎對本文的內(nèi)容提出不同見解和質(zhì)疑,不勝感激。
如果疑問,可發(fā)郵件聯(lián)系我??砂l(fā)郵件索取源代碼。