---
title: "5.3.3 代码中的安全隐患"
order: 5
---


![05-advanced_5.3-security_5.3.3-code-risks.png](/images/Basic/05-advanced_5.3-security_5.3.3-code-risks.png)
# 5.3.3 代码中的安全隐患

经过本节学习，你将掌握：
- 代码中常见的 5 类安全隐患
- 如何识别代码中的硬编码密钥
- .env 文件的正确使用方法
- .gitignore 的配置技巧

## 代码中常见的 5 类安全隐患

根据 Veracode 2025 报告和安全社区的分析，生成代码中需要特别关注的安全问题包括：

### 1. 硬编码密钥

这是最常见也最危险的问题。

```javascript
// ❌ 危险：密钥直接写在代码里
const API_KEY = "sk-proj-abc123xyz...";
const DB_PASSWORD = "SuperSecret123";

// ✅ 安全：使用环境变量
const API_KEY = process.env.API_KEY;
const DB_PASSWORD = process.env.DB_PASSWORD;
```

### 2. 跳过输入验证

如果没有明确要求，生成的代码可能会跳过输入验证。加载相关 Skills（如 `supabase-postgres-best-practices`）后，这类问题会被自动避免。

```javascript
// ❌ 危险：直接使用用户输入
function searchUser(username) {
  return db.query(`SELECT * FROM users WHERE name = '${username}'`);
}
// 攻击者可以输入：' OR '1'='1  来获取所有用户数据

// ✅ 安全：使用参数化查询
function searchUser(username) {
  return db.query('SELECT * FROM users WHERE name = $1', [username]);
}
```

### 3. 使用不安全的默认配置

```javascript
// ❌ 危险：允许所有来源的跨域请求
app.use(cors({ origin: '*' }));

// ✅ 安全：只允许特定来源
app.use(cors({ origin: 'https://yoursite.com' }));
```

### 4. 信息过度暴露

```javascript
// ❌ 危险：向用户暴露详细错误信息
app.use((err, req, res, next) => {
  res.status(500).json({ 
    error: err.message,
    stack: err.stack,  // 暴露了代码结构
    dbQuery: err.query // 暴露了数据库查询
  });
});

// ✅ 安全：只返回必要信息
app.use((err, req, res, next) => {
  console.error(err);  // 在服务器端记录详细信息
  res.status(500).json({ error: '服务器错误，请稍后重试' });
});
```

### 5. 使用过时或存在漏洞的库

AI 可能推荐一些过时的、存在已知漏洞的库。这个问题我们会在 5.3.5 节详细讨论。

## 如何识别硬编码的密钥

在代码中搜索这些关键词：

| 关键词 | 可能是什么 |
|--------|-----------|
| `password`、`passwd`、`pwd` | 密码 |
| `secret`、`api_key`、`apikey` | API 密钥 |
| `token`、`auth`、`bearer` | 认证令牌 |
| `sk-`、`pk-`、`AKIA` | 特定服务的密钥（OpenAI、AWS 等） |
| `-----BEGIN` | 私钥或证书 |

**快速检查方法**：

在你的项目文件夹中搜索这些模式。如果看到后面跟着一串看起来像真实密钥的字符串（而不是 `process.env.XXX`），就需要警惕。

## 使用 .env 文件存放敏感信息

`.env` 文件是存放敏感配置的标准方式。

### 创建 .env 文件

在项目根目录创建 `.env` 文件：

```bash
# .env 文件示例
# API 密钥
OPENAI_API_KEY=sk-proj-你的真实密钥
STRIPE_SECRET_KEY=sk_test_你的真实密钥

# 数据库连接
DATABASE_URL=postgres://user:password@localhost:5432/mydb

# 其他配置
NODE_ENV=development
```

### 在代码中读取环境变量

```javascript
// JavaScript/Node.js
const apiKey = process.env.OPENAI_API_KEY;
```

```python
# Python
import os
api_key = os.environ.get('OPENAI_API_KEY')
```

### 创建 .env.example 文件

为了让其他人（或未来的你）知道需要配置哪些环境变量，创建一个 `.env.example` 文件：

```bash
# .env.example - 这个文件可以提交到 Git
# 复制此文件为 .env，然后填入真实值

OPENAI_API_KEY=在这里填入你的密钥
STRIPE_SECRET_KEY=在这里填入你的密钥
DATABASE_URL=在这里填入数据库连接字符串
```

## 配置 .gitignore 防止泄露

`.gitignore` 文件告诉 Git 哪些文件不应该被上传。

在项目根目录创建或编辑 `.gitignore` 文件：

```bash
# 环境变量文件 - 最重要！
.env
.env.local
.env.development
.env.production
.env*.local

# 依赖文件夹
node_modules/
venv/
__pycache__/

# 编辑器和系统文件
.DS_Store
Thumbs.db
.vscode/
.idea/

# 构建产物
dist/
build/
*.log
```

::: warning 注意
如果你在添加 `.gitignore` 之前已经提交过 `.env` 文件，仅仅添加 `.gitignore` 是不够的。

你需要：
1. 从 Git 历史中删除该文件
2. **立即更换所有已泄露的密钥**

因为 Git 历史是可以被查看的，即使文件被删除。
:::

## 检查你的待办清单项目

回顾你在第四章做的待办清单，检查以下几点：

- [ ] 代码中没有硬编码的密钥或密码
- [ ] 如果有 API 调用，密钥是从环境变量读取的
- [ ] `.env` 文件（如果有）已经加入 `.gitignore`
- [ ] 没有在 console.log 中输出敏感信息

如果只是一个纯前端的待办清单（使用 localStorage），通常不会有这些问题。但养成检查习惯很重要，因为你以后的项目会越来越复杂。

→ [5.3.4 初学者安全检查清单](./5.3.4-checklist.md)
