Commit 869793d3 authored by zengtianlai3's avatar zengtianlai3

测试存储型XSS是否解决

parent 905a535b
...@@ -104,9 +104,6 @@ public class OperateController { ...@@ -104,9 +104,6 @@ public class OperateController {
String user = UserUtils.getLoginUserId(); String user = UserUtils.getLoginUserId();
int userI = Integer.valueOf(user); int userI = Integer.valueOf(user);
List<AlarmVo> alarmList = alarmService.getAlarmList(userI); List<AlarmVo> alarmList = alarmService.getAlarmList(userI);
for (AlarmVo alarmVo : alarmList) {
alarmVo.setLevelDescribe(ESAPI.encoder().encodeForHTML(alarmVo.getLevelDescribe()));
}
return ResResult.success().goRecord(alarmList); return ResResult.success().goRecord(alarmList);
} }
...@@ -114,9 +111,9 @@ public class OperateController { ...@@ -114,9 +111,9 @@ public class OperateController {
@PostMapping("alarm/read") @PostMapping("alarm/read")
@MyLog(title = "将告警信息状态设为已读", businessType = BusinessType.OTHER) @MyLog(title = "将告警信息状态设为已读", businessType = BusinessType.OTHER)
public BaseResult readAlarm() { public BaseResult readAlarm() {
String id = UserUtils.getLoginUserId(); String i = UserUtils.getLoginUserId();
int userId = Integer.valueOf(id); int uI = Integer.valueOf(i);
boolean res = alarmReadService.readAlarm(userId); boolean res = alarmReadService.readAlarm(uI);
if (res) { if (res) {
return BaseResult.success(); return BaseResult.success();
} else { } else {
......
...@@ -34,4 +34,9 @@ public class Alarm { ...@@ -34,4 +34,9 @@ public class Alarm {
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty("告警创建时间") @ApiModelProperty("告警创建时间")
private Date createTime; private Date createTime;
public Integer getI() {
return this.id;
}
} }
...@@ -8,9 +8,11 @@ import iot.sixiang.license.mapper.AlarmMapper; ...@@ -8,9 +8,11 @@ import iot.sixiang.license.mapper.AlarmMapper;
import iot.sixiang.license.mapper.AlarmReadMapper; import iot.sixiang.license.mapper.AlarmReadMapper;
import iot.sixiang.license.model.vo.AlarmVo; import iot.sixiang.license.model.vo.AlarmVo;
import iot.sixiang.license.service.AlarmReadService; import iot.sixiang.license.service.AlarmReadService;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List; import java.util.List;
/** /**
...@@ -29,15 +31,17 @@ public class AlarmReadServiceImpl extends ServiceImpl<AlarmReadMapper, AlarmRead ...@@ -29,15 +31,17 @@ public class AlarmReadServiceImpl extends ServiceImpl<AlarmReadMapper, AlarmRead
@Resource @Resource
AlarmReadMapper alarmReadMapper; AlarmReadMapper alarmReadMapper;
@Override @Override
public boolean readAlarm(int userId) { public boolean readAlarm(int userId) {
if (userId == 0) { if (userId == 0) {
throw new IotLicenseException(ResultCode.VALIDATE_FAILED.getCode(),ResultCode.VALIDATE_FAILED.getMsg()); throw new IotLicenseException(ResultCode.VALIDATE_FAILED.getCode(),ResultCode.VALIDATE_FAILED.getMsg());
} }
List<AlarmVo> alarmList = alarmMapper.getAlarmList(userId); List<AlarmVo> alarmList = alarmMapper.getAlarmList(userId);
for (AlarmVo alarm: alarmList) { for (AlarmVo alarm: alarmList) {
if (alarm.getReadFlag() == 0) { if (alarm.getReadFlag() == 0) {
int alarmId = alarm.getId(); int alarmId = alarm.getI();
int typeId = alarm.getTypeId(); int typeId = alarm.getTypeId();
String title = alarm.getTitle(); String title = alarm.getTitle();
String content = alarm.getContent(); String content = alarm.getContent();
......
package iot.sixiang.license.xss;
import iot.sixiang.license.model.vo.AlarmVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.*;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Statement;
import java.util.*;
/**
* @Author m33
* @Date 2022/7/15 19:52
* @Description: 对mybaits返回的结果集进行拦截,再做防XSS攻击处理 此处仅根据Mapper接口的返回类型做处理,其他未处理类型需要自行拓展
*/
@Slf4j
@Component
@Intercepts({@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})})
public class ResultSetInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
//取出查询的结果
final Object resultObject = invocation.proceed();
if (Objects.isNull(resultObject)) {
return resultObject;
}
//针对ArrayList进行过滤
if (resultObject instanceof ArrayList) {
ArrayList resultList = (ArrayList) resultObject;
if (CollectionUtils.isEmpty(resultList)) {
return resultList;
}
//遍历List里面所有对象
resultList.stream().forEach(value -> {
Field[] fields = value.getClass().getDeclaredFields();
Class<?> clazz = value.getClass();
Field[] field = null;
// for (; clazz != Object.class; clazz = clazz.getSuperclass()) {//向上循环 遍历父类
// field = clazz.getDeclaredFields();
// for (Field f : field) {
// f.setAccessible(true);
// try {
// System.out.println("属性:"+f.getName()+" 值:"+f.get(value).toString());
// } catch (IllegalAccessException e) {
// e.printStackTrace();
// }
//
// }
// }
// System.out.println(field);
//定义一个HashMap存取当前遍历的Map的k-v值
HashMap<String, Object> store = new HashMap<>();
//
// if (value instanceof AlarmVo) {
// System.out.println("=========================");
// for (Field field1 : fields) {
// try {
// System.out.println(field1.get(value).toString());
// } catch (IllegalAccessException e) {
// e.printStackTrace();
// }
// }
// System.out.println("=========================");
// }
//如果是List<Map> 则value为Map
if (value instanceof HashMap) {
System.out.println("Map ==>" + value);
//遍历Map的所有属性
Arrays.stream(fields).forEach(v1 -> {
//开启属性访问
v1.setAccessible(true);
try {
//声明一个java.util.HashMap$Node的Class 用于获取Node的key,value,next的值
Class clsHashMap$Node = Class.forName("java.util.HashMap$Node");
//遍历属性,获取Map的table属性 ,Node[] table
if (v1.getName() == "table") {
Object[] nodes = (Object[]) v1.get(value);
//遍历所有非空节点
for (Object node : nodes) {
if (node != null) {
//节点递归获取节点k-v值存入hashmap中
forEachGetNodeKV(node, clsHashMap$Node, store);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
});
//打印取出来的k-v结果
// for (Map.Entry entry : store.entrySet()) {
// System.out.println("key==>" + entry.getKey() + " value==>" + entry.getValue());
// }
}
//如果是List<String> 则value为String
if (value instanceof String) {
}
});
}
return resultObject;
}
/**
* 节点递归获取节点k-v值存入hashmap中
*
* @param node
* @param clsHashMap$Node
* @param hashMap
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws NoSuchFieldException
* @throws SecurityException
*/
private void forEachGetNodeKV(Object node, Class clsHashMap$Node, HashMap<String, Object> hashMap) throws Exception {
//获取node类里面的key属性
Field f_key = clsHashMap$Node.getDeclaredField("key");
//获取node类里面value属性
Field f_value = clsHashMap$Node.getDeclaredField("value");
//获取node类里面next属性,指向下一个节点
Field f_next = clsHashMap$Node.getDeclaredField("next");
//开启属性的私有属性访问
f_key.setAccessible(true);
f_value.setAccessible(true);
f_next.setAccessible(true);
//获取key,value,next属性的属性值
String key = f_key.get(node).toString();
Object value = f_value.get(node);
Object next = f_next.get(node);
//进行XSS攻击过滤
if (value instanceof String) {
String val = (String) value;
value = XssUtil.stripXSS(val);
//将过滤后的数据放入原节点
Method[] methods = node.getClass().getMethods();
for (Method method : methods) {
if (method.getName().equals("setValue")) {
method.setAccessible(true);
method.invoke(node, value);
}
}
}
//保存当前节点的k-v值
hashMap.put(key, value);
//判断next是否为空,不为空则递归
if (null != next) {
forEachGetNodeKV(next, clsHashMap$Node, hashMap);
}
}
@Override
public Object plugin(Object target) {
// 读取@Signature中的配置,判断是否需要生成代理类
if (target instanceof ResultSetHandler) {
return Plugin.wrap(target, this);
} else {
return target;
}
}
@Override
public void setProperties(Properties properties) {
log.info("setProperties");
}
}
...@@ -56,7 +56,7 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { ...@@ -56,7 +56,7 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
if (isMultipartContent || isMultipart) { if (isMultipartContent || isMultipart) {
fileUpload = true; fileUpload = true;
} }
try (BufferedReader isr = new BufferedReader(new InputStreamReader(ins, StandardCharsets.UTF_8));) { try (BufferedReader isr = new BufferedReader(new InputStreamReader(ins, StandardCharsets.UTF_8))) {
String line = ""; String line = "";
while ((line = isr.readLine()) != null) { while ((line = isr.readLine()) != null) {
sb.append(line); sb.append(line);
......
package iot.sixiang.license.xss;
import org.apache.commons.lang3.StringUtils;
import java.util.regex.Pattern;
/**
* @Author m33
* @Date 2022/7/15 20:00
* @Description
*/
public class XssUtil {
private final static Pattern SCRIPT_PATTERN = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
private final static Pattern SRC_PATTERN_ONE = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
private final static Pattern SRC_PATTERN_TWO = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
private final static Pattern SCRIPT_PATTERN_ONE = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);
private final static Pattern SCRIPT_PATTERN_TWO = Pattern.compile("<script(.*?)>",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
private final static Pattern EVAL_PATTERN = Pattern.compile("eval\\((.*?)\\)",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
private final static Pattern EXPRESSION_PATTERN = Pattern.compile("expression\\((.*?)\\)",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
private final static Pattern JAVASCRIPT_PATTERN = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);
private final static Pattern VB_SCRIPT_PATTERN = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);
private final static Pattern ON_LOAD_PATTERN = Pattern.compile("onload(.*?)=",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
private XssUtil() {
}
/**
* 过滤xss
* @param value 值
* @return 过滤置空
*/
public static String stripXSS(String value) {
if (StringUtils.isNotBlank(value)) {
value = SCRIPT_PATTERN.matcher(value).replaceAll("");
value = SRC_PATTERN_ONE.matcher(value).replaceAll("");
value = SRC_PATTERN_TWO.matcher(value).replaceAll("");
value = SCRIPT_PATTERN_ONE.matcher(value).replaceAll("");
value = SCRIPT_PATTERN_TWO.matcher(value).replaceAll("");
value = EVAL_PATTERN.matcher(value).replaceAll("");
value = EXPRESSION_PATTERN.matcher(value).replaceAll("");
value = JAVASCRIPT_PATTERN.matcher(value).replaceAll("");
value = VB_SCRIPT_PATTERN.matcher(value).replaceAll("");
value = ON_LOAD_PATTERN.matcher(value).replaceAll("");
}
return value;
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment