业务表单修改实现安全性疑问

小胖
  • 70

现在公司的程序在修改业务表单时碰到了安全性问题,现在分别有人提出三种实现方式。
程序架构:
SpringBoot、SpringMVC、Mybatis等
开发场景:
现有一个用户表,主要字段编号、昵称、余额、赠送余额。用户执行查看并修改个人信息,在页面展示所有字段,但是只允许用户修改昵称,其它字段设置为只读,现在争议发生在后端修改的实现方式。
方案一
通过SrpingMVC接收数据并注入到对象newUser中,然后直接使用MyBatis的updateByPrimaryKey方法执行修改。
代码:userMapper.updateByPrimaryKey(newUser);
发现问题:

  1. 脏数据覆盖,当用户在页面操作时其它模块操作了用户表的数据,此时用户再执行保存会用脏数据覆盖正确数据。

方案二
通过SrpingMVC接收数据并注入到对象newUser中,先通过MyBatis的selectByPrimaryKey查询到原用户对象oldUser,然后将newUser中的昵称赋值给oldUser,最后使用updateByPrimaryKey方法执行修改。
代码:
oldUser.setNickname(newUser.getNickname());
userMapper.updateByPrimaryKey(oldUser);
发现问题:

  1. 并发问题,当其它功能同时修改用户表的其它字段时,会导致修改数据被脏数据覆盖。

方案三
通过SrpingMVC接收数据并注入到对象newUser中,然后调用MyBatis的自定义语句执行修改,只修改用户的昵称。
代码:userMapper.updateNicknameByPrimaryKey(newUser);
sql:update user set nickname=#{nickname} where id=#{id}

求问
求问这三种方案各有什么优劣?哪种方案最安全?

回复
阅读 958
4 个回答
✓ 已被采纳

方案一修改的时候如果没做判断会修改到敏感数据 不可行
方案二、多了一个查询,并且明明是修改昵称,还更新了其他数据,虽然不影响。
方案三,前端直接传递nickname,和id字段即可,不用将所有字段全部暴露出去

方案三最优但是实现麻烦
方案二差一点但是最好实现
方案一要做字段过滤,有遗漏会改到不能改的数据,有风险,不行

如果表维护有最后操作时间,可以将这个时间传到前端,然后保存的时候也传这个值来判断数据库是否更改了。

谢邀,我对 JEE 栈不熟,只能给点建议:

我觉得关键是要解决「只更新需要更新的字段」这个问题,当然方案三。

不过用 MyBatis 就是为了减少 SQL,所以最好能找个方案三的等价 MyBatis 方案。据说 MyBatis-Plus 能解决,可以研究下。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏