Access Control: Database(数据库访问控制)最新解析及完整解决方案
知识库:Access Control: Database(数据库访问控制)
规则描述
数据库访问控制是指程序未进行恰当的访问控制,执行了一个包含用户控制主键的SQL语句,由于服务器端对客户提出的数据操作请求过分信任,忽略了对该用户操作权限的判定,导致修改相关参数就可以拥有了其他账户的增、删、查、改功能。如果在一个应用中,用户能够访问他本身无权访问的功能或者资源,就说明该应用存在访问控制缺陷,也就存在越权漏洞。详见CWE ID566: Authorization Bypass Through User-Controlled SQL Primary Key (http://cwe.mitre.org/data/definitions/566.html)。
漏洞危害
数据库访问控制是利用用户引入的参数生成由用户控制主键的 SQL 语句,令攻击者可以访问到同级别用户的资源或者访问更高级别用户的资源,会导致任意用户敏感信息泄露、用户信息被恶意修改或删除。数据库访问控制类似于数据库越权。例如某一页面服务器端响应中返回登录名、登录密码、手机号、身份证等敏感信息,如果存在数据库访问控制,通过对用户 ID 的遍历,就可以查看所有用户的敏感信息,这也是一种变相的脱库,而且很难被防火墙发现,因为这和正常的访问请求没有什么区别,也不会包含特殊字符,具有十足的隐秘性。
整改方案
缺陷代码
上述示例代码31-56行,程序获取用户输入的参数 id,并将传入参数转成 int 类型,然后创建数据库查询,查询 uid 为传入参数 id 的清单数据。显然,程序中未对传入参数做校验及过滤,用户可随意获得任何用户的清单数据。
从跟踪路径中可以分析出数据的污染源以及数据流向,在代码行第53行报出缺陷。
修复代码:
在上述修复代码中,在第34行从 session 中直接获取到 id 的值构造查询语句,获得当前用户的清单数据,避免用户操控SQL语句的主键值。
- 补充完整的解决方案:
发生构成该漏洞的两个必要条件:
1、来自用户或前端参数参与了后台操作数据库语句(数据从一个不可信赖的数据源进入程序)。
2、该参数做数据库表主键使用(这个数据用来指定 SQL 查询中主键的值。)
三种解决方案:
- 可不使用来自用户或前端参数做相关SQL操作(例:读取session里值构建SQL(一般通过session取用户id构建用户清单,但如果产生漏洞的id不为用户id,例:orgid,roleId,店铺id取机构、店铺信息时,则也需要保证该主键来自可信赖的数据源:后端或数据库等地方))
- 该参数不做SQL相关操作的主键使用。(使用一个与主键不一致的副id做相关操作)
例:图1的查询SQL语句
在图2中查询的org_id并未做主键id,而是作为的副id使用
且在图3中核对该主副id不一致
3、参照fortify官方解决方式。
附加了一个限制,以验证清单是否属于当前经过身份验证的用户。
...
userName = ctx.getAuthenticatedUserName();
id = Integer.decode(request.getParameter("invoiceID"));
String query =
"SELECT * FROM invoices WHERE id = ? AND user = ?";
PreparedStatement stmt = conn.prepareStatement(query);
stmt.setInt(1, id);
stmt.setString(2, userName);
ResultSet results = stmt.execute();
...
如上示例代码:加入一个用户名(不推荐使用用户id)的查询限制,匹配用户对该条查询是否有所有权。
上述三种解决方案:
方案1-->限制了构成漏洞的条件1;
方案2-->限制了构成漏洞的条件2;
方案3-->限制了操作越权的可能。
- 分享WordPress显示评论者IP的归属地及运营商信息的2种方案
- 解决dos2unix/unix2dos报错,并在家目录下生成u2dtmp*文件问题
- 【前沿】TensorFlow Pytorch Keras代码实现深度学习大神Hinton NIPS2017 Capsule论文
- Nginx通过二级目录(路径)映射不同的反向代理,规避IP+端口访问
- MySQL中批量初始化数据的对比测试(r12笔记第71天)
- Golang语言--包的概念、导入与可见性
- MySQL中的change,modify和自增列的关系(r12笔记第70天)
- Golang 值得注意的地方
- MySQL数值类型在binlog中需要注意的细节(r12笔记第69天)
- WordPress评论滑动/拉链解锁myQaptcha修改为自动提交的方法
- MySQL root用户登录的几个小问题(r12笔记第67天)
- Java实现生产者消费者的两种方式(r12笔记第66天)
- Golang语言的函数调用信息
- mysqldump的一点使用总结(r12笔记第81天)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法