/**
* @description 对HttpServletRequest 请求的数据进行转义,防止xss攻击
* URL: home.html?mothod=space&pid=335511
*/
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
private byte[] body;
public XssHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
String method = request.getMethod();
String pathInfo = request.getPathInfo();
String contentType = request.getContentType();
// 由于request并没有提供现成的获取json字符串的方法,所以我们需要将body中的流转为字符串
BufferedReader reader = request.getReader();
StringBuilder stringBuilder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
String json = stringBuilder.toString();
if ((HttpMethod.POST.equalsIgnoreCase(method) ||
HttpMethod.PUT.equalsIgnoreCase(method)) && StrUtil.isNotEmpty(contentType) && contentType.contains(
MediaType.APPLICATION_JSON_VALUE)) {
json = HtmlUtil.cleanHtmlTag(json);
json = json.replaceAll("iframe.*iframe","").replaceAll("javascript.*\\)","").replaceAll("alert","");
body = json.getBytes();
}
}
/**
* 重写getParameter方法,用HtmlUtil转义后再返回
*/
@Override
public String getParameter(String name) {
String value= super.getParameter(name);
if(!StrUtil.hasEmpty(value)){
// value= HtmlUtil.filter(value);
value = value.replaceAll("<iframe.*iframe>","").replaceAll("iframe.*iframe","").replaceAll("javascript.*\\)","").replaceAll("alert","");
}
return value;
}
public static void main(String[] args) {
String address = "<p>fegreef<iframe+src=javascript:&#37;&#53;&8#67;&#117;&#48;&#48;&8#54;&#49;&#37;&#53;&#67;&#117;&#48;&#48;&#54;&#67;&#378&#53;&#67;&#117;&#48;&#48;&#54;&#53;&#37;&#53;&#67;&#11F;&8#48;&#48;&#55;&#50;&#37;&#53;&#67;&#117;&#48;&#48;&#55;&#52;(88888)>&1t;/iframe>e</p>alert909090></p>";
String b = "<iframe src=//a.com></iframe>";
System.out.println(b.replaceAll("iframe.*iframe","").replaceAll("javascript.*\\)","").replaceAll("alert.*",""));
}
/**
* 重写getParameterValues方法,
* 遍历每一个值,用HtmlUtil转义后再返回
*/
@Override
public String[] getParameterValues(String name) {
String[] values= super.getParameterValues(name);
if(values!=null){
for (int i=0;i<values.length;i++){
String value=values[i];
if(!StrUtil.hasEmpty(value)){
// value= HtmlUtil.filter(value);
value = value.replaceAll("<iframe.*iframe>","").replaceAll("iframe.*iframe","").replaceAll("javascript.*\\)","").replaceAll("alert","");
}
values[i]=value;
}
}
return values;
}
/**
* 重写getParameterMap方法,
* 拿到所有的k-v键值对,用LinkedHashMap接收,
* key不变,value用HtmlUtil转义后再返回
*/
@Override
public Map<String, String[]> getParameterMap() {
Map<String, String[]> parameters = super.getParameterMap();
LinkedHashMap<String, String[]> map=new LinkedHashMap();
if(parameters!=null){
for (String key:parameters.keySet()){
String[] values=parameters.get(key);
for (int i = 0; i < values.length; i++) {
String value = values[i];
if (!StrUtil.hasEmpty(value)) {
// value = HtmlUtil.filter(value);
value = value.replaceAll("<iframe.*iframe>","").replaceAll("iframe.*iframe","").replaceAll("javascript.*\\)","").replaceAll("alert","");
}
values[i] = value;
}
map.put(key,values);
}
}
return map;
}
/**
* 重写getHeader方法,用HtmlUtil转义后再返回
*/
@Override
public String getHeader(String name) {
String value= super.getHeader(name);
if (!StrUtil.hasEmpty(value)) {
value = HtmlUtil.filter(value);
}
return value;
}
@Override
public ServletInputStream getInputStream(){
if (body != null && body.length > 0) {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body);
//匿名内部类,只需要重写read方法,把转义后的值,创建成ServletInputStream对象
return new ServletInputStream() {
@Override
public boolean isFinished() {
return byteArrayInputStream.available() == 0;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() throws IOException {
return byteArrayInputStream.read();
}
};
} else {
try {
return super.getInputStream();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
@Override
public BufferedReader getReader(){
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
}