1.已解密的登錄請求 推理: AppScan 識別了不是通過 SSL 發送的登錄請求。 測試請求和響應: 1.1.1 產生的原因 登錄介面,前端傳入的密碼參數沒有經過md5的加密就直接傳給了後端 1.1.2 解決方法 前端代碼傳參的時候做md5加密處理 2.會話標識未更新 推理: 測試結果似乎指示存 ...
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<String> roleList = sysRoleUserService.getRoleNameList(user.getId()); 38 List<String> 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<PageData<FtpConfigurationDto>> page(@ApiIgnore @RequestParam Map<String, Object> params) { 16 PageData<FtpConfigurationDto> page = ftpConfigurationService.page(params); 17 List<FtpConfigurationDto> 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<PageData<FtpConfigurationDto>>().ok(page); 28 }前端也對代碼做了相關的許可權校驗
靜態路由綁定按鈕跳轉:
4.1.7.驗證是否修複成功 先用不是用戶角色的用戶登錄系統後,然後直接在瀏覽器地址輸入“分頁查詢用戶列表”的url,查看頁面上是否有數據返回。如果有,則說明漏洞沒修複成功;如果沒有,則修複成功。
作者:常曼巴 出處:https://www.cnblogs.com/ctc-kb/ 本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須在文章頁面給出原文連接,否則保留追究法律責任的權利。