安全指南

安全超入门:.env 和 API key 到底危险在哪、又该怎么守

写给个人开发者的安全第一步:.env 和 API key 是什么、泄露后会发生什么(别人以你的身份使用服务,费用记在你账上),以及从今天就能做的 4 个基本防护办法。

发布于 2026-06-07 更新于 2026-10-06 3 分钟阅读
本页目录

「都说安全很重要,可到底该先从哪儿下手?」——这就是写给这样的个人开发者的、最最开始的第一步。不是为了吓唬你,而是只把从今天就能动手的事,按顺序讲清楚。

为什么要从秘密的值(.env 和 API key)开始

真实发生的事故,很多都不是什么高级攻击,而是从**「秘密的值泄露了」**开始的。本站拿来作为出发点的两个案例,也都是秘密泄露:

也就是说,只要能守住秘密的值,常见事故里的绝大多数就都能防住。所以我们就从这里开始。

.env 是什么(30 秒讲完)

.env(点 env)是把应用要用的秘密的值汇总到一起的配置文件。里面装着数据库的密码、外部服务的 API key、给会话加密用的密钥等等。正因为这些秘密的值都集中在一个文件里,一旦泄露就会全部暴露,所以要最优先地守好它(→ 术语:.env 是什么)。

秘密的值可以放在哪里(.env、环境变量、密钥管理服务)

存放秘密的值,不只有 .env 一种办法。按规模和用途来选。

存放位置适合要注意的地方
.env 文件本地开发、单台小型服务器不放进 Git,也不放进公开目录
托管服务的环境变量设置(在控制台中输入)生产环境限制谁能访问控制台;别让值出现在构建日志里
CI(自动测试和部署)的 secretsGitHub Actions 等自动化流程在 CI 中运行的外部工具能看到这些值;只传入权限够用的 key
密钥管理服务多人或多台服务器读取权限保持最小,并定期轮换

关于 CI 的 secrets,2021 年的 Codecov 事件很有参考价值。在 CI 中运行的一个外部工具被篡改,保存在 CI 环境变量里的秘密的值被拿走了(→ Codecov 事件)。

可以公开的 key 和绝不能公开的 key

有些 API key 本来就是要放进浏览器或手机 App 里发布的,有些则只能在服务器上用。凡是发送到浏览器的东西,都要假定任何人都能读到。

例子能否公开理由
Stripe 可发布密钥(以 pk_ 开头)可以文档说它可以放进前端代码;它不能执行创建扣款这类敏感操作
Stripe 私密密钥(sk_)或受限密钥(rk_)不可以它们能执行服务端操作;文档建议使用缩小了权限的受限密钥
带 NEXT_PUBLIC_ 的 Next.js 环境变量会被公开它的值会在构建时内联到浏览器端 JavaScript 中
不带 NEXT_PUBLIC_ 的 Next.js 环境变量不公开(仅服务端)秘密的值放在这里

拿不准时,去查该服务的官方文档,看这个 key 能否在客户端使用。如果文档没写,就把它当作不能公开的 key。

API key 泄露后会发生什么

API key 是「让服务把调用者当作你本人来对待的一串字符」。它一旦落到别人手里,损害就会这样扩大。

① API key 泄露(经由公开目录 · git 提交 · 漏洞)
↓ 时间差(数天起)
② 第三方“以你的身份”使用外部服务
↓
③ 盗刷(大量调用)/读写数据/冒名顶替
泄露刚发生时悄无声息。被人有时间差地滥用,某一天账单或损失突然浮出水面。

被偷走的 key 往往会有时间差地被转卖、滥用,「泄露刚发生时啥也没有→过些天账单突然飙升」是很典型的套路。所以「等发现了再说」就晚了,关键是从一开始就别让它泄露。

怀疑 key 已经泄露时该怎么做

只从代码里删掉 key,是挡不住的。GitGuardian 的 2025 年报告发现,2022 年在公开仓库中泄露的秘密信息,有 70% 到报告发布时仍然有效。请按以下顺序处理。

  1. 在签发方的控制台作废或轮换这个 key。如果服务提供宽限期,就让泄露的 key「立即」失效
  2. 在生产环境设置新 key,确认应用能正常运行
  3. 查看签发方的使用记录和账单,有没有不是你的活动
  4. 从文件和 Git 历史中删除,可以放到作废之后再做(单靠删除,挡不住已经拿到副本的人)

详情见 GitHub 上公开的 54 万个凭据仍然有效。GitHub 默认开启「推送保护」,可以阻止个人账户把秘密信息推送到公开仓库,但并不能拦住所有种类的秘密信息。

从今天就能做的 4 个防护办法

不需要什么难的东西。先做好这 4 件就行。

1

不公开

别把 .env 和应用本体放到 Web 上能看见的目录(公开根目录)里。对外公开的只能是 public/。在虚拟主机上的具体操作步骤见 这篇文章。

2

不提交

在 .gitignore 里加上 .env*(!.env.example 可以放行)。只共享不带值的样例。一旦提交过就能从历史里恢复出来,所以从一开始就别放进去。

3

泄露就全部更换

不是只换一个,而是把有可能泄露的钥匙全部轮换。优先顺序是「外部 API · OAuth → 加密密钥 → 邮件 → DB」。按「已经被看到了」的前提来处理。

4

自查

偶尔确认一下自己的网站,看 /.env 能不能从外面打开(见下)。

自查(只对自己拥有的域名做)

# 返回 200 且带正文就是被公开了。403/404 则暂时没问题
curl -sI https://你的域名/.env | head -1
curl -sI https://你的域名/.git/config | head -1

养成每次上线都确认一遍的习惯,就能尽早发现放置位置的失误。

除了从外部能看到的,也要检查 Git 和构建产物(在你自己的仓库中运行)。

# .env 是否曾被提交过?(有输出就说明某个时候提交过)
git log --all --oneline -- .env
# Git 当前跟踪的类似 env 的文件(.env.example 以外的都要看一下)
git ls-files | grep -i "env"

要确认没有 key 被发送到浏览器,可以在构建产物文件夹(Next.js 是 .next/static)中搜索 key 的前几个字符。也可以在发布前把代码粘贴到密钥泄露扫描里检查(不会发送到任何地方)。

容易犯的错 vs 正确的第一步

容易犯

  • 反正先跑起来了,就把 .env 直接放在 public 下
  • 想着「以后再删」,把 .env 提交进 git 一次
  • 只换那一个看到被滥用的钥匙

正确的第一步

  • 本体放在公开根目录之外,只公开 public/
  • 从一开始就用 .gitignore 把 .env 排除掉
  • 泄露了就把 env 里的钥匙全部轮换

下一步

走到这一步,接下来就是「自己技术栈里危险的默认设置」和「不在已公开漏洞(CVE)上落后的机制」了。别着急,一个一个来。

出处

接着读

FAQ

Q想学安全,该从哪儿开始?
A

先从『不让秘密的值(.env 和 API key)泄露出去』开始。很多真实事故都是从这里发生的。不公开、不提交到 git、泄露就全部更换、偶尔自查一下,做好这 4 点就能挡住绝大多数事故。

QAPI key 泄露后,具体会发生什么?
A

别人能冒充你去使用外部服务。常见的就是盗刷(用你的账单跑大量调用),以及读写数据。泄露的 key 往往会有时间差地被转卖、滥用。

Q.env 可以放进 git 吗?
A

不可以。要在 .gitignore 里加上 .env*,只共享把值清空后的 .env.example。一旦提交过,即便之后删掉,也能从 git 的历史里恢复出来。

Q.env 文件是什么?
A

一个把应用的设置,尤其是密码、API key 这类秘密的值,和代码分开保存的文本文件。每行写成「名称=值」。Laravel、Next.js、Django 等许多框架都会在启动时读取它。因为秘密的值都集中在里面,所以它必须远离 Git,也必须远离公开目录。

Q.env 和环境变量有什么区别?
A

环境变量是机制本身:操作系统或运行环境传给程序的值。.env 文件则是一个容器,把这些值写在文件里,让应用或库在启动时把它们作为环境变量读进来。在生产环境中,很多做法会不用 .env 文件,而是通过托管服务的控制台或密钥管理服务传入环境变量。

Q可以把 API key 写进前端(浏览器)代码吗?
A

只有官方明确说明可以公开的 key 才行。发送到浏览器的 JavaScript,任何人都能读取。例如,Stripe 的文档说可发布密钥(以 pk_ 开头)可以放进前端代码,而私密密钥(sk_)和受限密钥(rk_)绝不能暴露。在 Next.js 中,带 NEXT_PUBLIC_ 前缀的环境变量会被内联到浏览器端代码里,所以绝不要给秘密的值加这个前缀。