【EasyPan】项目常见问题解答(自用&持续更新中…)汇总版
一、loadDataList
方法概览
@RequestMapping ( "/loadFileList" )
@GlobalInterceptor ( checkParams = true , checkLogin = false )
public ResponseVO loadDataList ( HttpSession session, @VerifyParam ( required = true ) String shareId, String filePid) { SessionShareDto shareSessionDto = checkShare ( session, shareId) ; FileInfoQuery query = new FileInfoQuery ( ) ; if ( ! StringTools . isEmpty ( filePid) && ! Constants . ZERO_STR. equals ( filePid) ) { fileInfoService. checkRootFilePid ( shareSessionDto. getFileId ( ) , shareSessionDto. getShareUserId ( ) , filePid ) ; query. setFilePid ( filePid) ; } else { query. setFileId ( shareSessionDto. getFileId ( ) ) ; } query. setUserId ( shareSessionDto. getShareUserId ( ) ) ; query. setOrderBy ( "last_update_time desc" ) ; query. setDelFlag ( FileDelFlagEnums . USING. getFlag ( ) ) ; PaginationResultVO result = fileInfoService. findListByPage ( query) ; return getSuccessResponseVO ( convert2PaginationVO ( result, FileInfoVO . class ) ) ;
}
二、checkRootFilePid
方法深度分析
@Override
public void checkRootFilePid ( String rootFilePid, String userId, String fileId) { if ( StringTools . isEmpty ( fileId) ) { throw new BusinessException ( ResponseCodeEnum . CODE_600) ; } if ( rootFilePid. equals ( fileId) ) { return ; } checkFilePid ( rootFilePid, fileId, userId) ;
}
核心安全校验逻辑(递归实现)
private void checkFilePid ( String rootFilePid, String fileId, String userId) { FileInfo fileInfo = this . fileInfoMapper. selectByFileIdAndUserId ( fileId, userId) ; if ( fileInfo == null ) { throw new BusinessException ( ResponseCodeEnum . CODE_600) ; } if ( Constants . ZERO_STR. equals ( fileInfo. getFilePid ( ) ) ) { throw new BusinessException ( ResponseCodeEnum . CODE_600) ; } if ( fileInfo. getFilePath ( ) . equals ( rootFilePid) ) { return ; } checkFilePid ( rootFilePid, fileInfo. getFilePid ( ) , userId) ;
}
三、安全防护矩阵
攻击类型 防御措施 对应代码位置 路径遍历 递归验证父目录归属 checkFilePid
递归调用越权访问 用户ID+文件ID双重验证 selectByFileIdAndUserId
恶意参数 空值检查和根目录特殊处理 首个if
判断块 共享根目录 显式拦截根目录分享场景 ZERO_STR.equals
检查
分层防御机制
防御层级 检查点 拦截场景 典型攻击示例 L1 空值检查 空参数攻击 fileId=null
L2 快速路径匹配 直接访问分享根目录 正常访问分享链接 L3 数据库存在性检查 伪造文件ID fileId=123456
(不存在ID)L4 用户归属验证 越权访问其他用户文件 修改userId参数 L5 根目录保护 尝试分享整个网盘 filePid=0
L6 路径匹配验证 目录跳转攻击 ../../../etc/passwd
L7 递归父目录验证 深层嵌套越权 多级目录伪造
四、方法调用关系
loadDataList├─ checkShare (验证分享有效性)└─ checkRootFilePid├─ 直接返回 (当fileId=rootFilePid)└─ checkFilePid (递归验证)├─ 数据库查询验证├─ 根目录拦截└─ 递归向上验证
五、典型异常处理流程
1. 客户端请求: /loadFileList?shareId=abc&filePid=xyz
2. 服务端校验:- checkRootFilePid("root123", "user1", "xyz")→ 触发checkFilePid递归→ 第三次递归发现filePid="hij"不存在
3. 异常抛出:BusinessException(code=600, msg="参数错误",debugMsg="文件hij不存在或不属于用户user1")
4. 全局异常处理器转换为:{code:600, info:"参数错误", status:"error"}