Bootstrap

奇安信常见安全漏洞及修复

问题一:存储型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;
    }
}

;