如何阻止 Cursor 读取你的 .env

Cursor 的 .cursorignore 文件覆盖什么、不覆盖什么,zn-gate 的钩子为 .env 文件增加了什么,以及一个可以在你自己的机器上用假数据完成的简短测试。

查看 .md

有两层措施可以帮助让 .env 文件远离 Cursor 的智能体。Cursor 自带的忽略文件 .cursorignore 控制智能体、Tab 和 Inline Edit 能看到哪些文件。zn-gate 增加了钩子,用来阻止读取含有值的 .env 文件的文件读取操作和大多数 shell 命令。本页根据各自的文档说明两者的作用,并提供一个你可以自己运行的测试。

.cursorignore 的作用

根据 Cursor 关于忽略文件的文档:

  • 在根目录创建 .cursorignore 文件,使用 .gitignore 语法。
  • Cursor 会阻止其中列出的文件出现在 "Code accessible by Agent, Tab, and Inline Edit" 和 "Code accessible via @ mention references" 中。
  • Cursor "automatically ignores files in .gitignore and the default ignore list"。这个默认列表包含 .env*。
  • 你可以在 Cursor Settings > Indexing > Ignore Files > Hierarchical Cursor Ignore 中启用分层忽略文件,也可以在用户设置中配置全局忽略模式(全局列表默认为空)。

一个最简单的 .cursorignore:

.env
.env.*

.cursorignore 不覆盖的内容

同一页 Cursor 文档指出了两条限制:

  • "The terminal and MCP server tools used by Agent cannot block access to code governed by .cursorignore."(智能体使用的终端和 MCP 服务器工具无法阻止对 .cursorignore 所管辖内容的访问。)
  • "While Cursor blocks ignored files, complete protection isn't guaranteed due to LLM unpredictability."(Cursor 会阻止被忽略的文件,但由于 LLM 的不可预测性,不保证完整的保护。)

因此,忽略文件是有用的第一层,但根据 Cursor 自己的文档,它并不覆盖通向文件的所有途径。

zn-gate 在 Cursor 中增加了什么

zn hooks install cursor 会写入 Cursor 的 hooks.json。Cursor 的钩子文档描述了 zn-gate 使用的事件:beforeReadFile("Called before Agent reads a file. Use for access control to block sensitive files from being sent to the model")和 beforeShellExecution(在 shell 命令执行前调用,并返回权限决定)。安装钩子后:

  • 读取含有值的 .env 文件和常见凭据文件的文件读取与大多数 shell 命令会被阻止。
  • 粘贴到提示词中的密钥会被阻止。
  • 携带密钥值的 MCP 调用会被阻止。
  • zn-gate 识别出的密钥会从 MCP 工具输出中移除。

安装方法:

npm install -g zn-gate
zn hooks install cursor

重启 Cursor,然后在终端运行 zn-gate check。它应当对 Cursor 显示 OK(输出的含义)。

zn-gate 在 Cursor 中不覆盖的内容

  • shell 输出和文件内容不会被清理。Cursor 的文档没有列出能修改它们的钩子:postToolUse 只能替换 MCP 工具的输出(updated_mcp_tool_output,"For MCP tools only")。
  • 由 shell 命令打印的密钥,或写在智能体读取且未被阻止的文件中的密钥,会传到模型。
  • 写入保护是尽力而为,因为 Cursor 没有记录所有工具的输入。
  • Cursor CLI(cursor-agent)不在覆盖范围内。
  • 如果 zn 的钩子崩溃,读取和提示词会被阻止,其他事件则不经检查直接运行。
  • 未在 Windows 上测试。

如果你想把值完全移出文件,请把它们存放在 zn-gate 的保险库中:先运行 zn unlock,再运行 zn env shadow .env。这样你的 .env 里保存的是标记而不是真实值(Scrubber)。

在你自己的机器上测试

这个测试只使用假数据。我们没有在 Cursor 中完整地端到端运行过它(见 Cursor 页面上的状态说明),所以下面写的是根据文档预期会发生什么,以及如何自己检查每一步。

  1. 在一个新的空文件夹中创建 .env 文件,只写假数据:

    EXAMPLE_KEY=not-a-real-key
    EXAMPLE_URL=https://example.com
  2. 在 Cursor 中打开该文件夹,让智能体执行:"读取 .env 文件并告诉我里面有什么。"记录发生的情况。根据 Cursor 的默认忽略列表,.env* 文件应当已经被忽略。

  3. 创建内容为 .env 的 .cursorignore 文件。如果该文件夹是 git 仓库,运行 git check-ignore -v .env(Cursor 的文档建议用 git check-ignore -v [file] 测试模式)。再问一次并比较结果。

  4. 让智能体运行一条会打印该文件的终端命令。Cursor 的文档说终端工具不受 .cursorignore 管辖,请查看你实际看到的结果。

  5. 安装钩子(zn hooks install cursor),重启 Cursor,重复第 2 步和第 4 步。根据 zn-gate 的文档,读取该 .env 的文件读取和大多数 shell 命令应当被阻止,智能体应当收到钩子给出的消息,而不是这些值。

  6. 完成后删除示例文件夹。要移除钩子:zn hooks uninstall cursor。

这里只有你自己的结果才算数。如果某一步的表现与本页所述不同,请联系我们,并附上你的 Cursor 版本。

常见问题

.cursorignore 能阻止 Cursor 读取 .env 吗? 它会对智能体、Tab、Inline Edit 和 @ 引用屏蔽所列文件。Cursor 的文档说,智能体使用的终端和 MCP 工具不受它管辖,并且不保证完整保护。

Cursor 默认会忽略 .env 吗? Cursor 的文档在默认忽略列表中包含 .env*,同时也包含你的 .gitignore 中的文件。

zn-gate 能替代 .cursorignore 吗? 不能。它们作用于不同的环节。建议两者都用。

zn-gate 能隐藏 Cursor shell 输出中的密钥吗? 不能。Cursor 不允许钩子修改 shell 或文件输出,只有 MCP 工具输出会被清理。

如何撤销? zn hooks uninstall cursor。

来源