xss漏洞 我看网上有了很多的解释了 ,公司现在要过等保三级,然后发现一堆问题 要求修改。感觉没啥好说的 还是直接上代码吧。
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jl.net.framework.util.JLEncodeUtil;
import com.jl.net.framework.web.JLBodyReaderHttpServletRequestWrapper;
import com.jl.net.framework.web.JLJsonResponse;
public class XssFilter implements Filter {
/**
* 编码集
*
* @param encode
*/
public void setEncode(String encode) {
JLEncodeUtil.setEncode(encode);
}
@Override
public void destroy() {
}
/**
* 过滤器用来过滤的方法
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
StringBuffer requestURL = ((HttpServletRequest) request).getRequestURL();
String queryString = ((HttpServletRequest) request).getQueryString();
System.out.println(((HttpServletRequest) request).getRequestURL().toString());
//这两个 输出语句不要注释 这是因为 java缓存 或者是访问速度过快 可能会导致后面的 filter读取不到数据 导致本地启动不了
String trimToEmpty1 = StringUtils.trimToEmpty(request.getParameter("j_username"));
System.out.println(trimToEmpty1);
if(isSpecialChar(queryString)) {
response.setCharacterEncoding("GBK");
HttpServletResponse resp = (HttpServletResponse) response;
String json = "很抱歉,由于您访问的URL有可能对网站造成安全威胁,您的访问被阻断。";
resp.getWriter().write(json);
return;
}
MyHttpServletRequestWrapper req = null;
// if(!requestURL.toString().contains("login.jsp")) {
req = new MyHttpServletRequestWrapper((HttpServletRequest) request);
String bodyString = req.getBodyString();
System.out.println(bodyString);
if(!StringUtils.isBlank(bodyString)) {
//这两个 输出语句不要注释 这是因为 java缓存 或者是访问速度过快 可能会导致后面的 filter读取不到数据 导致本地启动不了
String trimToEmpty = StringUtils.trimToEmpty(request.getParameter("j_username"));
System.out.println(trimToEmpty);
try {
Map<String,Object> params = JSON.parseObject(bodyString, Map.class);
Set<String> keySet = params.keySet();
for (String param : keySet) {
if(isSpecialChar(String.valueOf(params.get(param)))) {
response.setCharacterEncoding(JLEncodeUtil.getEncode());
returnError(response,param+String.valueOf(params.get(param)).replace("<", "《"));
return;
}
}
} catch (Exception e) {
if(isSpecialChar(bodyString)) {
response.setCharacterEncoding(JLEncodeUtil.getEncode());
returnError(response,bodyString);
return;
}
}
}
// }
// 包装request
chain.doFilter(req != null ? req :request, response);
// chain.doFilter(request, response);
}
private void returnError(ServletResponse response,String parma) throws IOException {
HttpServletResponse resp = (HttpServletResponse) response;
JLJsonResponse jsonResponse = new JLJsonResponse(true);
jsonResponse.setSuccess(false);
if(parma.length() > 20) {
parma = parma.substring(0, 20);
}
jsonResponse.setMessage("很抱歉,由于您访问的URL有可能对网站造成安全威胁,您的访问被阻断。");
Object jsonObj = JSONObject.toJSON(jsonResponse);
String json = JSONObject.toJSONString(jsonObj);
// JLEncodeUtil.setEncode("GBK");
resp.getWriter().write(json);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
public static boolean isSpecialChar(String str) {
if(str == null) {
return false;
}
// String regEx = "[`~!#$^|';'<>~#……]|\n|\r|\t";
String regEx = "$';'|script|alert";
// String regEx = "[ `~!@#$%^&*()+=|{}';',\\[\\]<>?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]|\n|\r|\t";
// String regEx = "[ _`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]|\n|\r|\t";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(str.toLowerCase());
return m.find();
}
}
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.springframework.util.StreamUtils;
public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper {
private final byte[] body;
private String bodyString;
public MyHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
this.bodyString = StreamUtils.copyToString(request.getInputStream(), Charset.forName("UTF-8"));
body = bodyString.getBytes("UTF-8");
}
public String getBodyString() {
return this.bodyString;
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream bais = new ByteArrayInputStream(body);
return new ServletInputStream() {
@Override
public int read() throws IOException {
return bais.read();
}
};
}
}
这种的应该是没有什么问题的,两个fillter做数据流解析,然后判断 敏感字符,这就根据项目自行判断吧,我这和其他不一样的地方是:我们这边 body的数据也要我判断,我看网上的例子 都是只对地址栏的参数 做校验,但是公司的项目比较老师和庞大,只能我吧所有的参数进行校验。蓝瘦
有意者自取吧。
如果有问题的话可以评论区沟通,但是在下比较菜 不负责一定解决(手动狗头)