公司新招的实习生犯大错误了!!!

简介: 某天中午,公司的产品出现了问题,有人汇报说所有用户都变成了管理员,并且可以享受管理员的权限。然后员工小 A 大叫:“我 X,是我今天执行单元测试更新数据的时候,少加了个 where 条件!本来的预期:update user set userRole = 'admin' where id = 1实际上执行:update user set userRole = 'admin'于是导致整个库里的所有用户都变成了管理员,并且可以享受管理员的权限。

 其他系列文章导航

Java基础合集

数据结构与算法合集

设计模式合集

多线程合集

分布式合集

ES合集


文章目录

其他系列文章导航

文章目录

前言

一、处理措施

二、事后复盘完善

2.1 控制操作权限

2.2 生产环境隔离

2.3 SQL 审批

2.4 数据库审计

2.5 提升风险意识

三、总结


前言

情况:

某天中午,公司的产品出现了问题,有人汇报说所有用户都变成了管理员,并且可以享受管理员的权限。

然后员工小 A 大叫:“我 X,是我今天执行单元测试更新数据的时候,少加了个 where 条件!”

本来的预期:update user set userRole = 'admin' where id = 1
实际上执行:update user set userRole = 'admin'

image.gif

于是导致整个库里的所有用户都变成了管理员,并且可以享受管理员的权限。


一、处理措施

解释一下,就跟我们在路上看到一起交通事故一样,第一时间要么是保护现场,放一个小牌牌不让大家进到事故发生地;要么就是防止扩大影响,人工疏导不让更多人围观、阻塞交通。

一般这两件事情是同时执行的,由于我知道怎么能够判定哪些用户本来是 VIP(比如通过 VIP 信息)、而且程序又有详细的日志,所以第一时间是让员工先把 user 表的所有角色设置为普通用户权限,防止有人继续利用管理员权限去做一些不好的事情。

接下来就是立刻停止了线上的前后端服务,一方面是为了后面好恢复数据,另外也是防止一些同学发现自己突然从会员变成了普通用户,增加大量的人工咨询成本。

稳定现场后,接下来就是想办法恢复数据到正常的状态,好在我给数据库设置了分钟级别的备份,可以直接把数据恢复到事故发生前的最近正常的时间点。

image.gif编辑

有了备份后的老数据,还要考虑恢复这个时间点后新增的用户数据。

有很多种恢复策略,我优先选择了逻辑最简单的策略:直接更新用户 updateTime > '2023-07-20 10:00:00' 的数据,根据 id 点对点覆盖除了 userRole 之外的数据列;如果没有对应的 id,新增一条数据。也就是使用类似 saveOrUpdate 的方法。

理想很丰满,现实很残酷。万万没想到,由于 updateTime 是一个发生数据修改时自动更新的字段,导致所有的数据 updateTime 全是最新的,相当于要把数据库全量的数据都去比较一遍。

单线程还是太慢了,于是我用并发编程的方式改进了同步的过程。先把所有用户分组,然后多线程同时执行 saveOrUpdateBatch 方法。


二、事后复盘完善

2.1 控制操作权限

为了防止用户执行 update、delete 操作时不小心漏掉了 where 条件、直接更新全量数据,企业中一般是会禁止不带 where 条件的修改操作的。

出现这次的事故后,我也立刻给 MySQL 开启了 sql_safe_updates 配置:

image.gif编辑

缺少 where 条件的更新会直接触发下列报错:

image.gif编辑

之前为什么没加?主要是因为以前都是自己一个人开发系统,而且会有需要全量更新的场景,图省事儿。

2.2 生产环境隔离

正常情况下,不应该允许直接在本地连接和操作线上数据库的数据。而是需要先编写代码、提交代码审核、发布上线后,再执行修改操作。

像这次的事故,如果员工不是本地直接更新数据库,而是提交代码给我看一下,我大概率就会发现他少写了更新条件,就能防止了。

其实之前在大公司的时候,我们都会严格注意这些事项的。但之所以现在的小公司的项目是允许员工在本地连接线上的,想必大家也能猜到原因 —— 业务规模小、人数少,直接在同一个库开发会方便一些。

但如果项目的规模上来了,一定要做好多套环境的隔离,本地环境、测试环境、预发布环境、线上环境都要严格区分了。

2.3 SQL 审批

之前在大公司的时候,想要修改关键库的数据,不能直接执行 SQL 语句,而是要先把 SQL 语句提交到审核平台,等你的领导和数据库运维确认没问题后,才能执行。这样每条 SQL 都是至少有 2 个人看过的,能够大大增加安全性。

曾经我觉得这种机制很麻烦,但经历过一些血泪教训后,才意识到这个环节真的是泰裤辣!

2.4 数据库审计

数据库审计是指记录和监控数据库的访问及 SQL 语句执行情况,从而精细化风险控制,提高数据安全性。

可以自己在数据库配置(比如开启日志、使用审计插件等),也可以使用第三方云服务自带的审计规则配置。

2.5 提升风险意识

最不需要技术,却也是最重要的一点,那就是要让团队的所有同学意识到这件事情带来的风险、问题的严重性。

因为你永远叫不醒一个装睡的人,同理,再多的防护也限制不了本身就想搞事的人。

所以这件事情是我和这位员工共同的责任,作为惩罚,我们决定请其他同事喝奶茶。就这么愉快地决定了~


三、总结

这次事件再次强调了在进行数据库操作时,特别是更新、删除、赋予权限等敏感操作时,必须非常谨慎。任何的疏忽都可能导致严重的后果,如本次事件中,用户权限的错误更新导致了所有用户都拥有了管理员权限,这无疑是一个巨大的安全漏洞。

对于开发人员,如员工小A,应进行定期的代码审查和单元测试,确保此类问题不再发生。同时,对于此类可能产生严重后果的操作,应该采用更严格的审批流程,如需要多人同时审核,以确保操作的正确性和安全性。

此外,对于数据库操作,应该有完善的备份和恢复机制,以便在发生错误时能够迅速恢复到正常状态。对于用户数据的更改,也应该有详细的记录和审计机制,以便追踪和管理可能出现的问题。

总的来说,这次事件提醒我们在进行任何数据库操作时,都应该小心谨慎,避免因疏忽导致严重的后果。同时,对于可能产生严重后果的操作,应该采用更严格的审批流程和备份恢复机制,以确保数据的安全性和完整性。

目录
相关文章
|
7月前
|
Go 区块链 知识图谱
刚入职,严重怀疑自己不适合互联网行业。
近期几个月不少学弟学妹都陆陆续续毕业,然后把头发梳成大人摸样,相继开始入职,正式成为打工人!
48 0
|
11月前
|
消息中间件 设计模式 NoSQL
8年程序员年初被迫毕业,前后面试30家公司,如今终于上岸
大家好,我是君哥。今天分享一个老弟,被“毕业”后的求职经历。 在老东家干了 6 年,发展一般,很想出去,但是一直没有合适的机会,只好一边准备面试一边学习。让我没有想到的是,突然收到了“毕业”通知,当然,不光是我,而是整个团队。 毕业,对于我这样的老员工来说是不错的结果,因为正好我也想出去,而且这次公司还能给不少补贴。
|
弹性计算 Kubernetes 架构师
985毕业,工作3年,分享从阿里辞职到了国企的一路辛酸和经验
楼主本硕985,毕业的时候去了杭州某互联网大厂,后来又跳槽去了北京某互联网大厂。简单的谈一下互联网的感受吧,工作压力大,节奏快,但是从技术上确实得到了成长,尤其是当你维护与大促相关的系统的时候。记得在北京的时候,作为系统负责人,那个系统docker就800个,那个系统的并发量在全国来说肯定是top级别的。通过维护大促系统,排查跳点,不断地优化系统的框架,优化JVM,所带来的技术提升是质的飞跃。
|
搜索推荐
公司应该如何招人?
对公司来说,创始人最重要的三件事:找人、找钱、找方向。
93 0
公司应该如何招人?
|
缓存 算法 网络协议
二本学生小公司实习遭领导歧视,于是逆袭进百度!
二本学生小公司实习遭领导歧视,于是逆袭进百度!
二本学生小公司实习遭领导歧视,于是逆袭进百度!
|
中间件 程序员
历经外企、创业公司、大厂的程序员告诉你:第一份工作有多重要!
  笔者毕业5年,先后经历了创业公司,外企和国内一线互联网公司。本文用经历告诉你,第一份工作对于你的重要性和怎么选择第一份工作。   笔者第一份工作去了外企,也正是因为去了外企让我学会了很多,也塑造了自己的编程习惯和工作方式,时至现在也未曾改变。其实公司就是学校,第一家公司对你的工作习惯的塑造很重要。因为是外企,公司的文化相对扁平,没有尔虞我诈也没有勾心斗角。举几个具体的公司特质说一下对笔者的职业习惯的塑造。   新人培训:这里的新人培训不同其他公司,它会有6个月试用期,这6个月会有一个老师专门负责你的成长,定期给你 Review 表现。同时每一个月所有和你接触过的人会去一个小黑屋说你“坏
243 0
众筹十万美元搞火箭,搞研发全靠志愿者!这个“草根”航天组织已经开启载人测试
众筹十万美元搞火箭,搞研发全靠志愿者!这个“草根”航天组织已经开启载人测试
146 0
众筹十万美元搞火箭,搞研发全靠志愿者!这个“草根”航天组织已经开启载人测试
|
程序员 双11
程序员年底纷纷离职,同事们的反应让人意外
程序员年底纷纷离职,同事们的反应让人意外