是否应该在更改数据库的操作发生之前完成断言或检查?

Posted

技术标签:

【中文标题】是否应该在更改数据库的操作发生之前完成断言或检查?【英文标题】:should asserts or checks be completed before an action takes place to change the database? 【发布时间】:2017-06-08 16:06:02 【问题描述】:

是否应该在读取/写入实际数据之前执行用户对数据库中记录的读取/写入检查?或者可以在同一个查询中应用所有这些吗?

即。

assertUserCanViewClassRoom($clas-s-roomId, $userId, $userRole);
assertUserCanRemoveStudent($clas-s-roomId, $userId, $userRole);

还是应该在action的sql中完成检查?

viewClassRoom($clas-s-roomId, $userId, $userRole);
removeStudent($clas-s-roomId, $userId, $userRole);

我太啰嗦(又名罗嗦)

现在我要修改所有查询,只是为了确保允许执行操作的用户这样做,用户可以访问表 B 中他们可能创建的或他们的角色允许他们执行的读取/更新记录忽略属于较小用户(又名管理员、教师、学生)的记录

目前该过程允许任何用户修改记录(可怕的做法)。老师 A 可以查看老师 B 的信息,并通过在课堂上添加/删除学生来修改它。理想情况下,简单检查一下教师的 id 就可以防止这种行为发生。

我是否应该在访问该记录之前进行检查,以验证 X 老师是否有权在表 B 中记录 id=Y。这听起来不错,但真的如此吗?我做的工作是先检查而不是读/写数据吗?

我认为这将是一个简单的查询语句更改,它根据用户 ID用户角色权限 将表加入 到记录正在修改。

有人建议我做一个听起来不错的预检查,但现在我可能会为数据库增加额外的流量,以完成我认为是简单的读取或写入事务。我将其视为断言或通过 sql 检查以验证用户是否可以执行任务而不是执行它。

这是断言/权限检查的标准做法吗?先检查一下是否有一个简单的更新、插入或删除功能? (请注意,Delete 从未真正使用过)如果不是这种情况,那么更好的建议是什么?

附加信息 系统设置为用户当前可以读取自己的数据,但通过一些简单的修改,用户实际上可以读取任何人的数据。

项目是 phpmysql 后端所有面向对象

【问题讨论】:

【参考方案1】:

如果您很谨慎,请务必先检查,尤其是当您对消毒检查不是很有信心时。

所以,你会做一个简单的

SELECT is_admin FROM users WHERE user = '$userid';

等等。如果 is_admin 为真,则继续执行您的选择/更新/插入脚本。如果没有,拒绝访问。

【讨论】:

这些检查是否应该成为访问所有数据的标准做法?读/写? 这取决于您的读写需要什么级别的安全性。如果您正在向数据库写入一些通用的静态后端输出,那么您不需要这样做。对于阅读,它完全取决于它是否是敏感材料。如果他们应该是管理员用户或具有从这些行中选择的特殊权限,那么是的,请事先检查。但是,对于未经清理的数据,事先检查将无济于事 - 两种方式都可能发生注入。 目前从我上面的帖子来看,安全级别为零。我已经毫不费力地轻松入侵了该网站。我只是认为如果用户 A 可以看到用户 B 的数据而不是对其进行操作,则存在根本性的错误,为什么用户的 id 没有在使用左连接语句的基线查询中使用。 读取也是一样,为什么不检查用户A是否可以在select语句中使用用户id读取这个数据。为什么要执行检查,如果用户被允许,然后去阅读它?感觉像两倍的工作?我知道角色可以使查询复杂化。 如果读取适用于敏感数据,那么是的,您应该始终检查权限。几乎没有任何理由运行昂贵的合并查询来将所有数据返回到一个视图中 - 只需检查后端的权限,然后运行实际查询。

以上是关于是否应该在更改数据库的操作发生之前完成断言或检查?的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式的零宽断言

如何断言显示为字符串的货币值已正确更新

最好在更改约束之前或之后调用 .layoutIfNeeded()

每周必写

原子变量是不是保证 - “发生在关系之前”?

Unittest 框架之断言,你学会了吗??