问题一:存储型XSS
注意: 过滤器对奇安信XSS扫描无效
解决方式:
1,设置HttpOnly属性. 在接口中添加下面的代码.
response.setHeader("Set-Cookie", "cookiename=cookievalue;path=/;Domain=domainvalue;Max-age=seconds;HttpOnly");
2,对返回值信息进行特殊字符处理.
参考博客: https://blog.csdn.net/hwb33333/article/details/130976290
public static AccessTokenResultBody success(Object data) {
AccessTokenResultBody result = new AccessTokenResultBody();
result.setResultCode(ResultEnum.SUCCESS);
//处理XSS漏洞 博客:
String jsonData = JSON.toJSONString(data, SerializerFeature.WriteMapNullValue);
result.setAccess_token(JSON.parseObject(StringEscapeUtils.unescapeJson(jsonData),
(Type) data.getClass().getDeclaringClass(), Feature.OrderedField));
return result;
}
## 问题二:代码注入-HTTP响应截断
示例:
```bash
@Value(“${h5.header.X-EOS-SourceSysKey}”)
private String sourceSysKey;
headers.add(“X-EOS-SourceSysKey”,sourceSysKey);
解决办法: 这个参数值不要写在配置文件中,而是直接写到代码里.
注:生产环境中我们未做处理,需要在系统中标注为误报。
headers.add("X-EOS-SourceSysKey","xxxxxxxxxxxx");
问题三:系统信息泄露-外部
示例:
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add("Accept", MediaType.ALL_VALUE);
//注意:上线时需要修改成正式环境的
headers.add("X-EOS-ApiSubscriptionKey","xxxxxxx");
headers.add("X-EOS-SourceSysKey","xxxxxxx");
UserContactDetail userContactDetail = new RestTemplate()
.exchange(getPhone + "/oa-usermanager/userContactDetail/" + userId,
HttpMethod.GET,
new HttpEntity<String>(headers),
UserContactDetail.class
).getBody();
解决办法: 同” 代码注入-HTTP响应截断”,将header的值直接写在代码中.
注:生产中未处理
问题四:API误用-不安全的框架绑定
问题原因: 使用@RequestBody有安全漏洞问题
解决办法: 不用@RequestBody,使用@RequestParam
@PostMapping(value = "/getAccessToken")
public AccessTokenResultBody getAccessToken(@RequestParam("appId") String appId,@RequestParam("secret") String secret,HttpServletResponse response) {
log.info("认证中心获取access_token接口调用");
setCookie(response);
return authService.getAccessToken(new AccessTokenVo(appId,secret));
}
问题五:直接绑定敏感字段
问题描述: AccessToken实体类中的secret遇到这个问题.
解决办法:
同” API误用-不安全的框架绑定”,不用@RequestBody,使用@RequestParam
解决办法二:将getAccessToken接口的请求方式由POST改成GET后解决了.
问题六:密码管理-配置文件中的明文密码
参考博客: https://www.yii666.com/blog/402410.html
示例:
redis:
host: xx.xx.xx.xxx
port: 6379
password: xxxx
解决办法:使用jasypt对密码进行加密。
redis:
host: xx.xx.xx.xxx
port: 6379
password: ENC(ffavyblfrKc8OhFdi/HTLQtVbK95QhFY)
问题:jasypt的加密密码放在配置文件中还是会报这个错误.
解决办法:将jasypt加密工具类的密码当做系统属性.
注意:生产中把jasypt加密工具类的密码放在了nacos上
java -Djasypt.encryptor.password=password -jar jasypt-spring-boot-demo.jar
问题七:资源管理-数据库访问控制
注:生产环境中我们未做处理,需要在系统中标注为误报。
1,
redisTemplate.delete(key);
解决办法:不要使用delete,改成用expire;
2,
redisTemplate.opsForValue().get(key);
redisTemplate.opsForValue().set(key,value);
解决办法:
对涉及到的key/value使用md5加密.(base64加/解密无效);
3,
//1,校验appId和secret
Map<String,Object> params = new HashMap<>();
params.put("appId", accessTokenVo.getAppId());
params.put("secret",accessTokenVo.getSecret());
List<MicroAppEntity> appList = microAppMapper.selectMicroAppList(params);
解决办法: 先查询出列表的所有值,然后循环跟appId和secret进行比较
//1,校验appId和secret
List<MicroAppEntity> appList = microAppMapper.selectMicroAppList();
int count = 0;
for(MicroAppEntity entity : appList) {
if(entity.getMicroAppId().equals(accessTokenVo.getAppId()) && entity.getSubscriptionKey().equals(accessTokenVo.getSecret())) {
count = 1;
break;
}
}