|
web项目:漏洞修复(3)_struts2拦截器
只需要一个java文件+struts.xml的配置
1.java类IllegalCharacterInterceptor.java 可在相应位置 ,指定过滤的 方法、参数(参数值、参数名)等,可过滤指定元素
package com.*.*.*.util;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.struts2.StrutsStatics;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.util.ValueStack;
/**
* 拦截器-请求拦截过滤
*/
public class IllegalCharacterInterceptor extends AbstractInterceptor { private static Pattern SCRIPT_PATTERN = Pattern.compile("<script.*>.*<\\/script\\s*>"); private static Pattern HTML_PATTERN = Pattern.compile("<[^>]+>"); private static Pattern SQL_PATTERN1 = Pattern.compile("/((\\%3D)|(=))[^\\n]*((\\%27)|(\\)|(\\-\\-)|(\\%3B)|(:))/ix"); private static Pattern SQL_PATTERN2 = Pattern.compile("/\\w*((\\%27)|(\\'))((\\%6F)|o|(\\%4F))((\\%72)|r|(\\%52))/ix"); private static Pattern SQL_PATTERN3 = Pattern.compile("/((\\%27)|(\\'))union/ix");
@Override public String intercept(ActionInvocation invocation) throws Exception {
// System.out.println("+++++++++++++invocation+++++++++++++++++++++"); // 通过核心调度器invocation来获得调度的Action上下文 ActionContext actionContext = invocation.getInvocationContext(); //String actionName = invocation.getProxy().getActionName();//ActionName //获得请求 HttpServletRequest request= (HttpServletRequest) actionContext.get(StrutsStatics.HTTP_REQUEST); //获得请求路径 String url=request.getRequestURI();
// System.out.println("URL=="+url);
// System.out.println("Action"+invocation.getAction().getClass().getName());
// System.out.println("Struts2 Action"+invocation.getProxy().getActionName());
// System.out.println(""+invocation.getProxy().getMethod()); // 获取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 ( isUrlContains(url) && isKeySqlFunctions(key)) { //System.out.println("URL KEY "); // newValueStr=null; } else { // if (oldValues.length > 1) { newValueStr = "{"; for (int i = 0; i < oldValues.length; i++) { // 替换掉非法参数,这里只替换掉了',如有其他需求,可以专门写一个处理字符的类 //System.out.println("开始参数内容的过滤"); newValueStr += replaceString(oldValues[i].toString()); if (i != oldValues.length - 1) { newValueStr += ","; } } newValueStr += "}"; } else if (oldValues.length == 1) { // 替换掉非法参数,这里只替换掉了',如有其他需求,可以专门写一个处理字符的类 //System.out.println("开始参数内容的过滤"); newValueStr = replaceString(oldValues[0].toString()); } else { newValueStr = null; } }
// 处理后的请求参数加入值栈中 stack.setValue(key, newValueStr); } String result = null; try { // 调用下一个拦截器,如果拦截器不存在,则执行Action result = invocation.invoke(); } catch (Exception e) { e.printStackTrace(); } /* Map<String, Object> cacheMap = cache.getMapCache();*/ return result; } /** * 对Value进行过滤 * @param oldValue * @return */ private String replaceString(String oldValue) { System.out.println("----------------"+oldValue); String newValue = oldValue; newValue= StringEscapeUtils.escapeSql(newValue); // 过滤html标签 Matcher mHtml = HTML_PATTERN.matcher(newValue); if (mHtml.find()) { newValue = ""; } // 过滤script脚本 Matcher m = SCRIPT_PATTERN.matcher(newValue); if (m.find()) { newValue = ""; } Matcher sql1 = SQL_PATTERN1.matcher(newValue); if (sql1.find()) { newValue = ""; } Matcher sql2 = SQL_PATTERN2.matcher(newValue); if (sql2.find()) { newValue = ""; } Matcher sql3 = SQL_PATTERN3.matcher(newValue); if (sql3.find()) { newValue = ""; } // <> newValue = newValue.replaceAll("&","&" ); newValue = newValue.replaceAll("<","<"); newValue = newValue.replaceAll(">",">"); newValue = newValue.replaceAll(""","\""); newValue = newValue.replaceAll("<", ""); newValue = newValue.replaceAll(">", ""); // newValue = newValue.replaceAll("ScRipt", ""); newValue = newValue.replaceAll("script", ""); newValue = newValue.replaceAll("WEB-INF", ""); newValue = newValue.replaceAll("../", ""); newValue = newValue.replaceAll("./", ""); newValue = newValue.replaceAll("%20", ""); newValue = newValue.replaceAll(".java", ""); newValue = newValue.replaceAll(".xml", ""); newValue = newValue.replaceAll(".class", ""); newValue = newValue.replaceAll("alert", ""); newValue = newValue.replaceAll("%3E", "");
// sql newValue = newValue.replaceAll("chr[(] ", ""); newValue = newValue.replaceAll("chr [(] ", ""); newValue = newValue.replaceAll("ascii [(] ", ""); newValue = newValue.replaceAll("ascii[(] ", ""); // sql newValue = newValue.replaceAll("create ", ""); newValue = newValue.replaceAll("truncate ", ""); newValue = newValue.replaceAll("drop ", ""); newValue = newValue.replaceAll("insert ", ""); newValue = newValue.replaceAll("delete ", ""); newValue = newValue.replaceAll("select ", ""); newValue = newValue.replaceAll("lock table ", ""); newValue = newValue.replaceAll("update ", ""); System.out.println("----------------"+newValue); return newValue; } /** * й-- * @param key * @return */ private boolean isKeySqlFunctions(String key){ boolean isSqlFunction=false; if(key.contains("drop") || key.contains("insert") || key.contains("update") || key.contains("delete") || key.contains("select") || key.contains("__") ) { isSqlFunction=true; } return isSqlFunction; } /** * URLй-- * @param key * @return */ private boolean isUrlContains(String url){ boolean isUrlContain=false; if(url.contains("reservation/hos_showReservation") || url.contains("reservation/hos_search") ) { isUrlContain=true; } return isUrlContain; }
}
2.struts.xml 配置拦截器
<interceptors> <!-- Action请求拦截过滤--> <interceptor name="illegalCharacter" class="com.just.reserve.common.util.IllegalCharacterInterceptor"/> <!-- 登录拦截过滤--> <interceptor name="checkLogin" class="com.just.reserve.interceptor.LoginInterceptor" /> <interceptor-stack name="myStack"> <interceptor-ref name="defaultStack" /> <interceptor-ref name="illegalCharacter" /> <interceptor-ref name="checkLogin" />
</interceptor-stack> </interceptors>
这里登录拦截 原理和上面的过滤拦截是一样的 |