• Web安全漏洞解决方案


    1.已解密的登录请求

     

    推理: AppScan 识别了不是通过 SSL 发送的登录请求。
    测试请求和响应:

     1.1.1 产生的原因

     登录接口,前端传入的密码参数没有经过md5的加密就直接传给了后端

    1.1.2 解决方法

    前端代码传参的时候做md5加密处理

     

    2.会话标识未更新

    推理: 测试结果似乎指示存在脆弱性,因为“原始请求”和“响应”中的会话标识相同。这些标志应该已在响
    应中更新。
    测试请求和响应:

     

    2.1.2 产生原因

    会话标识未更新漏洞,在用户进入登录页面,但还未登录时,就已经产生了一个session,用户输入信息,登录以后,session的id不会改变,也就是说没有建立新session,原来的session也没有被销毁), 可能会窃取或操纵客户会话和cookie,它们可能用于模仿合法用户,从而使黑客能够以该用户身份查看或变更用户记录以及执行事务。
     
    2.1.3 解决方法
    如果用的是shiro框架,使用 shiro自己提供的api方法 SecurityUtils.getSubject().logout(); 在登录验证时生成新的session

     

     

    3.“Content-Security-Policy”,“X-Content-Type-Options”,“X-Content-Type-Options”头缺失或不安全

     

    推理: AppScan 检测到 Content-Security-Policy 响应头缺失或具有不安全策略,这可能会更大程度地暴露于各种跨站点注入攻击之下
     

     

    推理: AppScan 检测到“X-Content-Type-Options”响应头缺失或具有不安全值,这可能会更大程度地暴露
    于偷渡式下载攻击之下
     

     

    推理: AppScan 检测到 X-XSS-Protection 响应头缺失或具有不安全值,这可能会造成跨站点脚本编制攻击

     

    3.1.1 产生原因

    nginx.conf配置里没有添加对应的请求头

     

    3.1.2 解决方法

    nginx.conf里配置缺失的请求头

     

    4.垂直越权

    4.1.1 漏洞分析

    登录测试账号test并分析下列JS代码:js/app.eb5ecba8.js
    可获取若干隐藏配置菜单:

     

    发现通过访问上述对应menuAction即可实现越权:
     
    4.1.2.风险分析
    攻击者可基于低权限账户获取高权限账户的模块权限。
     
    4.1.3.风险等级
     
    4.1.4.安全建议
    对相关menuAction对应的接口完善鉴权。
     
    4.1.4.问题复现
    1)浏览器打开F12,找到vue.js中配置的一些项目接口的路由
    2)登录低权限test账号,然后在地址栏中直接访问vue.js中的某个路由地址,例如:http://221.***.**.50:58000/#/earlyReport 前提条件是该接口的是test用户不具有访问权限的一个模块中的接口
    3)结果是在浏览器能够直接访问接口所在的页面,并能访问数据
     
    4.1.5.什么是垂直越权
    一般越权漏洞容易出现在权限页面(需要登录的页面)增、删、改、查的的地方,当用户对权限页面内的信息进行这些操作时,后台需要对对当前用户的权限进行校验,看其是否具备操作的权限,从而给出响应,而如果校验的规则过于简单则容易出现越权漏洞 ,简单来说就是低权限用户能访问高权限用户,就是垂直越权
     
    4.1.6.解决方法
    采用AOP,切每个接口,对每个接口做权限校验;自定义一个注解,加在需要控制权限的接口方法上,并且设置这个接口的权限角色。然后通过AOP,切点就是这个自定义注解的方法,前置通知把方法拦截后,先拿到当前登录用户的角色,再拿到自定义注解中该方法的权限角色,根据这些判断当前登录用户有没有权限调用这个接口。如果有权限请求正常继续往下走,如果没有权限抛出异常,代码如下:
     
    自定义注解类:
    复制代码
     1 @Target(ElementType.METHOD)
     2 @Retention(RetentionPolicy.RUNTIME)
     3 public @interface SecurityAuth {
     4 
     5    /**
     6     * 拥有权限的角色名
     7     * @retuen
     8     */
     9    String roleName();
    10 }
    复制代码
    AOP切点类:
    复制代码
     1 @Aspect
     2 @Component
     3 public class SecurityAspect {
     4 
     5     @Autowired
     6     private SysRoleUserService sysRoleUserService;
     7 
     8     /**
     9      * 自定义注解切点
    10      */
    11     @Pointcut("@annotation(com.broadu.modules.filter.SecurityAuth)")
    12     public void annotationAspect(){}
    13 
    14     /**
    15      * 前置通知
    16      */
    17     @Around("annotationAspect()")
    18     public Object doBefore(ProceedingJoinPoint joinPoint) throws Throwable {
    19         // 拿到响应
    20         HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
    21         // 拿到当前登录用户
    22         UserDetail user = SecurityUser.getUser();
    23         if(null == user){
    24             // 未登录
    25             throw new RenException(ErrorCode.ACCOUNT_NOT_EXIST,"该用户不存在");
    26         }
    27         // 从切面织入点处通过反射机制获取织入点处的方法
    28         MethodSignature signature = (MethodSignature) joinPoint.getSignature();
    29         // 获取切入点所在的方法
    30         Method method = signature.getMethod();
    31         // 获取注解
    32         SecurityAuth auth = method.getAnnotation(SecurityAuth.class);
    33         // 获取该方法使用的角色
    34         String roleNames = auth.roleName();
    35         // 获取该用户的角色列表
    36         if(ObjectUtil.notEqual(user.getSuperAdmin(),1)){
    37             List roleList = sysRoleUserService.getRoleNameList(user.getId());
    38             List list = new ArrayList<>();
    39             if(null != roleList && roleList.size() > 0){
    40                 String[] roleName = roleNames.split(",");
    41                 for (String str : roleName) {
    42                     for (String s : roleList){
    43                         if(ObjectUtil.equal(str,s)){
    44                             list.add(s);
    45                             break;
    46                         }
    47                     }
    48                 }
    49                 if(list.size() == 0){
    50                     // 没有权限
    51                     throw new RenException(ErrorCode.ACCOUNT_NOT_PERMISSION,"该用户无权限访问");
    52                 }
    53             }
    54         }
    55         // 有权限
    56         return joinPoint.proceed();
    57     }
    58 
    59 }
    复制代码
    Controller类:
    复制代码
     1 @RestController
     2 @Slf4j
     3 @RequestMapping("/ftpConfiguration")
     4 public class FtpConfigurationController {
     5 
     6     @Autowired
     7     FtpConfigurationService ftpConfigurationService;
     8 
     9     @Autowired
    10     FactorService factorService;
    11 
    12     @SecurityAuth(roleName = "用户角色")
    13     @GetMapping("/page")
    14     @ApiOperation("统计报表")
    15     public Result> page(@ApiIgnore @RequestParam Map params) {
    16         PageData page = ftpConfigurationService.page(params);
    17         List list = page.getList();
    18         // 用户密码md5加密
    19         list.forEach(item ->{
    20             try {
    21                 item.setPassword(DigestUtils.md5Hex(item.getPassword()));
    22             } catch (Exception e) {
    23                 log.info("加密异常信息:{}"+e.getMessage());
    24             }
    25         });
    26         page.setList(list);
    27         return new Result>().ok(page);
    28     }
    复制代码
     
    前端也对代码做了相关的权限校验

     

    静态路由绑定按钮跳转:

     

    4.1.7.验证是否修复成功
    先用不是用户角色的用户登录系统后,然后直接在浏览器地址输入“分页查询用户列表”的url,查看页面上是否有数据返回。如果有,则说明漏洞没修复成功;如果没有,则修复成功。

     

     

  • 相关阅读:
    【Elasticsearch 学习笔记 ES安装及使用】
    Centos7 设置route网关的四种方式
    Win11任务栏太宽了怎么变窄?Win11任务栏宽度调整方法
    asp.net+sqlserver医院体检信息管理系统
    游戏史上五个定价最高的量产型游戏机
    算法通过村第十八关-回溯|白银笔记|经典问题
    Monocular arbitrary moving object discovery and segmentation 论文阅读
    Redis6入门到实战------思维导图+章节目录
    React 入门:组件实例三大属性之refs
    第三百八十六回
  • 原文地址:https://www.cnblogs.com/ctc-kb/p/17648025.html