越权漏洞之测试与修复
字数 943 2025-08-15 21:31:03
越权漏洞测试与修复指南
一、越权漏洞定义及分类
1. 未授权访问
- 定义:用户无需登录或认证即可访问需要权限的功能模块
- 特征:系统未对访问请求进行身份验证检查
2. 水平越权
- 定义:同等权限用户之间可以互相访问或操作对方的数据
- 特征:系统仅验证了用户身份但未验证数据归属关系
- 常见场景:订单管理、个人信息查看/修改等
3. 垂直越权
- 定义:低权限用户获取或执行高权限用户的功能
- 特征:系统未严格区分不同角色权限级别
- 常见场景:普通用户访问管理员功能
二、越权漏洞测试方法
1. 未授权访问测试
- 直接访问法:不登录直接访问需权限的功能URL
- 返回包修改法:
- 修改响应包中的状态参数(如status=false改为true)
- 删除页面跳转的JavaScript代码
- Cookie伪造法:修改或添加userid等标识用户的cookie值
2. 水平越权测试
- ID遍历测试:使用Burp Suite的Intruder模块对有序ID进行遍历
- 常见可遍历ID:
- 用户ID(如1001,1002...)
- 订单号(如20200520xxxx1,20200520xxxx2)
- 其他业务单据编号
3. 垂直越权测试
- 权限标识修改:如修改cookie中的isadmin=0为1
- 路径遍历测试:
http://www.xxxx.com/admin http://www.xxxx.com/admin.do%23 http://www.xxxx.com/js/../admin/admin.do http://www.xxxx.com/admin/./admin.do
三、越权漏洞修复方案
1. 权限校验整体流程
- 清洗URL并提取API接口名称
- 从session获取当前用户ID
- 获取用户角色ID
- 检查垂直越权(角色权限)
- 检查水平越权(数据归属)
2. 关键代码实现
获取API名称
public static String GetApiName(String Url) throws Exception {
String DecodeUrl = URLDecoder.decode(Url,"UTF-8");
URL url = new URL(DecodeUrl);
String ApiUrl = url.getPath();
if(ApiUrl !=null){
String[] ApiPath = ApiUrl.split("/");
String ApiName = ApiPath[ApiPath.length-1];
return ApiName;
}
return null;
}
获取用户角色ID
public static int GetRoleId(int UserId) {
Connection conn = Connect();
PreparedStatement st = null;
ResultSet rs = null;
int RoleId = 0;
try {
String sql = "select roleid from usertable where userid = ?";
st = conn.prepareStatement(sql);
st.setInt(1, UserId);
rs = st.executeQuery();
if(rs.next()){
RoleId = rs.getInt("roleid");
return RoleId;
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("查询失败!");
}
return RoleId;
}
垂直越权检查
public static boolean CheckUpPrivilege(int UserId, String Api_Name) {
Connection conn = Connect();
PreparedStatement st = null;
ResultSet rs = null;
int U_RoleId = GetRoleId(UserId);
int A_RoleId = 0;
try {
String sql = "select roleid from user_role where apiname = ?";
st = conn.prepareStatement(sql);
st.setString(1, Api_Name);
rs = st.executeQuery();
if(rs.next()) {
A_RoleId = rs.getInt("roleid");
if (U_RoleId >= A_RoleId) {
return true;
} else {
return false;
}
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("查询失败!");
}
return false;
}
水平越权检查
public static boolean CheckLevelPrivilege(int S_UserId, int P_UserId) {
if(S_UserId == P_UserId){
return true;
} else{
return false;
}
}
3. 其他防护措施
- 敏感ID处理:使用无规律ID(如UUID或哈希算法生成)
- 防重放攻击:请求中添加token参数
- Session管理:用户标识应从session获取而非cookie
- 数据库设计:
- 权限表应明确API与角色的对应关系
- 业务表应记录数据创建者/所有者
四、最佳实践建议
- 实施全局权限校验过滤器
- 所有API接口明确定义所需权限级别
- 所有业务数据记录所有者信息
- 避免使用可预测的有序ID
- 关键操作添加防重放机制
- 定期进行权限系统安全审计
通过以上措施,可有效防范各类越权漏洞,构建更安全的系统权限体系。