系统很多Url地址都暴露给用户,存在安全隐患,用户可以去随意修改Url地址和参数值,为了解决这个问题提供以下解决方案,具体步骤如下:
第一步:编码URL地址,调用CommonMethod.js的rewriteUrl方法,对Url地址进行Base64编码。
例如:
var url = basePath + "/testAction.do?ExeMethod=query&a=中国&b=2&c=3";
url = rewriteUrl(url); //Base64转码
转码前:
http://localhost:9080/demo/testAction.do?ExeMethod=query&a=中国&b=2&c=3
转码后:
http://localhost:9080/demo/dGVzdEFjdGlvbg==_ZG8=_RXhlTWV0aG9kPXF1ZXJ5JmE95Lit5Zu9JmI9MiZjPTM=.shtml
rewriteUrl方法JS代码:
/**
* 重写Url地址
* @param url
*/
function rewriteUrl(url){
var urlStr = "";
if(typeof(enableUrlEncrypt) != "undefined" && enableUrlEncrypt && enableUrlEncrypt != null && enableUrlEncrypt === "1"){
var queryStr = "";
var index = url.indexOf("?");
if(index != -1){
urlStr = url.substring(0, index);
queryStr = url.substring(index + 1);
}else{
urlStr = url;
}
$.base64.utf8encode = true;
index = urlStr.indexOf(".");
var suffix = urlStr.substring(index + 1);
if(index != -1 && suffix.toLowerCase() != "html"){
var idx = urlStr.lastIndexOf("/");
var prefix = "";
if(idx != -1 && idx < index){
prefix = urlStr.substring(idx + 1, index);
urlStr = urlStr.substring(0, idx);
}else{
urlStr = urlStr.substring(0, index);
}
if(prefix != ""){
urlStr += "/" + $.base64.btoa(prefix).replace(/\//g, ':');
}
if(queryStr != ""){
queryStr = encodeURI(queryStr);
queryStr = $.base64.btoa(suffix) + "_" + $.base64.btoa(queryStr);
queryStr = queryStr.replace(/\//g, ':');
}else{
queryStr = $.base64.btoa(suffix);
queryStr = queryStr.replace(/\//g, ':');
}
urlStr = urlStr + "_" + queryStr + ".shtml";
}
queryStr = null;
}else{
urlStr = url;
}
return urlStr;
}
第二步:解码URL地址并跳转,创建一个过滤器XssFilter,具体如下:
web.xml文件中增加过滤器配置:
XssFilter
com.spsoft.eintmgr.servlet.XssFilter
XssFilter
/*
过滤器代码:
public class XssFilter implements Filter{
private static String[] openUrls = null; //跳过xss过滤的uri地址
public void destroy() {}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)request;
String uri = req.getRequestURI();
int stIndex = uri.lastIndexOf("/");
int edIndex = uri.indexOf(".shtml");
String url = uri;
if(stIndex != -1 && edIndex != -1 && stIndex < edIndex){
String temp = uri.substring(stIndex + 1, edIndex);
String tempArr[] = temp.split("_");
String prefix = new String(Base64.decodeBase64(tempArr[0].getBytes()));
if(tempArr.length == 2){
temp = new String(Base64.decodeBase64(tempArr[1].getBytes()));
}else if(tempArr.length > 2){
temp = new String(Base64.decodeBase64(tempArr[1].getBytes()));
temp += "?" + new String(Base64.decodeBase64(tempArr[2].getBytes("GBK")), "UTF8");
}else{
temp = "";
}
url = uri.substring(0, stIndex) + "/" + prefix + "." + temp;
int index = uri.indexOf("?");
if(index != -1){
uri = url.substring(0, index);
}else{
uri = url;
}
}
int index = url.lastIndexOf("/");
if(index != -1 && index < url.length()){
url = url.substring(index + 1);
}
if(null != openUrls && openUrls.length > 0){
for(int i = 0; i < openUrls.length; i++){
if(uri.indexOf(openUrls[i]) != -1){ //包含跳过xss过滤的url地址,就不过滤
req.getRequestDispatcher(url).forward(req, response);
return;
}
}
}
req.getRequestDispatcher(url).forward(new RequestWrapper(req), response);
}
public void init(FilterConfig filterConfig) throws ServletException {}
}
第三步:跳转后可以获取各参数的值,例如:
@Controller
@RequestMapping("/testAction.do")
public class TestAction extends BasicAction {
@RequestMapping(params = "ExeMethod=query")
public String query(Model model, HttpServletRequest request, HttpServletResponse response) {
System.out.println("-->a:"+ request.getParameter("a"));
System.out.println("-->b:"+ request.getParameter("b"));
System.out.println("-->c:"+ request.getParameter("c"));
return "index";
}
}
打印结果:
16:13:17,415 INFO [STDOUT] -->a:中国
16:13:17,416 INFO [STDOUT] -->b:2
16:13:17,416 INFO [STDOUT] -->c:3