打开项目代码,一眼就看到数据库密码直接写在代码里。这种事我见过太多次了,多到我都不想数。
你要明白,把敏感信息硬编码在Python文件里,就像把家门钥匙挂在门上。早晚会出事。可能今天没事,明天没事,但总有人会看见那串钥匙。
我接手过一个项目,代码库里有十几个文件都引用了同一个密码变量。每次改密码都像扫雷一样,漏掉一个就等着半夜被运维电话叫醒。后来我实在受不了了,决定彻底整治。
最基础的做法是用环境变量。把数据库密码、API密钥这些敏感信息放到系统环境变量里。Python里用os.getenv()读取。这样代码里就不会出现任何明文密码。就算代码泄露了,别人拿到的也只是一堆变量名,没有实际值。
但环境变量也有麻烦的地方。你不可能把所有配置都扔进去,那样环境变量会变得又长又乱。我见过有人往环境变量里塞了三十多个配置项,每个项目光设置环境变量就要花十分钟。
更好的选择是用配置文件。我推荐用configparser或者python-dotenv这些库。把配置写在.env或config.ini文件里。这种文件要加到.gitignore里,绝对不能提交到版本控制里。
有人会担心配置文件不小心被提交。我建议在项目根目录放一个.env.example文件,里面写上所有配置项的键名,值留空或者填示例数据。这样新同事来了也知道该填什么。这个示例文件可以放心提交到Git里。
对于更敏感的密钥,要用专业的密钥管理服务。比如AWS的Secrets Manager、GCP的Secret Manager或者Vault。这些服务会自动轮换密钥,还能审计谁访问过哪些密钥。项目启动时从密钥服务里取一次值,缓存到内存里。
我见过有人偷懒,把生产环境的密钥写死在代码里。他说“反正没人看代码”。结果代码被外包团队复制走了,数据库被拖库,用户数据全没了。这种事一次就能让你长记性。
还有一个很多人踩过的坑:把密钥写在Git历史里。就算你后来删掉了,只要历史还在,别人就能翻出来。
正确做法是:从一开始就别让密钥进入版本控制。用.gitignore屏蔽所有含密钥的文件。如果已经不小心提交了,赶紧用git filter-branch或者BFG Repo-Cleaner清理掉历史。
我自己的做法是这样:开发环境用python-dotenv加载.env文件。测试环境用环境变量。生产环境用密钥管理服务。所有读取密钥的代码都封装在一个模块里,其他地方只导入模块,不直接触碰密钥字符串。
有一次我给团队做代码审查,发现有个新人把AWS的访问密钥写在了代码里。我让他改,他说“就这一次,马上要上线”。我没同意。后来他在.env文件里配置好,整个过程只花了三分钟。那三分钟省下了后面无穷的麻烦。
安全这件事,不能靠人的自觉,要靠机制。你没法保证每个程序员都时刻警惕。但你可以保证代码里没有硬编码的密钥,可以保证CI/CD流水线会自动扫描密钥泄露。
还有一点很多人忽略:日志里不要打印配置信息。我见过有人为了方便调试,在启动时把整个配置对象打印出来。然后日志文件被运维人员误发到公共聊天群,密码就这么公开了。
最后说一个实战技巧:把所有配置项的管理写一个统一的类。这个类从多个来源加载配置:优先从环境变量读,其次从配置文件读,最后用默认值。这样同一个配置项在不同环境有不同的值,代码里却只需要调用同一个方法。
做好这些事,花不了你太多时间。但能让你睡得安稳一点,能让你在出现安全事故时不用背锅。何乐而不为?