import java.io.PrintWriter;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONObject;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
/** * md5签名校验 */
private static final long serialVersionUID = -3613423227784326900L;
private static final Log logger = LogFactory.getLog(Md5Interceptor.class);
private static final String MD5_SALT =
@Override
public String intercept(ActionInvocation invocation) throws Exception {
HttpServletRequest request = ServletActionContext.getRequest();
//需要校验且校验失败
if (!check(request, invocation)) {
return checkMd5Failed();
}
return invocation.invoke();
}
/**
* 校验SIGN签名
*/
private boolean check(HttpServletRequest request, ActionInvocation invocation) {
String sign = request.getParameter("lvtukey");
if (StringUtils.isBlank(sign)) {
return false;
}
Map<String, Object> parameterMap = invocation.getInvocationContext().getParameters();
String originSign = getSign(parameterMap);
String expectSign = DigestUtils.md5Hex(originSign + MD5_SALT);
boolean checkResult = sign.equals(expectSign);
if(!checkResult) {
logger.warn("md5签名校验失败,预期的签名->" + expectSign);
}
return checkResult;
}
public static String getSign(Map<String, Object> parameterMap) {
List<String> keys = new ArrayList<String>(parameterMap.keySet());
keys.remove("IS_DEBUG"); //剔除IS_DEBUG、sign两个参数
keys.remove("lvtukey");
Collections.sort(keys); //键值ASCII码递增排序
StringBuilder sb = new StringBuilder();
for (String key : keys) {
Object value = parameterMap.get(key);
if (value == null) {
continue;
}
if (value.getClass().isArray()) {
for (int i = 0; i < Array.getLength(value); i++) {
String item = Array.get(value, i).toString();
sb.append(key).append('=').append(item).append('&');
}
} else if(value instanceof List) {
@SuppressWarnings("unchecked")
List<Object> items = (List<Object>) value;
for (Object item : items) {
sb.append(key).append('=').append(item.toString()).append('&');
}
} else {
String str = value.toString();
sb.append(key).append('=').append(str).append('&');
}
}
if (sb.length() > 0) {
sb.deleteCharAt(sb.length() - 1);
}
return sb.toString();
}
private String checkMd5Failed() {
Map<String, Object> resultMap = new HashMap<String, Object>();
resultMap.put("code", "-1");
resultMap.put("errorMessage", "签名校验失败");
resultMap.put("message", "该版本的第三方登录存在风险,建议升级为驴妈妈最新版本");
sendAjaxResultByJson(resultMap);
return null;
}
/**
* 发送Ajax请求结果json
*/
public void sendAjaxResultByJson(Map<String, Object> resultMap) {
this.getResponse().setContentType("application/json;charset=UTF-8");
this.getResponse().setCharacterEncoding("UTF-8");
try {
PrintWriter out = this.getResponse().getWriter();
JSONObject jsonObj = JSONObject.fromObject(resultMap);
out.write(jsonObj.toString());
out.flush();
out.close();
} catch (Exception e) {
//IGNORE
}
}
private HttpServletResponse getResponse() {
return ServletActionContext.getResponse();
}
}
Returns a set from comma delimted Strings.
com.opensymphony.xwork2.util.TextParseUtil
public void setExcludeMethods(String excludeMethods) {
this.excludeMethods = TextParseUtil.commaDelimitedStringToSet(excludeMethods);
}
package com.lvtu.service.api.rop.intercept;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;
import com.lvtu.utils.LvtuClientMemCacheConstants;
import com.lvtu.utils.cache.LvtuMemcachedUtil;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
/**
* 类描述:防止sql注入
* 项目名称:client-clutter
* 类名称:PreventSQLInjectInterceptor
* 创建人:ltwangwei
* 创建时间:2015-4-21 下午3:00:12
* 修改人:ltwangwei
* 修改时间:2015-4-21 下午3:00:12
* 修改备注:
* @version
*
*/
public class PreventSQLInjectInterceptor extends AbstractInterceptor {
private static final long serialVersionUID = -4421675513682811750L;
private static final Log logger = LogFactory.getLog(PreventSQLInjectInterceptor.class);
private static final String PATTERN_REGEX = "\\'|exec|execute|insert|select|delete|update|count|drop|\\*|\\%|chr|mid|master|truncate|" +
"char|declare|sitename|net user|xp_cmdshell|;|or|-|\\+|like\\'|exec|execute|insert|create|drop|" +
"table|from|grant|use|group_concat|column_name|" +
"information_schema.columns|table_schema|union|where|select|delete|update|order|by|count|\\*|" +
"chr|mid|master|truncate|char|declare|or|;|-|--|\\+|like|\\//|\\/|\\%|\\#|\\$";//过滤掉的sql关键字,可以手动添加
/**
* 是否需要防sql注入校验默认不需要
*/
private static boolean checkFlag=false;
@Override
public String intercept(ActionInvocation invocation) throws Exception {
//获取md5的counter
long switchStatus = -1l;
try {
switchStatus = LvtuMemcachedUtil.getInstance()
.getCounter(LvtuClientMemCacheConstants.CUSTOMIZE_COUNTER_CONSTANTS.PREVENT_SQLINJECT_INTERCEPTOR_COUNTER.getCacheKey());
//membercache 配置小于 -1 的时候走 检验
if(switchStatus < -1l){
checkFlag=true;
}
} catch (Exception e) {
logger.info("memcached访问出错");
}
if(checkFlag){
try {
String uri = this.getRequest().getRequestURI();
if(StringUtils.isNotBlank(uri) && uri.contains("router")){
@SuppressWarnings("unchecked")
Map<String, Object> paramMap = this.getRequest().getParameterMap();
if(null == paramMap || paramMap.isEmpty()){
return invocation.invoke();
}
for(String key : paramMap.keySet()){
if(StringUtils.isNotBlank(key) && "keyword".equals(key.toLowerCase())){
String str = ((String[])paramMap.get(key))[0];
if(this.sqlValidate(str)){
logger.error("sql注入攻击 param = " + str + ".........................");
Map<String,Object> resultMap = resultMapCreator();
resultMap.put("errorMessage", "关键字中包含敏感信息");
resultMap.put("message", "抱歉,您输入的信息有敏感信息,请您修改后重新输入!");
this.sendAjaxResultByJson(resultMap);
return null;
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
return invocation.invoke();
}
/**
* 构造返回数据(返回-1)
* @return
*/
public Map<String,Object> resultMapCreator(){
Map<String,Object> map = new HashMap<String,Object>();
map.put("code","-1");
return map;
}
/**
* 发送Ajax请求结果json
*
* @throws ServletException
* @throws IOException
*/
public void sendAjaxResultByJson(Map<String,Object> resultMap) {
this.getResponse().setContentType("application/json;charset=UTF-8");
this.getResponse().setCharacterEncoding("UTF-8");
try {
PrintWriter out = this.getResponse().getWriter();
JSONObject jsonObj = JSONObject.fromObject(resultMap);
out.write(jsonObj.toString());
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 是否输入sql注入验证
* @param name
* @param @return 设定文件
* @return String DOM对象
* @Exception 异常对象
* @since CodingExample Ver(编码范例查看) 1.1
*/
private boolean sqlValidate(String str){
str = str.replaceAll(" ", "").toLowerCase();//统一转为小写
Pattern p = Pattern.compile(PATTERN_REGEX);
Matcher m = p.matcher(str); // 获取 matcher 对象
return m.find();
}
/**
* 获取HttpRequest
*
* @return
*/
private HttpServletRequest getRequest() {
return ServletActionContext.getRequest();
}
private HttpServletResponse getResponse() {
return ServletActionContext.getResponse();
}
/**
* @param args
*/
public static void main(String[] args) {
String regex = "\\'|exec|execute|insert|select|delete|update|count|drop|\\*|\\%|chr|mid|master|truncate|" +
"char|declare|sitename|net user|xp_cmdshell|;|or|-|\\+|like\\'|exec|execute|insert|create|drop|" +
"table|from|grant|use|group_concat|column_name|" +
"information_schema.columns|table_schema|union|where|select|delete|update|order|by|count|\\*|" +
"chr|mid|master|truncate|char|declare|or|;|-|--|\\+|like|\\//|\\/|\\%|\\#|\\$";//过滤掉的sql关键字,可以手动添加
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher("where1=1"); // 获取 matcher 对象
System.out.println(m.find());
}
}