← 返回蜂巢洞察

如何修复泄露的API密钥:开发人员必备的Git安全指南

想象一下这样的场景:你工作到很晚,终于让代码运行成功了,准备将其推送到GitHub上。 你执行了以下操作: git add . git commit -m "修复API集成问题" git push 几分钟后,你发现了一些异常现象:API的使用量突然增加了。可能是出现了意外的请求、新的云资源被使用了,甚至账单金额也比预期要高得多。 然后你发现了问题的根源: const apiKey = "sk_live_123456789"; 你的API密钥竟然被保存在Git仓库中去了。 这种情况确实很令人紧张,但也是可以解决的。 最重要的一点是: 如果API密钥已经被提交到了Git仓库中,那么即使你立即将其删

想象一下这样的场景:你工作到很晚,终于让代码运行成功了,准备将其推送到GitHub上。

你执行了以下操作:

git add .
git commit -m "修复API集成问题"
git push

几分钟后,你发现了一些异常现象:API的使用量突然增加了。可能是出现了意外的请求、新的云资源被使用了,甚至账单金额也比预期要高得多。

然后你发现了问题的根源:

const apiKey = "sk_live_123456789";

你的API密钥竟然被保存在Git仓库中去了。

这种情况确实很令人紧张,但也是可以解决的。

最重要的一点是:

如果API密钥已经被提交到了Git仓库中,那么即使你立即将其删除,也要假设该密钥已经被复制并被人利用了。

仅仅从最新版本的文件中删除这个密钥,并不能确保旧版本的安全性。因为Git会保留文件的历次版本,而那些被暴露的敏感信息仍然可能被自动化扫描工具发现。

在接下来的内容中,你将学习到以下内容:

在整篇文章中,我们都将使用这种基本的工作流程:

使凭证失效 → 进行调查 → 移除该凭证 → 用新凭证替换它 → 防止类似事件再次发生

在讨论最关键的部分——即在密钥被泄露后现在应该采取什么措施之前,我们先来了解一下API密钥到底是什么。

什么是API密钥?

API密钥是一种凭证,它允许某个应用程序与另一项服务进行交互。

例如,一个应用程序可能会使用API密钥来访问以下服务:

  • 天气信息服务

  • 支付服务提供商

  • 地图服务

  • 人工智能API

  • 云平台

  • 数据库

  • 电子邮件服务提供商

  • 私营公司的API

API密钥的具体格式可能如下所示:

const apiKey = "你的真实API密钥";

或者它也可能出现在配置文件中:

{
  "apiKey": "你的真实API密钥",
  "databasePassword": "你的真实密码"
}

API密钥通常被称为敏感信息,因为拥有这些密钥就意味着有人可以利用它们来发送请求、访问数据、创建资源,甚至从你的账户中生成费用。

并不是所有的API密钥都具有同等的敏感性。有些服务会提供那些对用户来说显而易见的浏览器密钥,不过这类密钥仍然需要受到适当的限制、配额管理以及权限控制。

一般来说:

如果某种凭证能够访问敏感数据、创建资源、修改记录或生成费用,那么就不应该将其直接存储在源代码中。

紧急应对措施:首先应该做什么

当你发现自己的凭证被泄露时,人们通常会想到从文件中删除该密钥,然后提交一次更新。

但不要这样做。

你的首要任务是使这个被泄露的凭证失效

1. 使被泄露的凭证失效
2. 调查任何可疑活动
3. 从代码中移除该敏感信息
4>用新的凭证替换它
5>如有必要,清理Git历史记录
6>验证清理操作是否有效
7>采取措施防止未来再次发生类似泄露事件

可以把API密钥想象成一把掉在拥挤街道上的家门钥匙——如果有人已经捡到了这把钥匙,那么删除它的图片根本无济于事。

首先应该更换锁具。

第一步:撤销或更新被泄露的密钥

请前往发放该凭证的服务提供商的管控界面。

根据不同的服务提供商,你可能会看到以下选项:

  • 撤销

  • 删除

  • 禁用

  • 更新为新密钥

  • 重新生成密钥

  • 创建新的密钥

如果该服务提供者支持密钥轮换功能,那么在禁用旧密钥之前,应先创建一个新的替代凭证。这样可以在您更新配置时减少应用程序的停机时间。

最重要的是,原来的凭证必须不能再被使用。

切勿重新使用泄露的密钥。不要给它改名,也不要对它进行加密处理,更不要把它移到另一个文件中就认为它是安全的。千万不要以为没有人看到过这个泄露的密钥。

应该把它视为已经遭到泄露的密钥来处理。

步骤2:调查可疑活动

在禁用该凭证后,请查看服务提供者的使用情况监控面板和日志记录。

需要注意以下这些异常情况:

  • 请求量突然激增

  • 来自陌生地区的请求

  • 意外的数据库查询操作

  • 新出现的云资源

  • 权限设置发生了变化

  • 出现异常的文件下载行为

  • 不寻常的支付活动

  • 新的应用程序部署记录

  • 在您的应用程序处于非活跃状态时仍有人发起请求

如果该凭证拥有广泛的权限,那么就意味着在其权限范围内任何内容都可能被访问或修改

例如,如果某个云服务凭证具有创建虚拟机器的权限,就需要检查是否有人创建了不必要的虚拟机器。

如果某个凭证能够访问数据库,那么就需要审查以下内容:

  • 认证日志

  • 读取操作记录

  • 写入操作记录

  • 被删除的记录

  • 导出的数据

  • 新创建的用户账户

  • 权限设置的变化

如果该凭证能够生成基于使用量的费用,那么还需要检查您的账单信息。

把您发现的所有异常情况都记录下来。制作一个简单的时间线可以帮助您梳理这些事件的发展过程:

10:15 - API密钥被启用
10:23 - 代码库被公开发布
10:41 - 发现异常使用行为
10:45 - 密钥被禁用
11:00 - 查看日志记录
11:30 - 部署新的替代密钥
12:00 - 清理Git历史记录

如果需要向团队或服务提供商报告这一事件,这样的时间线会非常有用。

步骤3:从当前代码中移除该敏感信息

一旦原来的凭证被禁用,就必须从您的开发代码中将其删除。

const apiKey = "your-real-api-key"; // 这种写法是不安全的

正确的做法是从环境变量中获取该凭证:

const apiKey = process.env.API_KEY;

if (!apiKey) {
  throw new Error("API_KEY未配置");
}

在Python中也是同样的道理:

import os

api_key = os.environ.get("API_KEY")

if not api_key:
    raise RuntimeError("API_KEY未配置")

关键思路很简单:

源代码 → 环境变量 → 敏感信息

而不是这样:

源代码中直接写入硬编码的密钥

环境变量并非管理密钥的唯一方式,但对于本地开发和许多部署环境而言,它们确实是一种常见且实用的解决方案。

步骤 4:在本地开发中使用 .env 文件

在进行本地开发时,可以将环境变量保存在 .env 文件中。

例如:

API_KEY=你的本地开发密钥
DATABASE_URL=你的本地数据库地址

对于 Node.js 项目来说,可以使用像 dotenv 这样的包来加载这些配置值。

安装方法如下:

npm install dotenv

然后这样使用:

import "dotenv/config";

const apiKey = process.env.API_KEY;

需要注意的是,.env 文件通常不应该被提交到 Git 仓库中

需要将其添加到 .gitignore 文件中:

# 环境配置文件
.env
.env.*
!.env.example

# 认证信息文件
*.pem
*.key
credentials.json
service-account.json

# 本地开发相关文件
.DS_Store

不过需要注意的是,.gitignore 并不会删除 Git 已经跟踪的文件

如果 .env 文件已经被提交到了 Git 仓库中,将其添加到 .gitignore 中也不会使该文件从 Git 中被删除。

如果你想停止跟踪某个文件但仍然希望它在你的电脑上保留,可以执行以下命令:

git rm --cached .env

之后再提交 .gitignore 文件的更改:

git add .gitignore
git commit -m "忽略本地环境配置文件"

但请记住:这样做只会让未来的提交不再包含这个文件,而已提交的版本中的密钥信息并不会被删除。

这时 Git 的历史记录就起到了关键作用。

步骤 5:创建一个安全的 .env.example 文件

其他开发人员仍然需要知道应用程序需要哪些环境变量。

因此,不要直接将 .env 文件提交到仓库中,而是创建一个 .env.example 文件:

API_KEY=
DATABASE_URL=
PORT=3000
LOG_LEVEL=info

这个文件中包含的是变量名称而非真实的认证信息,因此可以将其提交到仓库中。

你还可以在文件中添加注释来说明各变量的用途:

# 必需的 API 认证信息
API_KEY=

# PostgreSQL 连接字符串
DATABASE_URL=

# 可选的应用程序端口
PORT=3000

新来的开发人员可以复制这个文件,然后填写自己对应的配置值。

在示例中,可以使用明显的占位符来表示这些需要用户输入的值:

API_KEY=请用你自己的密钥替换这里的内容

请避免将看起来真实的配置信息放入 .env.example 文件中。

步骤 6:确定该机密是否仍存在于 Git 历史记录中

这是解决配置信息泄露问题时最重要的环节之一。

假设你的 Git 历史记录如下所示:

提交 A:将 API 密钥添加到 config.js 文件中
提交 B:更新 API 集成功能
提交 C:删除 API 密钥

尽管提交 C 中已经没有该密钥了,但提交 A 中仍然保留着它。

Git 会记录文件的前几个版本信息。

你可以使用以下命令查看某个文件的版本历史:

git log --all -- config.js

如果要查看某个较早版本的文件,可以使用以下命令:

git show COMMIT_ID:config.js

你还可以在 Git 历史记录中搜索已泄露的密钥信息:

git log --all -S"your-leaked-key" --oneline

如果你确定该机密确实被提交到了 Git 仓库中,那么在证明其不存在之前,就应该认为它仍然存在于仓库的历史记录中。

何时需要重写 Git 历史记录?

并非所有情况下都需要重写 Git 历史记录。请考虑以下几种情况:

该机密从未被提交到仓库中

如果该机密仅存在于你的工作目录中,且从未被提交到仓库中,那么通常不需要重写历史记录。

只需将其删除,然后将相关文件添加到 .gitignore 文件中,然后继续正常操作即可。

该机密已在本地提交,但从未被推送到远程仓库

如果该机密仅存在于本地的提交记录中,而尚未被推送到远程仓库,那么你可以在推送之前先清理这些本地提交记录。

该机密已被推送到远程仓库

在这种情况下,应立即将该机密视为已泄露的敏感信息,并立即撤销或更换它。

之后再确定是否需要从仓库的历史记录中删除该机密。

该仓库是公共仓库

在这种情况下,应假设有人已经复制了该机密。

因此,撤销操作必须先于清理仓库历史记录的操作

该机密原本存在于私有仓库中

虽然私有仓库比公共仓库更安全,但它仍然不能被视为绝对安全的保密场所。

敏感信息仍有可能通过以下途径泄露:

  • 被入侵的账户

  • 外包商或合作伙伴

  • 集成系统

  • 持续集成工具的日志记录

  • 分支版本

  • 备份文件

  • 截图

  • 被复制的代码

  • 拉取请求

因此,最安全的做法依然是:

切勿故意将敏感信息提交到Git中,即使在私有仓库中也不行。

步骤7:从Git历史记录中删除敏感信息

如果这些敏感信息已经被提交到了仓库中,你可能需要将它们从仓库的历史记录中删除。

在修改历史记录之前,请先创建一个备份:

git clone --mirror https://github.com/your-username/your-repository.git repository-backup.git

这种“镜像克隆”方式会包含所有的分支和标签,因此如果在操作过程中出现问题,这个备份文件会非常有用。

选项1:删除整个文件

如果敏感信息被保存在某个文件中(例如`.env`文件),你可以将这个文件从仓库的历史记录中彻底删除:

git filter-repo --path .env --invert-paths

如果文件位于某个目录内,可以使用以下命令:

git filter-repo --path config/production.json --invert-paths

这样就可以将该文件从仓库的历史记录中删除。

选项2:替换文件中的敏感信息

有时你需要保留原来的文件,但只需从之前的版本中删除其中的敏感信息即可。

首先创建一个临时文件用于存储替换后的内容:

然后运行以下命令:

git filter-repo --replace-text replacements.txt

你可以用占位符来替换原来的敏感信息,例如:

your-leaked-key==>YOUR_API_KEY_HERE

请务必格外小心处理`replacements.txt`文件,因为其中包含原始的敏感信息,所以绝对不要将这个文件提交到仓库中。

在完成所有操作后,请立即删除这个临时文件:

rm replacements.txt

在Windows PowerShell环境中,可以使用以下命令:

Remove-Item replacements.txt

如果需要处理多个敏感信息,可以这样编写替换内容:

old-api-key==>>REMOVED_API_KEY
old-database-password==>>REMOVED_DATABASE_PASSWORD
old-token==>>REMOVED_TOKEN

之后再运行之前的命令即可。

首先在备份副本上测试这些操作,确保它们能够正常生效。

步骤8:确认敏感信息已被删除

即使命令执行成功,也不能就此认为清理工作已经完成。

请再次搜索那些已知泄露的敏感信息:

git log --all -S"your-leaked-key" --oneline

你还可以检查相关的文件和提交记录:

git log --all -- config.js

以及:

git show COMMIT_ID:config.js

如果你的仓库使用了分支和标签,请确保检查的范围包括所有分支,而不仅仅是当前激活的分支。

你还应该检查其他可能存放该敏感信息的地方,包括拉取请求、CI/CD日志、构建产物、发布文件、Docker镜像、软件包版本、文档、问题评论以及截图等。

请记住:

即使你修改了代码库的内容,那些已经存在于其他地方的副本并不会被自动删除。

这就是为什么必须撤销原有的敏感信息的原因之一。

步骤9:谨慎地推送已清理的历史记录

在确认所有数据都已被正确清理后,你可能需要将修改后的历史记录推送到远程仓库:

git push --force --all origin
git push --force --tags origin

重要警告

强行推送修改后的历史记录可能会对其他协作者造成影响。这种操作会改变提交哈希值,进而影响到那些已经克隆了该代码库的协作者。

在對共享项目执行此类操作之前,请务必:

  1. 通知所有协作者。

  2. 确保每个人都知道历史记录正在被修改。

  3. 与协作者协调,共同完成数据清理工作。

  4. 如果你的组织有相应的应急处理流程,请按照该流程操作。

在完成修改后,协作者可能需要重新克隆代码库:

git clone https://github.com/your-username/your-repository.git

他们不应该盲目地将自己本地仓库中的历史记录合并到已清理过的远程仓库中。

步骤10:在所有地方替换敏感信息

现在,你需要创建或使用新的敏感信息,并更新应用程序运行的所有环境。常见的需要更新的环境包括:

  • 本地开发环境

  • 测试环境

  • 预发布环境

  • 生产环境

  • Docker容器

  • Kubernetes配置文件

  • CI/CD系统

  • 托管平台

  • 定时执行的脚本

  • 无服务器函数

一个常见的错误是只更新了生产环境,却忽略了部署管道中的配置。

例如,你的本地应用程序可能可以正常运行,因为`.env`文件中使用了新的敏感信息,但CI/CD系统仍然使用旧的敏感信息。

你可以制作一份检查清单:

1. 本地开发环境
2. 自动化测试环境
3> 预发布环境
4> 生产环境
5> CI/CD系统中的配置变量
6> Docker配置文件
7> 云部署设置
8> 定时执行的脚本
9> 无服务器函数

在完成敏感信息的更新后,需要在每个关键环境中测试应用程序的功能。

步骤11:限制新敏感信息的使用范围

仅仅替换泄露的敏感信息还不够,还需要对新敏感信息进行适当限制,以确保其仅被用于实际需要的地方。

可以采取以下措施来限制新敏感信息的使用:

  • 只读权限

  • 特定的API使用范围

  • 允许的IP地址

  • 允许的域名

  • 针对特定环境的访问控制

  • 请求配额

  • 速率限制

  • 有效期

例如,一个天气应用可能只需要具备读取天气数据的权限。

它不应该被赋予管理用户、修改账单或删除无关资源的权限。

这就是最小权限原则

为每个凭证分配执行其功能所需的最小权限。

对于不同的环境,使用不同的凭证也是一个好习惯:

local-development-key
testing-key
staging-key
production-key

这样,如果开发环境的凭证泄露,也不会自动导致生产环境资源暴露。

前端应用程序呢?

在这里,API密钥的安全性就会变得复杂起来。

前端代码是在用户的设备上运行的。

这意味着用户可以查看这些代码。

举个例子:

const apiKey = "browser-key";

用户可以通过浏览器的开发者工具或网络请求来查看这个API密钥的值。

有些服务会故意提供可供公众访问的浏览器API密钥。

不过,这类密钥仍然应该受到以下限制:

  • 允许的域名

  • 网站来源地址

  • 可执行的API操作

  • 使用配额

  • 引用源限制

  • 时间限制

但是,真正的私密凭证绝对不应该被放在浏览器代码中

正确的做法应该是:

fetch("https://private-api.example.com/data", {
  headers: {
    Authorization: "Bearer private-secret-token"
  }
});

让浏览器直接调用你的后端服务:

fetch("/api/data");

然后后端再与私有服务进行交互:

const response = await fetch(
  "https://private-api.example.com/data",
  {
    headers: {
      Authorization: `Bearer ${process.env.PRIVATE_API_TOKEN}`
    }
  }
);

这样,后端只能返回浏览器被允许接收的信息。

公共/浏览器凭证
        ↓
可以公开显示,但需要加以限制

私密凭证
        ↓
必须保存在受信任的后端系统或秘密管理工具中

环境变量与秘密管理工具

环境变量确实很有用,但它们并不能作为通用的秘密管理解决方案。

对于小型应用程序或本地开发环境来说,使用以下配置通常是完全合理的:

API_KEY=your-secret

这样的设置完全适合这类场景。

而对于规模较大的生产系统而言,您可能会需要一个专用的秘密管理工具

秘密管理系统能够提供以下功能:

  • 集中存储凭证信息

  • 访问控制机制

  • 审计功能

  • 凭证轮换机制

  • 版本管理功能

  • 不同环境之间的隔离机制

  • 与部署系统的集成

重要的是,您的源代码不应该负责存储生产环境中的敏感信息。

正确的做法应该是:

应用程序
    ↓
秘密管理系统
    ↓
凭证信息

而不是:

应用程序
    ↓
硬编码的生产环境凭证信息

您应该根据项目规模和具体需求来选择合适的解决方案。

将秘密扫描功能添加到您的工作流程中

人类虽然是出色的程序员,但有时也会像糟糕的搜索引擎一样犯错。

自动化秘密扫描可以在凭证信息被上传到代码仓库之前就发现它们。

一些常用的工具包括:

  • Gitleaks

  • TruffleHog

  • detect-secrets

  • 预提交钩子

  • Git托管平台的秘密扫描功能
  • 持续集成安全扫描工具

例如,您可以在本地运行Gitleaks来检测敏感信息:

gitleaks detect --source . --verbose

您也可以将秘密扫描集成到持续集成流程中。

一个基本的GitHub Actions工作流程可能如下所示:

name: 秘密扫描

on:
  push:
  pull_request:

jobs:
  scan:
    runs-on: ubuntu-latest

    steps:
      - name: 检出代码仓库
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: 扫描敏感信息
        uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

请查阅所选工具的官方文档,并根据您项目的安全需求来配置相关参数。

秘密扫描工具有时会产生误报,因此您可能需要为一些安全的测试值设置例外情况。

不过,请注意不要使用过于宽泛的例外规则,否则可能会掩盖真正的敏感信息。

将Git钩子作为额外的安全保障

您还可以在文件被提交之前对其进行扫描。

例如,一个简单的预提交脚本可以检测其中是否包含可疑的敏感词汇:

#!/usr/bin/env bash

if grep -RniE "api[_-]?key|password|secret|token|private[_-]?key" . \
  --exclude-dir=.git \
  --exclude=".env.example"; then

  echo "检测到可能的敏感信息,提交操作被取消。"
  exit 1
fi

这并不是一个功能完备的安全扫描工具,但它能够发现一些显而易见的错误。

为了获得更强的保护效果,应通过预提交框架使用专门的秘密信息扫描工具。

我们的目标并不是让提交代码的过程变得极其繁琐,而是要增加意外泄露敏感信息的可能性。

在提交之前检查你的暂存变更内容

你可以养成的最简单的安全习惯之一,就是仔细确认自己究竟打算提交哪些内容。

首先:

git status

然后只将你确实想要提交的文件添加到暂存区中:

git add src/api.js README.md

接下来检查这些暂存的变更内容:

git diff --cached

需要特别注意以下内容:

  • API密钥

  • 密码

  • 令牌

  • 私有URL地址

  • 内部主机名

  • 客户数据

  • 调试输出信息

  • 个人信息

  • 私钥证书

只有当确认暂存区的变更内容没有问题后,才能进行提交:

git commit -m "从环境变量中加载API密钥"

对于以下命令要特别小心:

git add .

这个命令可能会将一些你本不打算公开的文件添加到暂存区中,比如`.env`文件、数据库导出文件、生成的临时文件或本地配置文件等。

开发者常犯的错误

错误1:“我已经把它删除了,所以应该没问题”

从当前版本的文件中删除某项敏感信息,并不会使该信息从Git历史记录中消失。

正确的处理方式:应立即撤销该敏感信息的有效性,并在适当的时候清理仓库的历史记录。

错误2:“我的仓库是私有的,所以应该没有问题”

私有仓库并不能提供绝对的安全保障。

即使仓库是私有的,敏感信息仍然有可能通过被入侵的账户、集成系统、持续集成工具的日志记录、分支操作、备份文件或被复制的代码等方式泄露出去。

正确的处理方式:即便是私有仓库,也不应该将敏感信息提交到其中。

错误3:“我只需要对它进行编码就可以了”

这样的操作并不能真正保护敏感信息:

const key = atob("c29tZS1rZXk+");

或者:

const key = "some-" + "secret-" + "value";

对敏感信息进行编码、分割、重命名或隐藏,并不能真正起到保护作用。

如果你的应用程序能够重新生成这些敏感信息,那么任何分析该应用程序的人也同样可以做到这一点。

错误4:将敏感信息记录在日志中

绝对不要这样做:

console.log(process.env.API_KEY);

日志文件可能会被你的终端、持续集成系统、托管服务提供商、监控平台或云服务存储起来。

相反,应该这样做:

console.log(
  "API密钥已配置。",
  Boolean(process.env.API_KEY)
);

如果在调试过程中确实需要查看某个值,请避免打印出完整的凭证信息。

例如:

function maskSecret(value) {
  if (!value) return "未配置";
  if (value.length <= 8) return "********";

  return `${value.slice(0, 4)}...${value.slice(-4)}`;
}

console.log(maskSecret(process.env.API_KEY));

即使是对经过处理的凭证信息,也应当谨慎对待。

错误5:在所有地方使用相同的凭证

如果本地开发、测试、预发布环境和生产环境都使用相同的凭证,那么一旦其中某个环境出现安全漏洞,整个系统都会受到影响。

正确的处理方式:应为不同的环境配置不同的凭证,并赋予它们不同的权限。

错误6:只清理当前分支

敏感信息可能会残留在以下地方:

  • 旧分支中

  • 标签中

  • 拉取请求中

  • 其他引用路径中

正确的处理方式:在排查和清理泄露的凭证信息时,应检查整个代码仓库。

错误7:忘记清除构建生成的文件

敏感信息还可能出现在以下文件中:

  • 编译后的JavaScript文件

  • Docker镜像

  • 可下载的发布版本文件

  • 已发布的软件包

  • 生成的文档

正确的处理方式:需要立即撤销该凭证,并找出所有可能受到影响的文件,然后将其删除或替换。

完整的API密钥安全事件检查清单

如果您发现自己的API密钥已经泄露,请使用以下检查清单进行处理:

1. 撤销或更换已泄露的密钥
2. 生成新的替代凭证
3> 为新的替代凭证设置相应的访问权限
4> 查看服务提供商提供的日志记录
5> 审查账单信息及使用情况
6> 检查是否存在未经授权的资源被访问
7> 从当前文件中删除该密钥
8> 将包含敏感信息的文件添加到.gitignore文件中
9> 创建或更新.env.example文件
10> 在Git历史记录中搜索相关线索
11> 检查所有分支和标签
12> 如有必要,从Git历史记录中清除这些敏感信息
13> 确认旧的敏感信息已被彻底删除
14> 如果合适,强制推送已清理过的Git历史记录
15> 检查所有的拉取请求和分支创建操作
16> 查看持续集成及部署相关的日志记录
17> 更新本地配置文件
18> 更新预发布环境的配置文件
19> 更新生产环境的配置文件
20> 更新与持续集成/持续交付相关的敏感信息设置
21> 运行专门用于检测敏感信息的工具
22> 将此次安全事件记录在案
23> 添加额外的安全防护措施

具体的操作步骤会因您所使用的服务提供商和项目类型而有所不同,但顺序非常重要:首先必须使密钥失效,然后再进行清理。

安全的项目架构设计

<一个简单的Node.js项目可能看起来像这样:

my-project/
├── src/
│   └── api.js
├── .env
├── .env.example
├── .gitignore
├── package.json
└── README.md

本地的`.env`文件中包含了用于开发的实际配置信息:

API_KEY=你的本地密钥

` .env.example`文件中并不包含任何真实的凭证信息:

API_KEY=请用你自己的密钥替换这里的内容

应用程序会读取这些环境变量来进行运行:

import "dotenv/config";

const apiKey = process.env.API_KEY;

if (!apiKey) {
  throw new Error("缺少API_KEY环境变量");
}

export async function getData() {
  const response = await fetch(
    "https://api.example.com/data",
    {
      headers: {
        Authorization: `Bearer ${apiKey}`
      }
    }
  );

  if (!response.ok) {
    throw new Error(
      `API请求失败:${response.status>`
    );
  }

  return response.json();
}

` .gitignore`文件的作用是确保这些本地配置文件不会被包含在未来的代码提交中:

.env
.env.*
!.env.example

node_modules/

最后,你的`README.md`文件可以用来说明如何进行配置,而无需暴露任何敏感信息:

步骤1:将示例环境文件复制到本地:`cp .env.example .env`

步骤2:在`.env`文件中填写你自己的API密钥。

最后一步,启动你的应用程序吧!

npm start

最后的建议

如果API密钥被泄露了,并不意味着你是一个糟糕的开发者。这仅仅说明你的开发流程还需要更加完善的防护措施。

最重要的是要懂得如何迅速应对这种问题,以及如何防止同样的错误再次发生。

请记住这个应急处理步骤:

使密钥失效 → 进行调查 → 移除旧密钥 → 更换为新密钥 → 采取预防措施

关键在于要迅速行动,并防止类似问题再次发生。

  • 首先,必须使被泄露的密钥失效,确保它不能再被使用。

  • 接着,仔细检查日志、使用记录和账单信息,判断该密钥是否被恶意使用了。

  • 然后,从当前的代码中删除这个敏感信息,必要时也要从Git历史记录中清除它。

  • 之后,用一个新的密钥替换原有的密钥,确保新密钥只具备所需的权限。

  • 最后,通过使用环境变量、秘密管理工具、进行秘密信息扫描以及遵循规范的Git操作习惯,来防止未来的泄露事件发生。

Git在记录项目历史方面确实非常有用。但当这些历史记录中包含了密码这类敏感信息时,它的作用就大打折扣了。

因此,在适当的情况下,可以将代码公开分享;但必须把敏感信息保存在其他地方。

祝编程愉快!

相关文章

技术实践

如何使用Python构建一个人工智能文件分析工具

如果你曾经打开过一份30页的PDF文件,然后心想“我绝对不可能读完这一切”,那么你就已经理解了为什么文件分析人工智能工具会非常有用。 想象一下,当你上传一篇研究论文、简历、CSV文件、商业报告或PDF文档后,只需简单地问这样一个问题: “其中最重要的发现是什么?” 人工智能工具无需你手动浏览整个文件,就能理解文件的内容,并回答相关问题。 在本教程中,我们正是要构建这样的工具。我们将使用Python编写一个适合初学者的 AI文件分析工具 ,它能够: 从你的电脑中接收文件 将文件上传到人工智能模型中 读取文件的内容 理解自然语言提出的问题 分析文件 给出有用的答案 处理各种类型的问题,而无需我们为

阅读全文
技术实践

为什么你绝不应该在API请求中包含电子邮件地址

在开发环境中,你的注册接口看起来没有任何问题。用户完成注册后,你会将相关数据保存到数据库中,然后调用邮件服务提供商,并返回状态码 201 Created ,这样用户就会收到欢迎邮件。一切似乎都很顺利。 然而,当生产环境中的请求开始涌入时,问题出现了: 邮件发送接口现在需要2秒钟才能完成响应,而不是原本的200毫秒。因此,有些请求会超时失败。而在邮件服务提供商出现故障的情况下,所有注册请求都会返回状态码 500 。技术支持人员很困惑:为什么用户能够创建账户,但却始终收不到确认邮件链接? 其实问题并不出在你的邮件模板上,而在于你选择将邮件发送处理逻辑放在HTTP请求路径中这一决策。 在这篇文章中,

阅读全文
技术实践

演讲主题:超越简单提示机制:为实用型人工智能系统构建合适的应用环境

里卡多·费雷拉探讨了如何超越简单的提示工程技术,来构建具备生产级功能的人工智能应用。他分享了一些实用的架构策略:如何利用Redis整合长期记忆与短期记忆机制,如何通过信息摘要来管理大语言模型的令牌使用限制,如何通过重新排序和语义缓存来防止上下文信息的丢失,以及如何在严格的延迟约束下控制API调用所带来的成本增长。 作者:里卡多·费雷拉

阅读全文
技术实践

了解人工智能软件开发生命周期流程——构建智能代理功能的完整指南

也许你可以理解这样的场景:本周,你用了同样的说明四次向别人解释人工智能模型的使用方法。 你反复讲解过团队是如何构建演示文稿的框架的,哪些检查步骤需要在部署之前完成,以及为什么测试数据库并不是文档中提到的那个。 每次你都要把这些内容重新写一遍,每次智能助手也能完成得不错,但每次新的会话开始时,一切都得从零开始。 而这正是 智能助手技能 所要解决的问题。 技能 实际上就是一个文件夹,其中只包含一个名为 Skill.md 的文件。智能助手在启动时会阅读其中的一行总结内容,而只有当真正需要时才会打开完整的说明文件。你只需把解释内容编写一次,将其与代码一起提交,那么团队中的每个智能助手就能访问这些信息,

阅读全文