关于hardcoded账号和密码的问题的想法

        在编写应用程序时,都会访问一些存储系统获取相关的信息。最简单的例子就是用户登录,需要访问存储的用户和密码,进而可以验证用户是否可以正常登录。为了访问数据库各种框架结构也都提供了相应的方法和接口支持。但是,程序员在实现时为了方便经常会使用一些不太安全的方法,容易导致系统的存储系统的访问账号和密码的泄露。而存储系统经常存储一些重要的敏感的信息,这就可能导致重要信息的泄露。一旦像数据库中的信息泄露,将会给系统带来严重的负面影响。

下面列举一下常见的错误:

  • 将密码写死在代码里

这是最容易也是最简单地实现访问存储系统的方法,直接写在代码里,访问数据库非常简单。同时,也就意味着会用同一套代码部署的系统只能用同一个账号和密码访问数据库。一旦密码泄露,也很难及时修复系统。必须要研发团队重新修改代码,升级系统,同时也需要数据库管理团队的密切配合。给系统的维护带来很大的不便。

  • 将密码写死在配置文件

写入配置文件相对于写在代码里稍微好一些,但是,也有同一个问题,就是开发环境和实际运行环境是否使用了不同的配置文件?是否能够保证使用了不同的配置文件之后,使用的账号和密码是不同的? 如果使用不同的配置文件,但是使用相同的账号和密码,这个和使用同一个配置文件也没什么区别,主要的区别就是修改产品线上的账号和密码时,比较容易一些。

在代码仓库上的默认的配置,是否能够保证在实际部署时,能够保证在产品线上使用不同的密码?

  • 使用系统默认的用户名和密码

所有的数据库系统基本上都会提供一个默认的管理员级别的用户名和密码,有些开发为省事,就直接使用这个账号和密码。当一个攻击者扫描到一个数据库系统时,就会首先尝试使用默认的用户名和密码。所以,一旦使用默认的用户名和密码,攻击者就可以控制整个数据库系统。

关于解决这些硬编码的密码的方案也有很多种,下面就罗列一下我自己的一些想法:

  • 在代码的仓库里,一定不能含有硬编码的密码,尤其是在产品线上仍然使用的密码,不管是在代码里,还是在配置文件里。如果是测试代码,建议使用一些明显测试特征的密码,例如:Test@1234。曾经在Review代码时,发现测试代码里测试加解密的代码里居然有访问数据的账号和密码,这就导致了密码多一个泄露的地方,而且,隐藏的很深。
  • 这些密码需要保存在一个受保护的区域,由专门的人负责维护。同时,对维护和访问的所有操作都要记录日志,实时监控。可以放在专门的系统里,例如:Vault;也可以放在HSM里,不过,HSM的价格一般比较昂贵。
  • 这些密码需要有一个安全的机制让应用程序在启动之前能够获取。应用程序和这些存储服务之间有严格认证关系,保证只有信任的服务器才能够访问。例如:可以使用公钥和私钥系统认证系统。
  • 密码可以定期更新,同时,所有应用程序可以根据更新的机制同步更新,不影响访问数据库系统。 例如:将账号和密码都列入更新的范围,这样新老账号可以同时工作一段时间,以防出现问题可以及时回滚,等新的账号和密码验证可以工作了,再删除老的。像MySQL8.0可以支持Dual-password的功能,就可以使用一个账号,然后,同时使用两个密码,等新的密码确认可以正常工作时,再废弃老的密码。更新时需要有通知的机制,保证各个团队都能够及时关注更新,观察产品是否能够正常运行。一旦发现有问题,要有机制尅及时回滚。
  • 要有机制废弃老的密码或者账号。如果更换了新的账号或者密码,但是老的账号或者密码没有机制保证能够及时废除,也是很危险的。可以设置一个自动超时机制,一旦,超过一定的时间,老的账号或者密码就强制自动废弃。
  • 一定不能使用系统默认的账号和密码。需要根据系统的需要专门创建一个符合应用需求的足够权限的账号即可,没有必要给太多权限,给的权限越多,出问题时,导致的伤害就会越大。例如:有SQL注入的问题时,如果提供的root账号,攻击者就可以做一些对系统由致命打击的删除操作,导致系统彻底不能使用。

总之,无论如何,尽量避免hardcoded的关键敏感信息,包括:密码、token、加密的密钥等,需要在实现之初就应该规划好如何管理这些内容,如何能够基于当前的系统架构实现动态更新,这样才能保证一旦出现泄漏问题,可以及时更换泄露的内容,保护系统的安全。

你可能感兴趣的:(数据库,安全)