SQL注入攻擊能得逞是因為在原有SQL語句中加入了新的邏輯
比如:原sql="select * from user where userid='"+userid+"'";
如果,我們把userid="' or 1='1";
這樣拼接的sql="select * from user where userid='' or 1='1'";
這樣的sql就可列出表里的所有記錄
對於一個好的程序員來說,編寫高質量的代碼,可以防止sql注入
比如使,用PreparedStatement來代替Statement來執行SQL語句,其后只是輸入參數
SQL注入攻擊手段將無效,這是因為PreparedStatement不允許在不同的插入時間改變查詢的邏輯結構
大部分的SQL注入已經擋住了
有時候我們的sql語句是拼接,這樣如果再重構我們的數據庫操作的話,會很麻煩的
為此我們需要對表單中的非法字符進行過濾
當然,我們可以用Filter來實現,對提交到servlet的表單進行驗證
但是,對於Struts2框架來說,似乎不起作用
這就需要用到struts2的攔截器來實現同樣的功能
攔截器使用就不再介紹,網上很多
現在就我的實現代碼貼出來供大家參考
IllegalCharacterInterceptor.java
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.util.ValueStack;
import com.sun.imageio.plugins.common.I18N;
public class IllegalCharacterInterceptor extends AbstractInterceptor {
@Override
public String intercept(ActionInvocation invocation) throws Exception {
//通過核心調度器invocation來獲得調度的Action上下文
ActionContext actionContext = invocation.getInvocationContext();
//獲取Action上下文的值棧
ValueStack stack = actionContext.getValueStack();
//獲取上下文的請求參數
Map valueTreeMap = actionContext.getParameters();
//獲得請求參數集合的迭代器
Iterator iterator = valueTreeMap.entrySet().iterator();
//遍歷組裝請求參數
while(iterator.hasNext()){
//獲得迭代的鍵值對
Entry entry = (Entry) iterator.next();
//獲得鍵值對中的鍵值
String key = (String) entry.getKey();
//原請求參數,因為有可能一鍵對多值所以這里用的String[]
String[] oldValues = null;
//對參數值轉換成String類型的
if(entry.getValue() instanceof String){
oldValues = new String[]{entry.getValue().toString()};
}else{
oldValues = (String[])entry.getValue();
}
//處理后的請求參數
String newValueStr = null;
//對請求參數過濾處理
if(oldValues.length>1){
newValueStr = "{" ;
for(int i=0 ;i<oldValues.length; i++){
//替換掉非法參數,這里只替換掉了',如有其他需求,可以專門寫一個處理字符的類
newValueStr+=oldValues[i].toString().replaceAll("'","");
if(i!=oldValues.length-1){
newValueStr+=",";
}
}
newValueStr+="}";
}else if(oldValues.length==1){
//替換掉非法參數,這里只替換掉了',如有其他需求,可以專門寫一個處理字符的類
newValueStr = oldValues[i].toString().replaceAll("'","");
}else{
newValueStr = null;
}
//處理后的請求參數加入值棧中
stack.setValue(key, newValueStr);
}
String result = null;
try {
// 調用下一個攔截器,如果攔截器不存在,則執行Action
result = invocation.invoke();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
攔截器寫好后,就可以使用了
在struts.xml中配置自定義攔截器時,需把默認攔截器加上
不然默認攔截器會不起作用的
<interceptors>
<interceptor name="illegalCharacter" class="com.ainong.interceptor.IllegalCharacterInterceptor"/>
<interceptor-stack name="myStack">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="illegalCharacter"></interceptor-ref>
</interceptor-stack>
</interceptors>
這樣就可使用myStack來攔截了
如果我們對於對每個Action都配置<interceptor-ref name="myStack"/>比較麻煩
我們也可把上面的攔截器棧,設置為默認攔截器棧,這樣可以對package中的所有Action起作用
而不需要我們配置
<default-interceptor-ref name="myStack"></default-interceptor-ref>